UNPKG

gy-map

Version:

gy

19,038 lines 563 kB
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
  return value;
};
import { defineComponent, onMounted, watch, onBeforeUnmount, ref, getCurrentInstance, computed, onBeforeMount, markRaw } from "vue-demi";
import { Style as Style$1, Stroke as Stroke$2, Fill as Fill$2, Icon as Icon$2, Circle as Circle$1, Text as Text$2 } from "ol/style";
import VectorLayer$2 from "ol/layer/Vector";
import VectorSource$2 from "ol/source/Vector";
import GeoJSON from "ol/format/GeoJSON";
import LineString from "ol/geom/LineString";
import feature from "ol/Feature";
import { fromLonLat as fromLonLat$1, toLonLat as toLonLat$1 } from "ol/proj";
import * as turf from "@turf/turf";
import { Point as Point$3 } from "ol/geom";
import { Vector as Vector$1, Heatmap } from "ol/layer";
import Map from "ol/Map";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import View$2 from "ol/View";
import Overlay from "ol/Overlay";
import { Draw, Snap, Modify, defaults as defaults$1 } from "ol/interaction";
import { Vector } from "ol/source";
import { singleClick as singleClick$1, altKeyOnly } from "ol/events/condition";
import Point$2 from "ol/geom/Point";
const x_PI = 3.141592653589793 * 3e3 / 180;
const PI = 3.141592653589793;
const a = 6378245;
const ee = 0.006693421622965943;
function bd09togcj02(bd_lon, bd_lat) {
  let x_pi = 3.141592653589793 * 3e3 / 180;
  let x = bd_lon - 65e-4;
  let y = bd_lat - 6e-3;
  let z = Math.sqrt(x * x + y * y) - 2e-5 * Math.sin(y * x_pi);
  let theta = Math.atan2(y, x) - 3e-6 * Math.cos(x * x_pi);
  let gg_lng = z * Math.cos(theta);
  let gg_lat = z * Math.sin(theta);
  return [gg_lng, gg_lat];
}
function gcj02tobd09(lng, lat) {
  let z = Math.sqrt(lng * lng + lat * lat) + 2e-5 * Math.sin(lat * x_PI);
  let theta = Math.atan2(lat, lng) + 3e-6 * Math.cos(lng * x_PI);
  let bd_lng = z * Math.cos(theta) + 65e-4;
  let bd_lat = z * Math.sin(theta) + 6e-3;
  return [bd_lng, bd_lat];
}
function wgs84togcj02(lng, lat) {
  if (outOfChina(lng, lat)) {
    return [lng, lat];
  } else {
    let dlat = transformlat(lng - 105, lat - 35);
    let dlng = transformlng(lng - 105, lat - 35);
    let radlat = lat / 180 * PI;
    let magic = Math.sin(radlat);
    magic = 1 - ee * magic * magic;
    let sqrtmagic = Math.sqrt(magic);
    dlat = dlat * 180 / (a * (1 - ee) / (magic * sqrtmagic) * PI);
    dlng = dlng * 180 / (a / sqrtmagic * Math.cos(radlat) * PI);
    const mglat = lat + dlat;
    const mglng = lng + dlng;
    return [mglng, mglat];
  }
}
function gcj02towgs84(lng, lat) {
  if (outOfChina(lng, lat)) {
    return [lng, lat];
  } else {
    let dlat = transformlat(lng - 105, lat - 35);
    let dlng = transformlng(lng - 105, lat - 35);
    let radlat = lat / 180 * PI;
    let magic = Math.sin(radlat);
    magic = 1 - ee * magic * magic;
    let sqrtmagic = Math.sqrt(magic);
    dlat = dlat * 180 / (a * (1 - ee) / (magic * sqrtmagic) * PI);
    dlng = dlng * 180 / (a / sqrtmagic * Math.cos(radlat) * PI);
    const mglat = lat + dlat;
    const mglng = lng + dlng;
    return [lng * 2 - mglng, lat * 2 - mglat];
  }
}
function bd09towgs84(lng, lat) {
  const gcj02 = bd09togcj02(lng, lat);
  const result = gcj02towgs84(gcj02[0], gcj02[1]);
  return result;
}
function wgs84tobd09(lng, lat) {
  const gcj02 = wgs84togcj02(lng, lat);
  const result = gcj02tobd09(gcj02[0], gcj02[1]);
  return result;
}
function transformlat(lng, lat) {
  let ret = -100 + 2 * lng + 3 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
  ret += (20 * Math.sin(6 * lng * PI) + 20 * Math.sin(2 * lng * PI)) * 2 / 3;
  ret += (20 * Math.sin(lat * PI) + 40 * Math.sin(lat / 3 * PI)) * 2 / 3;
  ret += (160 * Math.sin(lat / 12 * PI) + 320 * Math.sin(lat * PI / 30)) * 2 / 3;
  return ret;
}
function transformlng(lng, lat) {
  let ret = 300 + lng + 2 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
  ret += (20 * Math.sin(6 * lng * PI) + 20 * Math.sin(2 * lng * PI)) * 2 / 3;
  ret += (20 * Math.sin(lng * PI) + 40 * Math.sin(lng / 3 * PI)) * 2 / 3;
  ret += (150 * Math.sin(lng / 12 * PI) + 300 * Math.sin(lng / 30 * PI)) * 2 / 3;
  return ret;
}
function outOfChina(lng, lat) {
  return lng < 72.004 || lng > 137.8347 || (lat < 0.8293 || lat > 55.8271 || false);
}
let gyMapLonLatType = "WGS84";
const setMapLonLatType = (type) => {
  gyMapLonLatType = type;
};
const getMapLonLatType = () => {
  return gyMapLonLatType;
};
const formatLonLatToPosition = (lon, lat) => {
  if (Array.isArray(lon)) {
    return formatLonLatToPosition(lon[0], lon[1]);
  } else {
    if (!lat) {
      console.error("\u8BF7\u4F20\u5165\u6B63\u786E\u7684\u53C2\u6570\uFF01");
      return [];
    }
    return fromLonLat$1(wGS84ToLonlat(lon, lat, getMapLonLatType()));
  }
};
const flortAdd = (num1, num2) => {
  let r1, r2, m;
  try {
    r1 = num1.toString().split(".")[1].length;
  } catch (e) {
    r1 = 0;
  }
  try {
    r2 = num2.toString().split(".")[1].length;
  } catch (e) {
    r2 = 0;
  }
  m = Math.pow(10, Math.max(r1, r2));
  return Math.round(num1 * m + num2 * m) / m;
};
const lonlatToWGS84 = (lon, lat, type) => {
  lon = +lon;
  lat = +lat;
  type = type.toUpperCase();
  if (type === "GCJ02") {
    return gcj02towgs84(lon, lat);
  } else if (type === "BD09") {
    return bd09towgs84(lon, lat);
  } else {
    return [lon, lat];
  }
};
const wGS84ToLonlat = (lon, lat, type) => {
  lon = +lon;
  lat = +lat;
  type = type.toUpperCase();
  if (type === "GCJ02") {
    return gcj02towgs84(lon, lat);
  } else if (type === "BD09") {
    return bd09towgs84(lon, lat);
  } else {
    return [lon, lat];
  }
};
const getBufferArea = (positionArr, radius = 200) => {
  if (positionArr.length === 0 || radius === 0) {
    return [];
  }
  let geojsonObj;
  if (positionArr.length === 1) {
    geojsonObj = turf.point(positionArr[0]);
  } else {
    if (positionArr[0][0] === positionArr[positionArr.length - 1][0] && positionArr[0][1] === positionArr[positionArr.length - 1][1]) {
      geojsonObj = turf.polygon([positionArr]);
    } else {
      geojsonObj = turf.lineString(positionArr);
    }
  }
  let buffer2 = turf.buffer(geojsonObj, radius, { units: "meters" });
  if (buffer2.geometry.type === "Polygon") {
    return buffer2.geometry.coordinates[0];
  }
  if (buffer2.geometry.type === "MultiPolygon") {
    return buffer2.geometry.coordinates[0][0];
  }
  return [];
};
const gyMapUtils = {
  formatLonLatToPosition,
  flortAdd,
  gcj02towgs84,
  bd09towgs84,
  wgs84tobd09,
  wgs84togcj02,
  lonlatToWGS84,
  wGS84ToLonlat,
  setMapLonLatType,
  getBufferArea
};
const __vue2_script$b = defineComponent({
  name: "Gymap",
  props: {
    mapOpt: {
      type: Object,
      default: () => ({})
    },
    center: {
      type: Array,
      default: () => []
    },
    maplayerIndex: {
      type: Number,
      default: 0
    },
    zoom: {
      type: Number,
      default: 0
    },
    layerOpacity: {
      type: Number,
      default: 1
    },
    mapId: {
      type: String,
      default: "map"
    },
    lonlatType: {
      type: String,
      default: "WGS84"
    },
    interactionsObj: {
      type: Object,
      default: () => ({})
    },
    isShowControls: {
      type: Boolean,
      default: false
    }
  },
  setup(props) {
    const gyMapObj = gyMap$1(props.mapId).value;
    setMapLonLatType(props.lonlatType);
    onMounted(() => {
      gyMapObj.init(props.mapId, {
        ...props.mapOpt,
        maplayerIndex: props.maplayerIndex,
        zoom: props.zoom,
        centerPoint: props.center,
        layerOpacity: props.layerOpacity,
        interactionsObj: props.interactionsObj,
        isShowControls: props.isShowControls
      });
    });
    const mouseenterFun = () => {
      const contentIdDom = document.getElementById(props.mapId);
      if (contentIdDom) {
        contentIdDom.focus();
      }
    };
    watch(() => props.zoom, (n) => {
      gyMapObj && gyMapObj.zoomSetFun(n);
    });
    watch(() => props.maplayerIndex, (n) => {
      gyMapObj && gyMapObj.changeMapLayer(n);
    });
    watch(() => props.center, (n) => {
      gyMapObj && gyMapObj.changeCenterPoint(n);
    });
    watch(() => props.layerOpacity, (n) => {
      gyMapObj && gyMapObj.setLayerOpacity(n);
    });
    onBeforeUnmount(() => {
      gyMapObj && gyMapObj.destory();
    });
    return {
      id: props.mapId,
      gyMapObj,
      mouseenterFun
    };
  }
});
var render$b = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div", {
    staticClass: "map divMap",
    attrs: {
      "id": _vm.mapId,
      "tabindex": "0"
    },
    on: {
      "mouseenter": _vm.mouseenterFun
    }
  }, [_vm._t("default")], 2);
};
var staticRenderFns$b = [];
const Gymap_vue_vue_type_style_index_0_scoped_true_lang = "";
function normalizeComponent(scriptExports, render2, staticRenderFns2, functionalTemplate, injectStyles, scopeId, moduleIdentifier, shadowMode) {
  var options = typeof scriptExports === "function" ? scriptExports.options : scriptExports;
  if (render2) {
    options.render = render2;
    options.staticRenderFns = staticRenderFns2;
    options._compiled = true;
  }
  if (functionalTemplate) {
    options.functional = true;
  }
  if (scopeId) {
    options._scopeId = "data-v-" + scopeId;
  }
  var hook;
  if (moduleIdentifier) {
    hook = function(context) {
      context = context || this.$vnode && this.$vnode.ssrContext || this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext;
      if (!context && typeof __VUE_SSR_CONTEXT__ !== "undefined") {
        context = __VUE_SSR_CONTEXT__;
      }
      if (injectStyles) {
        injectStyles.call(this, context);
      }
      if (context && context._registeredComponents) {
        context._registeredComponents.add(moduleIdentifier);
      }
    };
    options._ssrRegister = hook;
  } else if (injectStyles) {
    hook = shadowMode ? function() {
      injectStyles.call(
        this,
        (options.functional ? this.parent : this).$root.$options.shadowRoot
      );
    } : injectStyles;
  }
  if (hook) {
    if (options.functional) {
      options._injectStyles = hook;
      var originalRender = options.render;
      options.render = function renderWithStyleInjection(h, context) {
        hook.call(context);
        return originalRender(h, context);
      };
    } else {
      var existing = options.beforeCreate;
      options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
    }
  }
  return {
    exports: scriptExports,
    options
  };
}
const __cssModules$b = {};
var __component__$b = /* @__PURE__ */ normalizeComponent(
  __vue2_script$b,
  render$b,
  staticRenderFns$b,
  false,
  __vue2_injectStyles$b,
  "5c0faef4",
  null,
  null
);
function __vue2_injectStyles$b(context) {
  for (let o in __cssModules$b) {
    this[o] = __cssModules$b[o];
  }
}
const Gymap = /* @__PURE__ */ function() {
  return __component__$b.exports;
}();
const __vue2_script$a = defineComponent({
  name: "GymapHtml",
  props: {
    offset: {
      type: Array,
      default: () => [0, 0]
    },
    position: {
      type: Array,
      default: () => []
    },
    stopEvent: {
      type: Boolean,
      default: true
    },
    className: {
      type: String,
      default: ""
    },
    maxZoom: {
      type: Number,
      default: 18
    },
    minZoom: {
      type: Number,
      default: 0
    },
    mapId: {
      type: String,
      default: ""
    }
  },
  setup(props) {
    const htmlDom = ref(null);
    const { proxy } = getCurrentInstance();
    const mapId = props.mapId || proxy.$parent.id;
    const gyMapObj = gyMap$1(mapId).value;
    const mapFinish = computed(() => gyMapObj && gyMapObj.mapFinish);
    const zoom = computed(() => gyMapObj && gyMapObj.zoom);
    let isDraw = false;
    watch(mapFinish, () => {
      drawDom();
    });
    let isUndefined = false;
    const changeZoomFun = (val) => {
      if (val > props.maxZoom || val < props.minZoom) {
        isUndefined = true;
        overlay && overlay.setPosition(void 0);
      } else if (isUndefined) {
        isUndefined = false;
        setOverLayerPosition(props.position);
      }
    };
    watch(zoom, (val) => {
      changeZoomFun(val);
    });
    let overlay = null;
    const drawDom = () => {
      if (mapFinish.value && !isDraw) {
        isDraw = true;
        overlay = gyMapObj.drawHtmlToMap(htmlDom.value, {
          offset: props.offset,
          position: props.position,
          stopEvent: props.stopEvent,
          className: props.className
        });
        changeZoomFun(zoom.value);
        const runTask = proxy.$parent.runTask;
        if (runTask) {
          runTask(overlay, props);
        }
      }
    };
    onMounted(() => {
      drawDom();
    });
    const setOverLayerPosition = (p) => {
      let pos = gyMapUtils.formatLonLatToPosition(p);
      overlay && overlay.setPosition(pos);
    };
    watch(() => props.position, (p) => {
      setOverLayerPosition(p);
      changeZoomFun(zoom.value);
    });
    watch(() => props.offset, (p) => {
      overlay && overlay.setOffset(p);
    });
    onBeforeUnmount(() => {
      overlay && gyMapObj && gyMapObj.removeOverlay(overlay);
      const destoryTask = proxy.$parent.destory;
      if (destoryTask) {
        destoryTask();
      }
    });
    return {
      htmlDom,
      mapId,
      gyMapObj,
      mapFinish
    };
  }
});
var render$a = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div", {
    ref: "htmlDom",
    staticClass: "GymapHtml"
  }, [_vm._t("default")], 2);
};
var staticRenderFns$a = [];
const __cssModules$a = {};
var __component__$a = /* @__PURE__ */ normalizeComponent(
  __vue2_script$a,
  render$a,
  staticRenderFns$a,
  false,
  __vue2_injectStyles$a,
  null,
  null,
  null
);
function __vue2_injectStyles$a(context) {
  for (let o in __cssModules$a) {
    this[o] = __cssModules$a[o];
  }
}
const GymapHtml = /* @__PURE__ */ function() {
  return __component__$a.exports;
}();
const __vue2_script$9 = defineComponent({
  name: "GymapPolygon",
  props: {
    positionList: {
      type: Array,
      default: () => []
    },
    className: {
      type: String
    },
    fillColor: {
      type: String,
      default: "rgba(0, 0, 255, 0.1)"
    },
    strokeColor: {
      type: String,
      default: ""
    },
    strokeWidth: {
      type: Number,
      default: 3
    },
    minZoom: {
      type: Number,
      default: 1
    },
    maxZoom: {
      type: Number,
      default: 18
    },
    opacity: {
      type: Number,
      default: 1
    },
    mapId: {
      type: String,
      default: ""
    }
  },
  emits: ["clickFun"],
  setup(props, { emit }) {
    const { proxy } = getCurrentInstance();
    const mapId = props.mapId || proxy.$parent.id;
    const gyMapObj = gyMap$1(mapId);
    const mapFinish = computed(() => gyMapObj.value && gyMapObj.value.mapFinish);
    let polygonLayer = null;
    let isDraw = false;
    watch(mapFinish, () => {
      drawPolygon();
    });
    onMounted(() => {
      drawPolygon();
    });
    const getFeatures = () => {
      let positionList = props.positionList;
      let firstValue = positionList[0];
      let lonlatArr = [];
      if (firstValue && !Array.isArray(firstValue[0])) {
        lonlatArr = [positionList];
      } else {
        lonlatArr = positionList;
      }
      let features = lonlatArr.map((v) => {
        let coordinates2 = v.map((v2) => {
          return gyMapUtils.formatLonLatToPosition(v2);
        });
        return {
          "type": "Feature",
          "geometry": {
            "type": "Polygon",
            "coordinates": [
              coordinates2
            ]
          }
        };
      });
      return features;
    };
    const getSource = () => {
      const features = getFeatures();
      if (!features) {
        return;
      }
      const geojsonObject = {
        "type": "FeatureCollection",
        "crs": {
          "type": "name",
          "properties": {
            "name": "EPSG:3857"
          }
        },
        "features": features
      };
      const source = new VectorSource$2({
        features: new GeoJSON().readFeatures(geojsonObject)
      });
      let feature2 = source.getFeatures()[0] || null;
      if (feature2) {
        feature2.on("click", (e) => {
          emit("clickFun", e);
        });
      }
      return source;
    };
    const getStyle = () => {
      return new Style$1({
        stroke: props.strokeColor ? new Stroke$2({
          color: props.strokeColor,
          width: props.strokeWidth
        }) : null,
        fill: props.fillColor ? new Fill$2({
          color: props.fillColor
        }) : null
      });
    };
    const drawPolygon = () => {
      if (!mapFinish.value || isDraw) {
        return;
      }
      isDraw = true;
      const source = getSource();
      if (!source) {
        return;
      }
      const stylePol = getStyle();
      polygonLayer = new VectorLayer$2({
        source,
        style: [stylePol],
        minZoom: props.minZoom,
        maxZoom: props.maxZoom,
        opacity: props.opacity
      });
      gyMapObj.value.map.addLayer(polygonLayer);
    };
    watch(() => props.positionList, () => {
      const source = getSource();
      if (!source) {
        return;
      }
      polygonLayer && polygonLayer.setSource(source);
    }, {
      deep: true
    });
    watch([() => props.strokeColor, () => props.strokeWidth, () => props.fillColor], () => {
      const stylePol = getStyle();
      polygonLayer && polygonLayer.setStyle(stylePol);
    });
    watch(() => props.opacity, (n) => {
      polygonLayer && polygonLayer.setOpacity(n);
    });
    watch(() => props.minZoom, (n) => {
      polygonLayer && polygonLayer.setMinZoom(n);
    });
    watch(() => props.maxZoom, (n) => {
      polygonLayer && polygonLayer.setMaxZoom(n);
    });
    const destory = () => {
      if (polygonLayer) {
        gyMapObj.value && gyMapObj.value.map.removeLayer(polygonLayer);
        polygonLayer = null;
      }
    };
    onBeforeUnmount(() => {
      destory();
    });
  }
});
var render$9 = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div");
};
var staticRenderFns$9 = [];
const __cssModules$9 = {};
var __component__$9 = /* @__PURE__ */ normalizeComponent(
  __vue2_script$9,
  render$9,
  staticRenderFns$9,
  false,
  __vue2_injectStyles$9,
  null,
  null,
  null
);
function __vue2_injectStyles$9(context) {
  for (let o in __cssModules$9) {
    this[o] = __cssModules$9[o];
  }
}
const GymapPolygon = /* @__PURE__ */ function() {
  return __component__$9.exports;
}();
const arrowIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAATCAMAAACTKxybAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAHJQTFRF//////8A//8A/6pV/79A/8wz/9Ur/9Eu/8Q7/8wz/9It/8k2/9Eu/8o1/9Av/8o1/84x/8wz/8wz/8wz/8wz/8wz/8s0/8wz/8s0/8wz/8wz/8wz/8wz/8s0/8wz/8wz/8wz/8wz/8wz/8wz/8wz/8wzo2lg3QAAACV0Uk5TAAECAwQFBgsNDxETFhgbHUNGm6Ckqa2usrW+w8fLztLV1tnc9jtYQ+sAAABdSURBVAjXZc9HDsAwCARAp/fee+X/X8wesIQVbiMELEqVU6B0VS8tocZARGvE8Edoi1leD+0Jy+2gI2U5LXRmLLuB7pxl1dBT6N4Fzf+OnJHb5B2ZwMhmpDb+kZ9+tBQLxwwvvoMAAAAASUVORK5CYII=";
const __vue2_script$8 = defineComponent({
  name: "GymapLine",
  props: {
    positionList: {
      type: Array,
      default: () => []
    },
    strokeColor: {
      type: String,
      default: "blue"
    },
    strokeWidth: {
      type: Number,
      default: 3
    },
    minZoom: {
      type: Number,
      default: 1
    },
    maxZoom: {
      type: Number,
      default: 18
    },
    opacity: {
      type: Number,
      default: 1
    },
    arrow: {
      type: [Boolean, String],
      default: false
    },
    arrowAnchor: {
      type: Array,
      default: () => [0.75, 0.5]
    },
    animate: {
      type: Boolean,
      default: false
    },
    step: {
      type: Number,
      default: 1e-3
    },
    loop: {
      type: Boolean,
      default: false
    },
    arrowStep: {
      type: Number,
      default: 20
    },
    mapId: {
      type: String,
      default: ""
    }
  },
  emits: ["clickFun"],
  setup(props, { emit }) {
    const { proxy } = getCurrentInstance();
    const mapId = props.mapId || proxy.$parent.id;
    const gyMapObj = gyMap$1(mapId);
    const mapFinish = computed(() => gyMapObj.value && gyMapObj.value.mapFinish);
    let lineLayer = null;
    let lineFeatures = null;
    let isDraw = false;
    let style = null;
    let lineAllGeometry = null;
    let lineGeometry = null;
    let animCoordinates = [];
    let aId = null;
    let lineIndex = 0;
    let lineFeature = null;
    watch(mapFinish, () => {
      drawLine();
    });
    onMounted(() => {
      drawLine();
    });
    const getCoordinates = (positionList) => {
      let coordinates2 = positionList.map((v) => {
        return gyMapUtils.formatLonLatToPosition(v);
      });
      return new LineString(coordinates2);
    };
    const getFeatures = () => {
      let positionList = props.positionList;
      if (props.animate) {
        positionList = [];
      }
      lineGeometry = getCoordinates(positionList);
      lineFeature = new feature({
        type: "lineStyle",
        geometry: lineGeometry
      });
      lineFeature.on("click", (e) => {
        emit("clickFun", e);
      });
      return lineFeature;
    };
    const getSource = () => {
      lineFeatures = getFeatures();
      lineFeatures.setStyle(style);
      if (!lineFeatures) {
        return;
      }
      return new VectorSource$2({
        features: [lineFeatures]
      });
    };
    const styleFunction = function(feature2) {
      const geometry = feature2.getGeometry();
      const styles = [
        new Style$1({
          stroke: new Stroke$2({
            color: props.strokeColor,
            width: props.strokeWidth
          })
        })
      ];
      if (props.arrow) {
        let i = 0;
        let step = props.step;
        step = Math.min(step, 0.01);
        geometry.forEachSegment(function(start, end) {
          const dx = end[0] - start[0];
          const dy = end[1] - start[1];
          const rotation = Math.atan2(dy, dx);
          i++;
          let arrowStep = Math.min(props.arrowStep, 1 / step);
          if (!props.animate || i % (1 / step / arrowStep) == 0) {
            let icon = null;
            if (typeof props.arrow === "boolean") {
              icon = arrowIcon;
            } else {
              icon = props.arrow;
            }
            styles.push(
              new Style$1({
                geometry: new Point$2(end),
                image: new Icon$2({
                  src: icon,
                  anchor: props.arrowAnchor,
                  rotateWithView: true,
                  rotation: -rotation
                })
              })
            );
          }
        });
      }
      return styles;
    };
    const drawLine = () => {
      if (!mapFinish.value || isDraw) {
        return;
      }
      isDraw = true;
      style = styleFunction;
      clearTimer();
      const source = getSource();
      if (!source) {
        return;
      }
      lineLayer = new VectorLayer$2({
        source,
        minZoom: props.minZoom,
        maxZoom: props.maxZoom,
        opacity: props.opacity
      });
      gyMapObj.value.map.addLayer(lineLayer);
      if (props.animate) {
        lineAllGeometry = getCoordinates(props.positionList);
        animate();
      }
    };
    const animate = () => {
      animCoordinates.push(lineAllGeometry.getCoordinateAt(Math.min(lineIndex, 1)));
      updateLine();
      if (lineIndex > 1) {
        clearTimer();
        if (props.loop) {
          animCoordinates = [];
          lineIndex = 0;
          animate();
        }
        return;
      }
      let step = props.step;
      step = Math.min(step, 0.01);
      lineIndex += step;
      aId = window.requestAnimationFrame(animate);
    };
    const updateLine = () => {
      let line = null;
      if (props.animate) {
        line = new LineString(animCoordinates);
      } else {
        line = getCoordinates(props.positionList);
      }
      lineFeature && lineFeature.setGeometry(line);
    };
    const destory = () => {
      if (lineLayer) {
        gyMapObj.value && gyMapObj.value.map.removeLayer(lineLayer);
        lineLayer = null;
      }
      clearTimer();
    };
    const clearTimer = () => {
      aId && window.cancelAnimationFrame(aId);
    };
    watch(() => props.positionList, (n) => {
      updateLine();
    });
    watch(() => props.opacity, (n) => {
      lineLayer && lineLayer.setOpacity(n);
    });
    watch(() => props.animate, (n) => {
      isDraw = false;
      destory();
      drawLine();
    });
    watch(() => props.minZoom, (n) => {
      lineLayer && lineLayer.setMinZoom(n);
    });
    watch(() => props.maxZoom, (n) => {
      lineLayer && lineLayer.setMaxZoom(n);
    });
    watch([() => props.strokeColor, () => props.strokeColor, () => props.arrow], () => {
      style = styleFunction;
      lineFeatures && lineFeatures.setStyle(style);
    });
    onBeforeUnmount(() => {
      destory();
    });
  }
});
var render$8 = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div");
};
var staticRenderFns$8 = [];
const __cssModules$8 = {};
var __component__$8 = /* @__PURE__ */ normalizeComponent(
  __vue2_script$8,
  render$8,
  staticRenderFns$8,
  false,
  __vue2_injectStyles$8,
  null,
  null,
  null
);
function __vue2_injectStyles$8(context) {
  for (let o in __cssModules$8) {
    this[o] = __cssModules$8[o];
  }
}
const GymapLine = /* @__PURE__ */ function() {
  return __component__$8.exports;
}();
const __vue2_script$7 = defineComponent({
  name: "GymapTask",
  props: {
    mapId: {
      type: String,
      default: ""
    },
    positionList: {
      type: Array,
      default: () => []
    },
    loop: {
      type: Boolean,
      default: false
    },
    step: {
      type: Number,
      default: 1e-3
    },
    taskStatus: {
      type: String,
      default: "play"
    },
    delay: {
      type: Number,
      default: 3e3
    },
    animateDataType: {
      type: String,
      default: "LONLAT"
    }
  },
  emits: ["animate"],
  setup(props, { emit }) {
    const { proxy } = getCurrentInstance();
    const mapId = props.mapId || proxy.$parent.id;
    let canPlay = true;
    let noComponents = false;
    let childrenWatch = null;
    let layer = null;
    let timer = void 0;
    const runTask = (childLayerObj, childProps) => {
      if (!canPlay) {
        return;
      }
      if (!noComponents) {
        if (!childrenWatch) {
          childrenWatch = watch(() => childProps.position, () => {
            animIndex = 0;
            destory();
          });
        }
        layer = childLayerObj;
      }
      if (props.taskStatus === "play") {
        startTask();
      }
      if (props.delay !== 0) {
        timer = setTimeout(() => {
          startTask();
        }, props.delay);
      }
    };
    watch(() => props.taskStatus, (n) => {
      if (n === "play") {
        startTask();
      } else if (n === "stop") {
        animIndex = 0;
        stopTask();
      } else if (n === "pause") {
        stopTask();
      }
    });
    const getAllCoordinates = (positions) => {
      let coordinates2 = positions.map((v) => {
        return gyMapUtils.formatLonLatToPosition(v);
      });
      let linestring = new LineString(coordinates2);
      return linestring;
    };
    let lineGeometry = null;
    const startTask = () => {
      if (timer) {
        clearTimeout(timer);
        timer = null;
      }
      if (noComponents ? false : !layer) {
        return;
      }
      if (aId) {
        return;
      }
      if (!lineGeometry) {
        lineGeometry = getAllCoordinates(props.positionList);
      }
      animate();
    };
    let animIndex = 0;
    let aId = null;
    const animate = () => {
      let coordinate = lineGeometry.getCoordinateAt(Math.min(animIndex, 1));
      if (!noComponents) {
        if (layer.geometry) {
          layer.geometry.setCoordinates(coordinate);
        } else {
          layer.setPosition(coordinate);
        }
      }
      if (props.animateDataType === "LONLAT") {
        coordinate = toLonLat$1(coordinate);
      }
      emit("animate", coordinate, animIndex);
      if (animIndex > 1) {
        stopTask();
        if (props.loop) {
          animIndex = 0;
          animate();
        }
        return;
      }
      let step = props.step;
      animIndex = gyMapUtils.flortAdd(animIndex, step);
      aId = window.requestAnimationFrame(animate);
    };
    const stopTask = () => {
      childrenWatch && childrenWatch();
      aId && window.cancelAnimationFrame(aId);
      aId = null;
    };
    const destory = () => {
      if (timer) {
        clearTimeout(timer);
        timer = null;
      }
      stopTask();
    };
    onBeforeMount(() => {
      let defaultStr = proxy.$slots.default;
      if (defaultStr) {
        let children = proxy.$slots.default();
        let len = 0;
        for (let i = 0; i < children.length; i++) {
          let child = children[i];
          if (typeof child.type !== "symbol") {
            len++;
            if (len > 1) {
              canPlay = false;
              console.error("GymapTask\u7EC4\u4EF6\u4E2D\u53EA\u5141\u8BB8\u5B58\u5728\u4E00\u4E2A\u9700\u8981\u6267\u884C\u52A8\u753B\u7684\u7EC4\u4EF6\u3002");
              break;
            }
          }
        }
      } else if (!defaultStr) {
        noComponents = true;
        runTask();
      }
    });
    onMounted(() => {
      if (noComponents) {
        runTask();
      }
    });
    return {
      id: mapId,
      runTask,
      destory
    };
  }
});
var render$7 = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div", [_vm._t("default")], 2);
};
var staticRenderFns$7 = [];
const __cssModules$7 = {};
var __component__$7 = /* @__PURE__ */ normalizeComponent(
  __vue2_script$7,
  render$7,
  staticRenderFns$7,
  false,
  __vue2_injectStyles$7,
  null,
  null,
  null
);
function __vue2_injectStyles$7(context) {
  for (let o in __cssModules$7) {
    this[o] = __cssModules$7[o];
  }
}
const GymapTask = /* @__PURE__ */ function() {
  return __component__$7.exports;
}();
class createOlLayer {
  constructor(id, stylesObj, emit, clusterSource, otherOpts) {
    __publicField(this, "style");
    __publicField(this, "geometry");
    __publicField(this, "feature");
    __publicField(this, "mapId");
    __publicField(this, "source");
    __publicField(this, "layer");
    __publicField(this, "clusterSource");
    __publicField(this, "minZoom");
    __publicField(this, "maxZoom");
    __publicField(this, "olPositions");
    __publicField(this, "opacity");
    __publicField(this, "declutter");
    __publicField(this, "zIndex");
    __publicField(this, "stylesObj");
    __publicField(this, "gyMapObj");
    __publicField(this, "mapFinish");
    __publicField(this, "isDraw");
    __publicField(this, "emit");
    __publicField(this, "otherOpts");
    this.style = void 0;
    this.geometry = void 0;
    this.feature = new feature();
    this.mapId = "";
    this.source = void 0;
    this.layer = null;
    this.clusterSource = clusterSource;
    this.otherOpts = otherOpts || {};
    this.minZoom = computed(() => stylesObj.minZoom);
    this.maxZoom = computed(() => stylesObj.maxZoom);
    this.opacity = computed(() => stylesObj.opacity);
    this.olPositions = computed(() => stylesObj.position);
    this.declutter = stylesObj.declutter;
    this.stylesObj = stylesObj;
    this.zIndex = void 0;
    this.gyMapObj = gyMap$1(id);
    this.mapFinish = computed(() => this.gyMapObj.value && this.gyMapObj.value.mapFinish);
    this.isDraw = false;
    this.emit = emit || null;
  }
  init() {
  }
  draw() {
    this.geometry = this.getGeometry();
    this.addFeature();
    this.setStyle();
    this.addSource();
    this.addLayer();
    this.addWatchFun();
    this.addLayerToMap();
  }
  addFeature() {
    this.feature = new feature({
      geometry: this.geometry
    });
    this.feature.on("click", (e) => {
      this.emit && this.emit("clickFun", e);
    });
  }
  addSource() {
    this.source = new VectorSource$2({
      features: [this.feature]
    });
  }
  addLayer() {
    this.layer = new VectorLayer$2({
      source: this.source,
      declutter: this.declutter,
      minZoom: this.minZoom.value,
      maxZoom: this.maxZoom.value,
      opacity: this.opacity.value
    });
  }
  addLayerToMap() {
    var _a, _b, _c;
    if (!this.isDraw && this.mapFinish.value) {
      let imageSource = this.otherOpts && this.otherOpts.imageSource;
      if (imageSource) {
        let imageFeature = imageSource.getFeatures()[0];
        let imageStyle = imageFeature.getStyle();
        let textStyle = (_a = this.getStyle()) == null ? void 0 : _a.getText();
        if (imageStyle && textStyle) {
          imageStyle.setText(textStyle);
        }
      } else if (this.clusterSource) {
        this.clusterSource.addFeature(this.feature);
      } else {
        this.isDraw = true;
        (_c = (_b = this.gyMapObj.value) == null ? void 0 : _b.map) == null ? void 0 : _c.addLayer(this.layer);
      }
    }
  }
  addWatchFun() {
    watch(this.mapFinish, (n) => {
      this.addLayerToMap();
    });
    this.addLayerWatch();
    this.addPropsWatch();
  }
  addLayerWatch() {
    watch(this.minZoom, (n) => {
      var _a;
      (_a = this.layer) == null ? void 0 : _a.setMinZoom(n);
    });
    watch(this.maxZoom, (n) => {
      var _a;
      (_a = this.layer) == null ? void 0 : _a.setMaxZoom(n);
    });
    watch(this.opacity, (n) => {
      var _a;
      (_a = this.layer) == null ? void 0 : _a.setOpacity(n);
    });
    watch(this.olPositions, (n) => {
      this.setGeoPosition(n);
    });
  }
  addPropsWatch() {
    watch(this.stylesObj, () => {
      this.setStyle();
    });
  }
  getGeometry() {
    return void 0;
  }
  setGeoPosition(position) {
  }
  getStyle() {
    return void 0;
  }
  setStyle() {
    this.style = this.getStyle();
    if (this.style && this.feature)
      this.feature.setStyle(this.style);
  }
  destory() {
    var _a, _b;
    (_b = (_a = this.gyMapObj.value) == null ? void 0 : _a.map) == null ? void 0 : _b.removeLayer(this.layer);
    this.layer = null;
    this.isDraw = false;
  }
}
const layerProps$4 = {
  isAuto: {
    type: Boolean,
    default: false
  },
  declutter: {
    type: Boolean,
    default: false
  },
  minZoom: {
    type: Number,
    default: 1
  },
  maxZoom: {
    type: Number,
    default: 18
  },
  opacity: {
    type: Number,
    default: 1
  }
};
class CreateCircleLayer extends createOlLayer {
  constructor(id, position, stylesObj, emit, clusterSource) {
    super(id, stylesObj, emit, clusterSource);
    __publicField(this, "position");
    __publicField(this, "fillColor");
    __publicField(this, "strokeColor");
    __publicField(this, "strokeWidth");
    __publicField(this, "lineDash");
    __publicField(this, "radius");
    __publicField(this, "scale");
    __publicField(this, "rotation");
    __publicField(this, "isAuto");
    this.position = computed(() => gyMapUtils.formatLonLatToPosition(position));
    this.fillColor = computed(() => stylesObj.fillColor);
    this.strokeColor = computed(() => stylesObj.strokeColor);
    this.strokeWidth = computed(() => stylesObj.strokeWidth);
    this.radius = computed(() => stylesObj.radius);
    this.lineDash = computed(() => stylesObj.lineDash);
    this.scale = computed(() => stylesObj.scale);
    this.rotation = computed(() => stylesObj.rotation);
    this.isAuto = computed(() => stylesObj.isAuto);
    this.draw();
  }
  getGeometry() {
    return new Point$3(this.position.value);
  }
  setGeoPosition(position) {
    this.geometry.setCoordinates(gyMapUtils.formatLonLatToPosition(position));
  }
  getStyle() {
    const s = new Style$1({
      image: new Circle$1({
        radius: this.radius.value || 5,
        fill: this.fillColor.value ? new Fill$2({
          color: this.fillColor.value
        }) : void 0,
        stroke: this.strokeColor.value ? new Stroke$2({
          color: this.strokeColor.value,
          width: this.strokeWidth.value
        }) : void 0,
        scale: this.scale.value,
        rotation: this.rotation.value
      })
    });
    return this.isAuto.value ? (feature2, resolution) => {
      s.getImage().setScale(1 / Math.pow(resolution, 1));
      return s;
    } : s;
  }
}
const layerProps$3 = {
  ...layerProps$4,
  position: {
    type: Array,
    default: () => []
  },
  fillColor: {
    type: String,
    default: ""
  },
  strokeColor: {
    type: String,
    default: ""
  },
  strokeWidth: {
    type: Number,
    default: 3
  },
  scale: {
    type: [Number, Array],
    default: 1
  },
  radius: {
    type: Number,
    default: 5
  },
  rotation: {
    type: Number,
    default: 0
  },
  mapId: {
    type: String,
    default: ""
  }
};
const __vue2_script$6 = defineComponent({
  name: "GymapCircle",
  props: {
    ...layerProps$3
  },
  emits: ["clickFun"],
  setup(props, { emit }) {
    const { proxy } = getCurrentInstance();
    const mapId = props.mapId || proxy.$parent.id;
    const clusterSource = proxy.$parent.clusterSource;
    const setParentStylesByLayer = proxy.$parent.setParentStylesByLayer;
    let layerObj = null;
    onMounted(() => {
      layerObj = new CreateCircleLayer(mapId, props.position, props, emit, clusterSource);
      const runTask = proxy.$parent.runTask;
      if (runTask) {
        runTask(layerObj, props);
      }
      setParentStylesByLayer && setParentStylesByLayer(layerObj);
    });
    const destory = () => {
      layerObj == null ? void 0 : layerObj.destory();
      layerObj = null;
    };
    onBeforeUnmount(() => {
      destory();
      const destoryTask = proxy.$parent.destory;
      if (destoryTask) {
        destoryTask();
      }
    });
  }
});
var render$6 = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div");
};
var staticRenderFns$6 = [];
const __cssModules$6 = {};
var __component__$6 = /* @__PURE__ */ normalizeComponent(
  __vue2_script$6,
  render$6,
  staticRenderFns$6,
  false,
  __vue2_injectStyles$6,
  null,
  null,
  null
);
function __vue2_injectStyles$6(context) {
  for (let o in __cssModules$6) {
    this[o] = __cssModules$6[o];
  }
}
const GymapCircle = /* @__PURE__ */ function() {
  return __component__$6.exports;
}();
class CreateTextLayer extends createOlLayer {
  constructor(id, position, stylesObj, emit, clusterSource, otherOpts) {
    super(id, stylesObj, emit, clusterSource, otherOpts);
    __publicField(this, "position");
    __publicField(this, "text");
    __publicField(this, "font");
    __publicField(this, "offsetX");
    __publicField(this, "offsetY");
    __publicField(this, "scale");
    __publicField(this, "rotation");
    __publicField(this, "textAlign");
    __publicField(this, "textBaseline");
    __publicField(this, "fillColor");
    __publicField(this, "strokeColor");
    __publicField(this, "strokeWidth");
    __publicField(this, "backgroundFillColor");
    __publicField(this, "backgroundStrokeColor");
    __publicField(this, "backgroundStrokeWidth");
    __publicField(this, "padding");
    __publicField(this, "isAuto");
    this.position = computed(() => {
      if (!position.length)
        return [];
      return gyMapUtils.formatLonLatToPosition(position);
    });
    this.text = computed(() => stylesObj.text);
    this.font = computed(() => stylesObj.font);
    this.offsetX = computed(() => stylesObj.offsetX);
    this.offsetY = computed(() => stylesObj.offsetY);
    this.scale = computed(() => stylesObj.scale);
    this.rotation = computed(() => stylesObj.rotation);
    this.textAlign = computed(() => stylesObj.textAlign);
    this.textBaseline = computed(() => stylesObj.textBaseline);
    this.fillColor = computed(() => stylesObj.fillColor);
    this.strokeColor = computed(() => stylesObj.strokeColor);
    this.strokeWidth = computed(() => stylesObj.strokeWidth);
    this.backgroundFillColor = computed(() => stylesObj.backgroundFillColor);
    this.backgroundStrokeColor = computed(() => stylesObj.backgroundStrokeColor);
    this.backgroundStrokeWidth = computed(() => stylesObj.backgroundStrokeWidth);
    this.padding = computed(() => stylesObj.padding);
    this.isAuto = computed(() => stylesObj.isAuto);
    this.draw();
  }
  getGeometry() {
    return new Point$3(this.position.value);
  }
  setGeoPosition(position) {
    this.geometry.setCoordinates(gyMapUtils.formatLonLatToPosition(position));
  }
  getStyle() {
    const s = new Style$1({
      text: new Text$2({
        text: this.text.value,
        font: this.font.value,
        offsetX: this.offsetX.value,
        offsetY: this.offsetY.value,
        placement: "point",
        scale: this.scale.value,
        rotation: this.rotation.value,
        textAlign: this.textAlign.value,
        textBaseline: this.textBaseline.value,
        fill: this.fillColor.value ? new Fill$2({
          color: this.fillColor.value
        }) : void 0,
        stroke: this.strokeColor.value ? new Stroke$2({
          color: this.strokeColor.value,
          width: this.strokeWidth.value
        }) : void 0,
        backgroundFill: this.backgroundFillColor.value ? new Fill$2({
          color: this.backgroundFillColor.value
        }) : void 0,
        backgroundStroke: this.backgroundStrokeColor.value ? new Stroke$2({
          color: this.backgroundStrokeColor.value,
          width: this.backgroundStrokeWidth.value
        }) : void 0,
        padding: this.padding.value
      })
    });
    return this.isAuto.value ? (feature2, resolution) => {
      s.getText().setScale(1 / Math.pow(resolution, 1));
      return s;
    } : s;
  }
}
const layerProps$2 = {
  ...layerProps$4,
  position: {
    type: Array,
    default: () => []
  },
  text: {
    type: String,
    default: ""
  },
  font: {
    type: String,
    default: ""
  },
  offsetX: {
    type: Number,
    default: 0
  },
  offsetY: {
    type: Number,
    default: 0
  },
  scale: {
    type: Number,
    default: 1
  },
  rotation: {
    type: Number,
    default: 0
  },
  textAlign: {
    type: String,
    default: ""
  },
  textBaseline: {
    type: String,
    default: ""
  },
  fillColor: {
    type: String,
    default: ""
  },
  strokeColor: {
    type: String,
    default: ""
  },
  strokeWidth: {
    type: Number,
    default: 5
  },
  backgroundFillColor: {
    type: String,
    default: ""
  },
  backgroundStrokeColor: {
    type: String,
    default: ""
  },
  backgroundStrokeWidth: {
    type: Number,
    default: 5
  },
  padding: {
    type: Array,
    default: () => [0, 0, 0, 0]
  },
  mapId: {
    type: String,
    default: ""
  }
};
const __vue2_script$5 = defineComponent({
  name: "GymapText",
  props: {
    ...layerProps$2
  },
  emits: ["clickFun"],
  setup(props, { emit }) {
    const { proxy } = getCurrentInstance();
    const mapId = props.mapId || proxy.$parent.id;
    const clusterSource = proxy.$parent.clusterSource;
    const imageSource = proxy.$parent.imageSource;
    const setParentStylesByLayer = proxy.$parent.setParentStylesByLayer;
    let layerObj = null;
    layerObj = new CreateTextLayer(mapId, props.position, props, emit, clusterSource, { imageSource });
    onMounted(() => {
      const runTask = proxy.$parent.runTask;
      if (runTask) {
        runTask(layerObj, props);
      }
      setParentStylesByLayer && setParentStylesByLayer(layerObj);
    });
    const destory = () => {
      layerObj.destory();
      layerObj = null;
    };
    onBeforeUnmount(() => {
      destory();
      const destoryTask = proxy.$parent.destory;
      if (destoryTask) {
        destoryTask();
      }
    });
  }
});
var render$5 = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div");
};
var staticRenderFns$5 = [];
const __cssModules$5 = {};
var __component__$5 = /* @__PURE__ */ normalizeComponent(
  __vue2_script$5,
  render$5,
  staticRenderFns$5,
  false,
  __vue2_injectStyles$5,
  null,
  null,
  null
);
function __vue2_injectStyles$5(context) {
  for (let o in __cssModules$5) {
    this[o] = __cssModules$5[o];
  }
}
const GymapText = /* @__PURE__ */ function() {
  return __component__$5.exports;
}();
class CreateImageLayer extends createOlLayer {
  constructor(id, position, stylesObj, emit, clusterSource) {
    super(id, stylesObj, emit, clusterSource);
    __publicField(this, "position");
    __publicField(this, "src");
    __publicField(this, "anchor");
    __publicField(this, "displacement");
    __publicField(this, "scale");
    __publicField(this, "rotation");
    __publicField(this, "isAuto");
    this.position = computed(() => gyMapUtils.formatLonLatToPosition(position));
    this.src = computed(() => stylesObj.src);
    this.anchor = computed(() => stylesObj.anchor);
    this.displacement = computed(() => stylesObj.displacement);
    this.scale = computed(() => stylesObj.scale);
    this.rotation = computed(() => stylesObj.rotation);
    this.isAuto = computed(() => stylesObj.isAuto);
    this.draw();
  }
  getGeometry() {
    return new Point$3(this.position.value);
  }
  setGeoPosition(position) {
    this.geometry.setCoordinates(gyMapUtils.formatLonLatToPosition(position));
  }
  getStyle() {
    const s = new Style$1({
      image: new Icon$2({
        crossOrigin: "anonymous",
        src: this.src.value,
        anchor: this.anchor.value,
        displacement: this.displacement.value,
        scale: this.scale.value,
        rotation: this.rotation.value
      })
    });
    return this.isAuto.value ? (feature2, resolution) => {
      s.getImage().setScale(1 / Math.pow(resolution, 1));
      return s;
    } : s;
  }
}
const layerProps$1 = {
  ...layerProps$4,
  position: {
    type: Array,
    default: () => []
  },
  src: {
    type: String,
    default: ""
  },
  anchor: {
    type: Array,
    default: () => [0.5, 0.5]
  },
  displacement: {
    type: Array,
    default: () => [0, 0]
  },
  scale: {
    type: Number,
    default: 1
  },
  rotation: {
    type: Number,
    default: 0
  },
  mapId: {
    type: String,
    default: ""
  }
};
const __vue2_script$4 = defineComponent({
  name: "GymapImage",
  props: {
    ...layerProps$1
  },
  emits: ["clickFun"],
  setup(props, { emit, expose }) {
    const showSlot = ref(false);
    const { proxy } = getCurrentInstance();
    const mapId = props.mapId || proxy.$parent.id;
    const clusterSource = proxy.$parent.clusterSource;
    const setParentStylesByLayer = proxy.$parent.setParentStylesByLayer;
    let layerObj = null;
    layerObj = new CreateImageLayer(mapId, props.position, props, emit, clusterSource);
    const source = layerObj.source;
    onMounted(() => {
      showSlot.value = true;
      const runTask = proxy.$parent.runTask;
      if (runTask) {
        runTask(layerObj, props);
      }
      setParentStylesByLayer && setParentStylesByLayer(layerObj);
    });
    const destory = () => {
      layerObj.destory();
      layerObj = null;
    };
    onBeforeUnmount(() => {
      destory();
      const destoryTask = proxy.$parent.destory;
      if (destoryTask) {
        destoryTask();
      }
    });
    return {
      id: mapId,
      imageSource: source,
      showSlot
    };
  }
});
var render$4 = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div", [_vm.showSlot ? _vm._t("default") : _vm._e()], 2);
};
var staticRenderFns$4 = [];
const __cssModules$4 = {};
var __component__$4 = /* @__PURE__ */ normalizeComponent(
  __vue2_script$4,
  render$4,
  staticRenderFns$4,
  false,
  __vue2_injectStyles$4,
  null,
  null,
  null
);
function __vue2_injectStyles$4(context) {
  for (let o in __cssModules$4) {
    this[o] = __cssModules$4[o];
  }
}
const GymapImage = /* @__PURE__ */ function() {
  return __component__$4.exports;
}();
const __vue2_script$3 = defineComponent({
  name: "GymapDraw",
  props: {
    canInsertVertexCondition: {
      type: Boolean,
      default: true
    },
    drawTypeList: {
      type: Array,
      default: () => {
        return [
          "Point",
          "LineString",
          "Circle",
          "Polygon"
        ];
      }
    },
    drawTypeCnameList: {
      type: Array,
      default: () => {
        return [
          "\u70B9",
          "\u7EBF",
          "\u5706",
          "\u591A\u8FB9\u5F62"
        ];
      }
    },
    btnBackground: {
      type: String,
      default: "rgb(102, 102, 102)"
    },
    btnColor: {
      type: String,
      default: "#fff"
    },
    btnActiveBackground: {
      type: String,
      default: "rgb(142, 142, 142)"
    },
    btnActiveColor: {
      type: String,
      default: "#fff"
    },
    deleteActiveBackground: {
      type: String,
      default: "rgb(28 137 189)"
    },
    deleteActiveColor: {
      type: String,
      default: "#fff"
    },
    fillColor: {
      type: String,
      default: "rgba(255, 255, 255, 0.2)"
    },
    strokeColor: {
      type: String,
      default: "#ffcc33"
    },
    strokeWidth: {
      type: Number,
      default: 3
    },
    pointRadius: {
      type: Number,
      default: 7
    }
  },
  emits: ["drawFinish"],
  setup(props, { emit }) {
    const drawCon = ref(null);
    const { proxy } = getCurrentInstance();
    const mapId = proxy.$parent.id;
    const gyMapObj = gyMap$1(mapId);
    const mapFinish = computed(() => gyMapObj.value && gyMapObj.value.mapFinish);
    let drawObj = null;
    let snapObj = null;
    let modify = null;
    let source = ref(null);
    let layer = null;
    let isInit = false;
    const drawType = ref("Point");
    const status = ref("");
    const hasFeature = computed(() => source.value && source.value.getFeatures().length != 0);
    const startDraw = () => {
      if (status.value === "start") {
        return;
      }
      status.value = "start";
      if (!source.value) {
        source.value = new Vector();
      }
      if (!isInit) {
        isInit = true;
        layer = new Vector$1({
          source: source.value,
          style: {
            "fill-color": props.fillColor,
            "stroke-color": props.strokeColor,
            "stroke-width": props.strokeWidth,
            "circle-radius": props.pointRadius,
            "circle-fill-color": props.strokeColor
          }
        });
        gyMapObj.value.map.addLayer(layer);
        gyMapObj.value.map.on("singleclick", (e) => {
          if (status.value === "delete" && singleClick$1(e)) {
            gyMapObj.value.map.forEachFeatureAtPixel(e.pixel, (feature2) => {
              layer.getSource().removeFeature(feature2);
              if (!hasFeature.value) {
                startDraw();
              }
              return true;
            }, {
              hitTolerance: 0
            });
          }
        });
      }
      drawObj = new Draw({
        source: source.value,
        type: drawType.value
      });
      snapObj = new Snap({
        source: source.value
      });
      modify = new Modify({
        source: source.value,
        deleteCondition: (e) => {
          return altKeyOnly(e) && singleClick$1(e);
        },
        insertVertexCondition: (e) => {
          return props.canInsertVertexCondition;
        },
        snapToPointer: false
      });
      gyMapObj.value.map.addInteraction(modify);
      gyMapObj.value.map.addInteraction(drawObj);
      gyMapObj.value.map.addInteraction(snapObj);
    };
    const deleteDraw = () => {
      if (status.value === "start") {
        endDraw();
      }
      status.value = "delete";
    };
    const changeDrawType = (type) => {
      drawType.value = type;
      if (status.value !== "end") {
        endDraw();
        startDraw();
      }
    };
    const endDraw = (finish) => {
      if (status.value !== "end") {
        status.value = "end";
        destory();
        finish && submitData();
      }
    };
    const submitData = () => {
      const features = source.value.getFeatures();
      let data = [];
      features.forEach((feature2) => {
        let geometry = feature2.getGeometry();
        let type = geometry.getType();
        let coordinates2 = geometry.getCoordinates();
        switch (type) {
          case "Circle":
            coordinates2 = [geometry.getCenter()];
            break;
          case "Point":
            coordinates2 = [coordinates2];
            break;
          case "Polygon":
            coordinates2 = coordinates2[0];
            break;
        }
        let lonlats = [];
        coordinates2.forEach((coordinate) => {
          lonlats.push(toLonLat$1(coordinate));
        });
        let obj = {
          coordinates: lonlats,
          type
        };
        if (type === "Circle") {
          let radius = geometry.getRadius();
          obj.radius = radius;
        }
        data.push(obj);
      });
      emit("drawFinish", data);
    };
    const destory = () => {
      gyMapObj.value.map.removeInteraction(modify);
      gyMapObj.value.map.removeInteraction(drawObj);
      gyMapObj.value.map.removeInteraction(snapObj);
    };
    onMounted(() => {
      drawCon.value.style.setProperty("--btnBackground", props.btnBackground);
      drawCon.value.style.setProperty("--btnColor", props.btnColor);
      drawCon.value.style.setProperty("--deleteActiveBackground", props.deleteActiveBackground);
      drawCon.value.style.setProperty("--deleteActiveColor", props.deleteActiveColor);
      drawCon.value.style.setProperty("--btnActiveBackground", props.btnActiveBackground);
      drawCon.value.style.setProperty("--btnActiveColor", props.btnActiveColor);
    });
    onBeforeUnmount(() => {
      destory();
    });
    return {
      drawCon,
      drawType,
      status,
      gyMapObj,
      mapFinish,
      hasFeature,
      startDraw,
      deleteDraw,
      changeDrawType,
      endDraw,
      submitData,
      destory
    };
  }
});
var render$3 = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div", {
    directives: [{
      name: "show",
      rawName: "v-show",
      value: _vm.mapFinish,
      expression: "mapFinish"
    }],
    ref: "drawCon",
    staticClass: "draw-btns-list"
  }, [_c("div", {
    directives: [{
      name: "show",
      rawName: "v-show",
      value: !_vm.status || _vm.status === "end",
      expression: "!status || status === 'end'"
    }],
    staticClass: "draw-start draw-btn",
    on: {
      "click": _vm.startDraw
    }
  }, [_vm._v("\u5F00\u59CB\u7ED8\u5236")]), _c("div", {
    directives: [{
      name: "show",
      rawName: "v-show",
      value: _vm.status && _vm.status !== "end",
      expression: "status && status !== 'end'"
    }],
    staticClass: "draw-type draw-btn draw-type-select"
  }, [_vm._v(" \u7ED8\u5236\u7C7B\u578B "), _c("div", {
    staticClass: "draw-type-select-con"
  }, _vm._l(_vm.drawTypeList, function(item, index2) {
    return _c("div", {
      key: "type" + index2,
      class: ["draw-type-option", {
        "active": _vm.drawType === item
      }],
      on: {
        "click": function($event) {
          return _vm.changeDrawType(item);
        }
      }
    }, [_vm._v(" " + _vm._s(_vm.drawTypeCnameList[index2] || "\u5F85\u5B9A") + " ")]);
  }), 0)]), _c("div", {
    directives: [{
      name: "show",
      rawName: "v-show",
      value: _vm.status && _vm.status !== "end",
      expression: "status && status !== 'end'"
    }],
    staticClass: "draw-end draw-btn",
    on: {
      "click": function($event) {
        return _vm.endDraw(true);
      }
    }
  }, [_vm._v("\u7ED8\u5236\u5B8C\u6210")]), _c("div", {
    directives: [{
      name: "show",
      rawName: "v-show",
      value: _vm.hasFeature && _vm.status && _vm.status !== "end",
      expression: "hasFeature && (status && status !== 'end')"
    }],
    class: ["draw-end", "draw-btn", {
      "active": _vm.status === "delete"
    }],
    on: {
      "click": _vm.deleteDraw
    }
  }, [_vm._v("\u5220\u9664\u56FE\u5F62 ")])]);
};
var staticRenderFns$3 = [];
const GymapDraw_vue_vue_type_style_index_0_scoped_true_lang = "";
const __cssModules$3 = {};
var __component__$3 = /* @__PURE__ */ normalizeComponent(
  __vue2_script$3,
  render$3,
  staticRenderFns$3,
  false,
  __vue2_injectStyles$3,
  "408c15a3",
  null,
  null
);
function __vue2_injectStyles$3(context) {
  for (let o in __cssModules$3) {
    this[o] = __cssModules$3[o];
  }
}
const GymapDraw = /* @__PURE__ */ function() {
  return __component__$3.exports;
}();
class CreateHeatMapLayer extends createOlLayer {
  constructor(id, position, stylesObj, emit) {
    super(id, stylesObj, emit);
    __publicField(this, "visible");
    __publicField(this, "gradien");
    __publicField(this, "radius");
    __publicField(this, "blur");
    __publicField(this, "weight");
    __publicField(this, "heatMapData");
    __publicField(this, "maxValue");
    __publicField(this, "minValue");
    __publicField(this, "subValue");
    this.gradien = stylesObj.gradien;
    this.weight = stylesObj.weight;
    this.maxValue = stylesObj.maxValue;
    this.minValue = stylesObj.minValue;
    this.heatMapData = computed(() => stylesObj.data);
    this.visible = computed(() => stylesObj.visible);
    this.radius = computed(() => stylesObj.radius);
    this.blur = computed(() => stylesObj.blur);
    this.minZoom = computed(() => stylesObj.minZoom);
    this.maxZoom = computed(() => stylesObj.maxZoom);
    this.opacity = computed(() => stylesObj.opacity);
    this.subValue = 0;
    this.formatMinMaxValue();
    this.draw();
  }
  formatMinMaxValue() {
    if (this.minValue < 0) {
      this.subValue = Math.abs(this.minValue);
      this.minValue = 0;
      this.maxValue = gyMapUtils.flortAdd(this.maxValue, this.subValue);
    }
  }
  checkData() {
    if (this.heatMapData.value.length !== 0) {
      let fitstData = this.heatMapData.value[0];
      if (Array.isArray(fitstData)) {
        if (fitstData.length < 3) {
          console.error("\u8BF7\u4F20\u5165\u6B63\u786E\u7684\u6570\u636E\u683C\u5F0F\uFF01");
          return false;
        }
        return true;
      } else {
        console.error("\u8BF7\u4F20\u5165\u6B63\u786E\u7684\u6570\u636E\u683C\u5F0F\uFF01");
        return false;
      }
    }
    return true;
  }
  addFeature() {
  }
  addFeatures() {
    let features = [];
    if (this.checkData()) {
      features = this.heatMapData.value.map((data) => {
        let lonlat = [data[0], data[1]];
        const geo = new Point$3(gyMapUtils.formatLonLatToPosition(lonlat));
        return new feature({
          geometry: geo,
          data
        });
      });
    }
    return features;
  }
  addSource() {
  }
  addLayer() {
    let weightHandler = this.weight ? (feature2) => this.weight(feature2.get("data"), feature2) : (feature2) => {
      const item = feature2.get("data") || [];
      let value = item[2];
      if (this.subValue !== 0) {
        value = gyMapUtils.flortAdd(value, this.subValue);
      }
      if (value > this.maxValue) {
        return 1;
      } else if (value < this.minValue) {
        return 0;
      } else {
        return value / this.maxValue;
      }
    };
    let features = this.addFeatures();
    let source = new VectorSource$2({
      features
    });
    this.layer = new Heatmap({
      source,
      blur: this.blur.value,
      radius: this.radius.value,
      visible: this.visible.value,
      gradient: this.gradien,
      weight: weightHandler,
      minZoom: this.minZoom.value,
      maxZoom: this.maxZoom.value,
      opacity: this.opacity.value
    });
  }
  addLayerWatch() {
    watch(this.heatMapData, (n) => {
      this.destory();
      this.addLayer();
      this.addLayerToMap();
    });
    watch(this.visible, (n) => {
      var _a;
      (_a = this.layer) == null ? void 0 : _a.setVisible(n);
    });
    watch(this.radius, (n) => {
      var _a;
      (_a = this.layer) == null ? void 0 : _a.setRadius(n);
    });
    watch(this.blur, (n) => {
      var _a;
      (_a = this.layer) == null ? void 0 : _a.setBlur(n);
    });
    watch(this.minZoom, (n) => {
      var _a;
      (_a = this.layer) == null ? void 0 : _a.setMinZoom(n);
    });
    watch(this.maxZoom, (n) => {
      var _a;
      (_a = this.layer) == null ? void 0 : _a.setMaxZoom(n);
    });
    watch(this.opacity, (n) => {
      var _a;
      (_a = this.layer) == null ? void 0 : _a.setOpacity(n);
    });
  }
  addPropsWatch() {
    watch(this.stylesObj, () => {
    });
  }
}
const layerProps = {
  data: {
    type: Array,
    default: () => []
  },
  visible: {
    type: Boolean,
    default: true
  },
  gradien: {
    type: Array,
    default: () => ["#00f", "#0ff", "#0f0", "#ff0", "#f00"]
  },
  radius: {
    type: Number,
    default: 100
  },
  blur: {
    type: Number,
    default: 100
  },
  maxValue: {
    type: Number,
    default: 1
  },
  minValue: {
    type: Number,
    default: 0
  },
  subValue: {
    type: Number,
    default: 0
  },
  weight: {
    type: [String, Function],
    default: ""
  },
  minZoom: {
    type: Number,
    default: 1
  },
  maxZoom: {
    type: Number,
    default: 18
  },
  opacity: {
    type: Number,
    default: 1
  },
  mapId: {
    type: String,
    default: ""
  }
};
const __vue2_script$2 = defineComponent({
  name: "GymapHeat",
  props: {
    ...layerProps
  },
  setup(props) {
    const { proxy } = getCurrentInstance();
    const mapId = props.mapId || proxy.$parent.id;
    let layerObj = null;
    onMounted(() => {
      layerObj = new CreateHeatMapLayer(mapId, props.position, props);
    });
    const destory = () => {
      layerObj.destory();
      layerObj = null;
    };
    onBeforeUnmount(() => {
      destory();
    });
  }
});
var render$2 = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div");
};
var staticRenderFns$2 = [];
const __cssModules$2 = {};
var __component__$2 = /* @__PURE__ */ normalizeComponent(
  __vue2_script$2,
  render$2,
  staticRenderFns$2,
  false,
  __vue2_injectStyles$2,
  null,
  null,
  null
);
function __vue2_injectStyles$2(context) {
  for (let o in __cssModules$2) {
    this[o] = __cssModules$2[o];
  }
}
const GymapHeat = /* @__PURE__ */ function() {
  return __component__$2.exports;
}();
const __vue2_script$1 = defineComponent({
  name: "GymapLonlat",
  props: {
    showCon: {
      type: Boolean,
      default: true
    },
    className: {
      type: String,
      default: ""
    }
  },
  emits: ["getLonlat"],
  setup(props, { emit }) {
    const { proxy } = getCurrentInstance();
    const mapId = proxy.$parent.id;
    const gyMapObj = gyMap$1(mapId);
    const mapFinish = computed(() => gyMapObj.value && gyMapObj.value.mapFinish);
    let isOn = false;
    const lonlat = ref("");
    const getLonLat = (e) => {
      let coordinate = e.coordinate;
      let l = toLonLat$1(coordinate);
      lonlat.value = l.join(",");
      emit("getLonlat", lonlat.value);
    };
    const addEvent = () => {
      if (mapFinish.value && !isOn) {
        gyMapObj.value.map.on("click", getLonLat);
      }
    };
    watch(mapFinish, () => {
      addEvent();
    });
    onMounted(() => {
      addEvent();
    });
    const destory = () => {
      gyMapObj.value.map && gyMapObj.value.map.un("click", getLonLat);
    };
    onBeforeUnmount(() => {
      destory();
    });
    return {
      className: props.className,
      lonlat
    };
  }
});
var render$1 = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div", {
    directives: [{
      name: "show",
      rawName: "v-show",
      value: _vm.showCon,
      expression: "showCon"
    }],
    class: ["GySjmapLonlat-con", _vm.className]
  }, [_vm._v(" " + _vm._s(_vm.lonlat) + " ")]);
};
var staticRenderFns$1 = [];
const GymapLonlat_vue_vue_type_style_index_0_scoped_true_lang = "";
const __cssModules$1 = {};
var __component__$1 = /* @__PURE__ */ normalizeComponent(
  __vue2_script$1,
  render$1,
  staticRenderFns$1,
  false,
  __vue2_injectStyles$1,
  "f531d402",
  null,
  null
);
function __vue2_injectStyles$1(context) {
  for (let o in __cssModules$1) {
    this[o] = __cssModules$1[o];
  }
}
const GymapLonlat = /* @__PURE__ */ function() {
  return __component__$1.exports;
}();
const ObjectEventType = {
  PROPERTYCHANGE: "propertychange"
};
const EventType = {
  CHANGE: "change",
  ERROR: "error",
  BLUR: "blur",
  CLEAR: "clear",
  CONTEXTMENU: "contextmenu",
  CLICK: "click",
  DBLCLICK: "dblclick",
  DRAGENTER: "dragenter",
  DRAGOVER: "dragover",
  DROP: "drop",
  FOCUS: "focus",
  KEYDOWN: "keydown",
  KEYPRESS: "keypress",
  LOAD: "load",
  RESIZE: "resize",
  TOUCHMOVE: "touchmove",
  WHEEL: "wheel"
};
class Disposable {
  constructor() {
    this.disposed = false;
  }
  dispose() {
    if (!this.disposed) {
      this.disposed = true;
      this.disposeInternal();
    }
  }
  disposeInternal() {
  }
}
const Disposable$1 = Disposable;
function binarySearch(haystack, needle, comparator) {
  let mid, cmp;
  comparator = comparator || ascending;
  let low = 0;
  let high = haystack.length;
  let found = false;
  while (low < high) {
    mid = low + (high - low >> 1);
    cmp = +comparator(haystack[mid], needle);
    if (cmp < 0) {
      low = mid + 1;
    } else {
      high = mid;
      found = !cmp;
    }
  }
  return found ? low : ~low;
}
function ascending(a3, b) {
  return a3 > b ? 1 : a3 < b ? -1 : 0;
}
function descending(a3, b) {
  return a3 < b ? 1 : a3 > b ? -1 : 0;
}
function linearFindNearest(arr, target, direction) {
  if (arr[0] <= target) {
    return 0;
  }
  const n = arr.length;
  if (target <= arr[n - 1]) {
    return n - 1;
  }
  if (typeof direction === "function") {
    for (let i = 1; i < n; ++i) {
      const candidate = arr[i];
      if (candidate === target) {
        return i;
      }
      if (candidate < target) {
        if (direction(target, arr[i - 1], candidate) > 0) {
          return i - 1;
        }
        return i;
      }
    }
    return n - 1;
  }
  if (direction > 0) {
    for (let i = 1; i < n; ++i) {
      if (arr[i] < target) {
        return i - 1;
      }
    }
    return n - 1;
  }
  if (direction < 0) {
    for (let i = 1; i < n; ++i) {
      if (arr[i] <= target) {
        return i;
      }
    }
    return n - 1;
  }
  for (let i = 1; i < n; ++i) {
    if (arr[i] == target) {
      return i;
    }
    if (arr[i] < target) {
      if (arr[i - 1] - target < target - arr[i]) {
        return i - 1;
      }
      return i;
    }
  }
  return n - 1;
}
function reverseSubArray(arr, begin, end) {
  while (begin < end) {
    const tmp = arr[begin];
    arr[begin] = arr[end];
    arr[end] = tmp;
    ++begin;
    --end;
  }
}
function extend$2(arr, data) {
  const extension = Array.isArray(data) ? data : [data];
  const length = extension.length;
  for (let i = 0; i < length; i++) {
    arr[arr.length] = extension[i];
  }
}
function equals$2(arr1, arr2) {
  const len1 = arr1.length;
  if (len1 !== arr2.length) {
    return false;
  }
  for (let i = 0; i < len1; i++) {
    if (arr1[i] !== arr2[i]) {
      return false;
    }
  }
  return true;
}
function TRUE() {
  return true;
}
function FALSE() {
  return false;
}
function VOID() {
}
function memoizeOne(fn) {
  let lastResult;
  let lastArgs;
  let lastThis;
  return function() {
    const nextArgs = Array.prototype.slice.call(arguments);
    if (!lastArgs || this !== lastThis || !equals$2(nextArgs, lastArgs)) {
      lastThis = this;
      lastArgs = nextArgs;
      lastResult = fn.apply(this, arguments);
    }
    return lastResult;
  };
}
function toPromise(getter) {
  function promiseGetter() {
    let value;
    try {
      value = getter();
    } catch (err) {
      return Promise.reject(err);
    }
    if (value instanceof Promise) {
      return value;
    }
    return Promise.resolve(value);
  }
  return promiseGetter();
}
function clear(object) {
  for (const property in object) {
    delete object[property];
  }
}
function isEmpty$1(object) {
  let property;
  for (property in object) {
    return false;
  }
  return !property;
}
class BaseEvent {
  constructor(type) {
    this.propagationStopped;
    this.defaultPrevented;
    this.type = type;
    this.target = null;
  }
  preventDefault() {
    this.defaultPrevented = true;
  }
  stopPropagation() {
    this.propagationStopped = true;
  }
}
const Event = BaseEvent;
class Target extends Disposable$1 {
  constructor(target) {
    super();
    this.eventTarget_ = target;
    this.pendingRemovals_ = null;
    this.dispatching_ = null;
    this.listeners_ = null;
  }
  addEventListener(type, listener) {
    if (!type || !listener) {
      return;
    }
    const listeners = this.listeners_ || (this.listeners_ = {});
    const listenersForType = listeners[type] || (listeners[type] = []);
    if (!listenersForType.includes(listener)) {
      listenersForType.push(listener);
    }
  }
  dispatchEvent(event) {
    const isString = typeof event === "string";
    const type = isString ? event : event.type;
    const listeners = this.listeners_ && this.listeners_[type];
    if (!listeners) {
      return;
    }
    const evt = isString ? new Event(event) : event;
    if (!evt.target) {
      evt.target = this.eventTarget_ || this;
    }
    const dispatching = this.dispatching_ || (this.dispatching_ = {});
    const pendingRemovals = this.pendingRemovals_ || (this.pendingRemovals_ = {});
    if (!(type in dispatching)) {
      dispatching[type] = 0;
      pendingRemovals[type] = 0;
    }
    ++dispatching[type];
    let propagate;
    for (let i = 0, ii = listeners.length; i < ii; ++i) {
      if ("handleEvent" in listeners[i]) {
        propagate = listeners[i].handleEvent(evt);
      } else {
        propagate = listeners[i].call(this, evt);
      }
      if (propagate === false || evt.propagationStopped) {
        propagate = false;
        break;
      }
    }
    if (--dispatching[type] === 0) {
      let pr = pendingRemovals[type];
      delete pendingRemovals[type];
      while (pr--) {
        this.removeEventListener(type, VOID);
      }
      delete dispatching[type];
    }
    return propagate;
  }
  disposeInternal() {
    this.listeners_ && clear(this.listeners_);
  }
  getListeners(type) {
    return this.listeners_ && this.listeners_[type] || void 0;
  }
  hasListener(type) {
    if (!this.listeners_) {
      return false;
    }
    return type ? type in this.listeners_ : Object.keys(this.listeners_).length > 0;
  }
  removeEventListener(type, listener) {
    if (!this.listeners_) {
      return;
    }
    const listeners = this.listeners_[type];
    if (!listeners) {
      return;
    }
    const index2 = listeners.indexOf(listener);
    if (index2 !== -1) {
      if (this.pendingRemovals_ && type in this.pendingRemovals_) {
        listeners[index2] = VOID;
        ++this.pendingRemovals_[type];
      } else {
        listeners.splice(index2, 1);
        if (listeners.length === 0) {
          delete this.listeners_[type];
        }
      }
    }
  }
}
const EventTarget = Target;
function listen(target, type, listener, thisArg, once) {
  if (once) {
    const originalListener = listener;
    listener = function(event) {
      target.removeEventListener(type, listener);
      return originalListener.call(thisArg != null ? thisArg : this, event);
    };
  } else if (thisArg && thisArg !== target) {
    listener = listener.bind(thisArg);
  }
  const eventsKey = {
    target,
    type,
    listener
  };
  target.addEventListener(type, listener);
  return eventsKey;
}
function listenOnce(target, type, listener, thisArg) {
  return listen(target, type, listener, thisArg, true);
}
function unlistenByKey(key) {
  if (key && key.target) {
    key.target.removeEventListener(key.type, key.listener);
    clear(key);
  }
}
class Observable extends EventTarget {
  constructor() {
    super();
    this.on = this.onInternal;
    this.once = this.onceInternal;
    this.un = this.unInternal;
    this.revision_ = 0;
  }
  changed() {
    ++this.revision_;
    this.dispatchEvent(EventType.CHANGE);
  }
  getRevision() {
    return this.revision_;
  }
  onInternal(type, listener) {
    if (Array.isArray(type)) {
      const len = type.length;
      const keys = new Array(len);
      for (let i = 0; i < len; ++i) {
        keys[i] = listen(this, type[i], listener);
      }
      return keys;
    }
    return listen(this, type, listener);
  }
  onceInternal(type, listener) {
    let key;
    if (Array.isArray(type)) {
      const len = type.length;
      key = new Array(len);
      for (let i = 0; i < len; ++i) {
        key[i] = listenOnce(this, type[i], listener);
      }
    } else {
      key = listenOnce(this, type, listener);
    }
    listener.ol_key = key;
    return key;
  }
  unInternal(type, listener) {
    const key = listener.ol_key;
    if (key) {
      unByKey(key);
    } else if (Array.isArray(type)) {
      for (let i = 0, ii = type.length; i < ii; ++i) {
        this.removeEventListener(type[i], listener);
      }
    } else {
      this.removeEventListener(type, listener);
    }
  }
}
Observable.prototype.on;
Observable.prototype.once;
Observable.prototype.un;
function unByKey(key) {
  if (Array.isArray(key)) {
    for (let i = 0, ii = key.length; i < ii; ++i) {
      unlistenByKey(key[i]);
    }
  } else {
    unlistenByKey(key);
  }
}
const Observable$1 = Observable;
function abstract() {
  throw new Error("Unimplemented abstract method.");
}
let uidCounter_ = 0;
function getUid(obj) {
  return obj.ol_uid || (obj.ol_uid = String(++uidCounter_));
}
class ObjectEvent extends Event {
  constructor(type, key, oldValue) {
    super(type);
    this.key = key;
    this.oldValue = oldValue;
  }
}
class BaseObject extends Observable$1 {
  constructor(values) {
    super();
    this.on;
    this.once;
    this.un;
    getUid(this);
    this.values_ = null;
    if (values !== void 0) {
      this.setProperties(values);
    }
  }
  get(key) {
    let value;
    if (this.values_ && this.values_.hasOwnProperty(key)) {
      value = this.values_[key];
    }
    return value;
  }
  getKeys() {
    return this.values_ && Object.keys(this.values_) || [];
  }
  getProperties() {
    return this.values_ && Object.assign({}, this.values_) || {};
  }
  getPropertiesInternal() {
    return this.values_;
  }
  hasProperties() {
    return !!this.values_;
  }
  notify(key, oldValue) {
    let eventType;
    eventType = `change:${key}`;
    if (this.hasListener(eventType)) {
      this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
    }
    eventType = ObjectEventType.PROPERTYCHANGE;
    if (this.hasListener(eventType)) {
      this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
    }
  }
  addChangeListener(key, listener) {
    this.addEventListener(`change:${key}`, listener);
  }
  removeChangeListener(key, listener) {
    this.removeEventListener(`change:${key}`, listener);
  }
  set(key, value, silent) {
    const values = this.values_ || (this.values_ = {});
    if (silent) {
      values[key] = value;
    } else {
      const oldValue = values[key];
      values[key] = value;
      if (oldValue !== value) {
        this.notify(key, oldValue);
      }
    }
  }
  setProperties(values, silent) {
    for (const key in values) {
      this.set(key, values[key], silent);
    }
  }
  applyProperties(source) {
    if (!source.values_) {
      return;
    }
    Object.assign(this.values_ || (this.values_ = {}), source.values_);
  }
  unset(key, silent) {
    if (this.values_ && key in this.values_) {
      const oldValue = this.values_[key];
      delete this.values_[key];
      if (isEmpty$1(this.values_)) {
        this.values_ = null;
      }
      if (!silent) {
        this.notify(key, oldValue);
      }
    }
  }
}
const BaseObject$1 = BaseObject;
function assert(assertion, errorMessage) {
  if (!assertion) {
    throw new Error(errorMessage);
  }
}
class Feature extends BaseObject$1 {
  constructor(geometryOrProperties) {
    super();
    this.on;
    this.once;
    this.un;
    this.id_ = void 0;
    this.geometryName_ = "geometry";
    this.style_ = null;
    this.styleFunction_ = void 0;
    this.geometryChangeKey_ = null;
    this.addChangeListener(this.geometryName_, this.handleGeometryChanged_);
    if (geometryOrProperties) {
      if (typeof geometryOrProperties.getSimplifiedGeometry === "function") {
        const geometry = geometryOrProperties;
        this.setGeometry(geometry);
      } else {
        const properties = geometryOrProperties;
        this.setProperties(properties);
      }
    }
  }
  clone() {
    const clone2 = new Feature(this.hasProperties() ? this.getProperties() : null);
    clone2.setGeometryName(this.getGeometryName());
    const geometry = this.getGeometry();
    if (geometry) {
      clone2.setGeometry(geometry.clone());
    }
    const style = this.getStyle();
    if (style) {
      clone2.setStyle(style);
    }
    return clone2;
  }
  getGeometry() {
    return this.get(this.geometryName_);
  }
  getId() {
    return this.id_;
  }
  getGeometryName() {
    return this.geometryName_;
  }
  getStyle() {
    return this.style_;
  }
  getStyleFunction() {
    return this.styleFunction_;
  }
  handleGeometryChange_() {
    this.changed();
  }
  handleGeometryChanged_() {
    if (this.geometryChangeKey_) {
      unlistenByKey(this.geometryChangeKey_);
      this.geometryChangeKey_ = null;
    }
    const geometry = this.getGeometry();
    if (geometry) {
      this.geometryChangeKey_ = listen(
        geometry,
        EventType.CHANGE,
        this.handleGeometryChange_,
        this
      );
    }
    this.changed();
  }
  setGeometry(geometry) {
    this.set(this.geometryName_, geometry);
  }
  setStyle(style) {
    this.style_ = style;
    this.styleFunction_ = !style ? void 0 : createStyleFunction(style);
    this.changed();
  }
  setId(id) {
    this.id_ = id;
    this.changed();
  }
  setGeometryName(name) {
    this.removeChangeListener(this.geometryName_, this.handleGeometryChanged_);
    this.geometryName_ = name;
    this.addChangeListener(this.geometryName_, this.handleGeometryChanged_);
    this.handleGeometryChanged_();
  }
}
function createStyleFunction(obj) {
  if (typeof obj === "function") {
    return obj;
  }
  let styles;
  if (Array.isArray(obj)) {
    styles = obj;
  } else {
    assert(
      typeof obj.getZIndex === "function",
      "Expected an `ol/style/Style` or an array of `ol/style/Style.js`"
    );
    const style = obj;
    styles = [style];
  }
  return function() {
    return styles;
  };
}
const Feature$1 = Feature;
const Relationship = {
  UNKNOWN: 0,
  INTERSECTING: 1,
  ABOVE: 2,
  RIGHT: 4,
  BELOW: 8,
  LEFT: 16
};
function buffer(extent, value, dest) {
  if (dest) {
    dest[0] = extent[0] - value;
    dest[1] = extent[1] - value;
    dest[2] = extent[2] + value;
    dest[3] = extent[3] + value;
    return dest;
  }
  return [
    extent[0] - value,
    extent[1] - value,
    extent[2] + value,
    extent[3] + value
  ];
}
function clone(extent, dest) {
  if (dest) {
    dest[0] = extent[0];
    dest[1] = extent[1];
    dest[2] = extent[2];
    dest[3] = extent[3];
    return dest;
  }
  return extent.slice();
}
function closestSquaredDistanceXY(extent, x, y) {
  let dx, dy;
  if (x < extent[0]) {
    dx = extent[0] - x;
  } else if (extent[2] < x) {
    dx = x - extent[2];
  } else {
    dx = 0;
  }
  if (y < extent[1]) {
    dy = extent[1] - y;
  } else if (extent[3] < y) {
    dy = y - extent[3];
  } else {
    dy = 0;
  }
  return dx * dx + dy * dy;
}
function containsCoordinate(extent, coordinate) {
  return containsXY(extent, coordinate[0], coordinate[1]);
}
function containsExtent(extent1, extent2) {
  return extent1[0] <= extent2[0] && extent2[2] <= extent1[2] && extent1[1] <= extent2[1] && extent2[3] <= extent1[3];
}
function containsXY(extent, x, y) {
  return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3];
}
function coordinateRelationship(extent, coordinate) {
  const minX = extent[0];
  const minY = extent[1];
  const maxX = extent[2];
  const maxY = extent[3];
  const x = coordinate[0];
  const y = coordinate[1];
  let relationship = Relationship.UNKNOWN;
  if (x < minX) {
    relationship = relationship | Relationship.LEFT;
  } else if (x > maxX) {
    relationship = relationship | Relationship.RIGHT;
  }
  if (y < minY) {
    relationship = relationship | Relationship.BELOW;
  } else if (y > maxY) {
    relationship = relationship | Relationship.ABOVE;
  }
  if (relationship === Relationship.UNKNOWN) {
    relationship = Relationship.INTERSECTING;
  }
  return relationship;
}
function createEmpty() {
  return [Infinity, Infinity, -Infinity, -Infinity];
}
function createOrUpdate(minX, minY, maxX, maxY, dest) {
  if (dest) {
    dest[0] = minX;
    dest[1] = minY;
    dest[2] = maxX;
    dest[3] = maxY;
    return dest;
  }
  return [minX, minY, maxX, maxY];
}
function createOrUpdateEmpty(dest) {
  return createOrUpdate(Infinity, Infinity, -Infinity, -Infinity, dest);
}
function createOrUpdateFromCoordinate(coordinate, dest) {
  const x = coordinate[0];
  const y = coordinate[1];
  return createOrUpdate(x, y, x, y, dest);
}
function createOrUpdateFromFlatCoordinates(flatCoordinates, offset, end, stride, dest) {
  const extent = createOrUpdateEmpty(dest);
  return extendFlatCoordinates(extent, flatCoordinates, offset, end, stride);
}
function equals$1(extent1, extent2) {
  return extent1[0] == extent2[0] && extent1[2] == extent2[2] && extent1[1] == extent2[1] && extent1[3] == extent2[3];
}
function extend$1(extent1, extent2) {
  if (extent2[0] < extent1[0]) {
    extent1[0] = extent2[0];
  }
  if (extent2[2] > extent1[2]) {
    extent1[2] = extent2[2];
  }
  if (extent2[1] < extent1[1]) {
    extent1[1] = extent2[1];
  }
  if (extent2[3] > extent1[3]) {
    extent1[3] = extent2[3];
  }
  return extent1;
}
function extendCoordinate(extent, coordinate) {
  if (coordinate[0] < extent[0]) {
    extent[0] = coordinate[0];
  }
  if (coordinate[0] > extent[2]) {
    extent[2] = coordinate[0];
  }
  if (coordinate[1] < extent[1]) {
    extent[1] = coordinate[1];
  }
  if (coordinate[1] > extent[3]) {
    extent[3] = coordinate[1];
  }
}
function extendFlatCoordinates(extent, flatCoordinates, offset, end, stride) {
  for (; offset < end; offset += stride) {
    extendXY(extent, flatCoordinates[offset], flatCoordinates[offset + 1]);
  }
  return extent;
}
function extendXY(extent, x, y) {
  extent[0] = Math.min(extent[0], x);
  extent[1] = Math.min(extent[1], y);
  extent[2] = Math.max(extent[2], x);
  extent[3] = Math.max(extent[3], y);
}
function forEachCorner(extent, callback) {
  let val;
  val = callback(getBottomLeft(extent));
  if (val) {
    return val;
  }
  val = callback(getBottomRight(extent));
  if (val) {
    return val;
  }
  val = callback(getTopRight(extent));
  if (val) {
    return val;
  }
  val = callback(getTopLeft(extent));
  if (val) {
    return val;
  }
  return false;
}
function getBottomLeft(extent) {
  return [extent[0], extent[1]];
}
function getBottomRight(extent) {
  return [extent[2], extent[1]];
}
function getCenter(extent) {
  return [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2];
}
function getForViewAndSize(center, resolution, rotation, size, dest) {
  const [x0, y0, x1, y1, x2, y2, x3, y3] = getRotatedViewport(
    center,
    resolution,
    rotation,
    size
  );
  return createOrUpdate(
    Math.min(x0, x1, x2, x3),
    Math.min(y0, y1, y2, y3),
    Math.max(x0, x1, x2, x3),
    Math.max(y0, y1, y2, y3),
    dest
  );
}
function getRotatedViewport(center, resolution, rotation, size) {
  const dx = resolution * size[0] / 2;
  const dy = resolution * size[1] / 2;
  const cosRotation = Math.cos(rotation);
  const sinRotation = Math.sin(rotation);
  const xCos = dx * cosRotation;
  const xSin = dx * sinRotation;
  const yCos = dy * cosRotation;
  const ySin = dy * sinRotation;
  const x = center[0];
  const y = center[1];
  return [
    x - xCos + ySin,
    y - xSin - yCos,
    x - xCos - ySin,
    y - xSin + yCos,
    x + xCos - ySin,
    y + xSin + yCos,
    x + xCos + ySin,
    y + xSin - yCos,
    x - xCos + ySin,
    y - xSin - yCos
  ];
}
function getHeight(extent) {
  return extent[3] - extent[1];
}
function getTopLeft(extent) {
  return [extent[0], extent[3]];
}
function getTopRight(extent) {
  return [extent[2], extent[3]];
}
function getWidth(extent) {
  return extent[2] - extent[0];
}
function intersects$1(extent1, extent2) {
  return extent1[0] <= extent2[2] && extent1[2] >= extent2[0] && extent1[1] <= extent2[3] && extent1[3] >= extent2[1];
}
function isEmpty(extent) {
  return extent[2] < extent[0] || extent[3] < extent[1];
}
function returnOrUpdate(extent, dest) {
  if (dest) {
    dest[0] = extent[0];
    dest[1] = extent[1];
    dest[2] = extent[2];
    dest[3] = extent[3];
    return dest;
  }
  return extent;
}
function intersectsSegment(extent, start, end) {
  let intersects2 = false;
  const startRel = coordinateRelationship(extent, start);
  const endRel = coordinateRelationship(extent, end);
  if (startRel === Relationship.INTERSECTING || endRel === Relationship.INTERSECTING) {
    intersects2 = true;
  } else {
    const minX = extent[0];
    const minY = extent[1];
    const maxX = extent[2];
    const maxY = extent[3];
    const startX = start[0];
    const startY = start[1];
    const endX = end[0];
    const endY = end[1];
    const slope = (endY - startY) / (endX - startX);
    let x, y;
    if (!!(endRel & Relationship.ABOVE) && !(startRel & Relationship.ABOVE)) {
      x = endX - (endY - maxY) / slope;
      intersects2 = x >= minX && x <= maxX;
    }
    if (!intersects2 && !!(endRel & Relationship.RIGHT) && !(startRel & Relationship.RIGHT)) {
      y = endY - (endX - maxX) * slope;
      intersects2 = y >= minY && y <= maxY;
    }
    if (!intersects2 && !!(endRel & Relationship.BELOW) && !(startRel & Relationship.BELOW)) {
      x = endX - (endY - minY) / slope;
      intersects2 = x >= minX && x <= maxX;
    }
    if (!intersects2 && !!(endRel & Relationship.LEFT) && !(startRel & Relationship.LEFT)) {
      y = endY - (endX - minX) * slope;
      intersects2 = y >= minY && y <= maxY;
    }
  }
  return intersects2;
}
function wrapX$1(extent, projection) {
  const projectionExtent = projection.getExtent();
  const center = getCenter(extent);
  if (projection.canWrapX() && (center[0] < projectionExtent[0] || center[0] >= projectionExtent[2])) {
    const worldWidth = getWidth(projectionExtent);
    const worldsAway = Math.floor(
      (center[0] - projectionExtent[0]) / worldWidth
    );
    const offset = worldsAway * worldWidth;
    extent[0] -= offset;
    extent[2] -= offset;
  }
  return extent;
}
function wrapAndSliceX(extent, projection, multiWorld) {
  if (projection.canWrapX()) {
    const projectionExtent = projection.getExtent();
    if (!isFinite(extent[0]) || !isFinite(extent[2])) {
      return [[projectionExtent[0], extent[1], projectionExtent[2], extent[3]]];
    }
    wrapX$1(extent, projection);
    const worldWidth = getWidth(projectionExtent);
    if (getWidth(extent) > worldWidth && !multiWorld) {
      return [[projectionExtent[0], extent[1], projectionExtent[2], extent[3]]];
    }
    if (extent[0] < projectionExtent[0]) {
      return [
        [extent[0] + worldWidth, extent[1], projectionExtent[2], extent[3]],
        [projectionExtent[0], extent[1], extent[2], extent[3]]
      ];
    }
    if (extent[2] > projectionExtent[2]) {
      return [
        [extent[0], extent[1], projectionExtent[2], extent[3]],
        [projectionExtent[0], extent[1], extent[2] - worldWidth, extent[3]]
      ];
    }
  }
  return [extent];
}
function clamp(value, min, max) {
  return Math.min(Math.max(value, min), max);
}
function squaredSegmentDistance(x, y, x1, y1, x2, y2) {
  const dx = x2 - x1;
  const dy = y2 - y1;
  if (dx !== 0 || dy !== 0) {
    const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
    if (t > 1) {
      x1 = x2;
      y1 = y2;
    } else if (t > 0) {
      x1 += dx * t;
      y1 += dy * t;
    }
  }
  return squaredDistance(x, y, x1, y1);
}
function squaredDistance(x1, y1, x2, y2) {
  const dx = x2 - x1;
  const dy = y2 - y1;
  return dx * dx + dy * dy;
}
function toDegrees(angleInRadians) {
  return angleInRadians * 180 / Math.PI;
}
function toRadians(angleInDegrees) {
  return angleInDegrees * Math.PI / 180;
}
function modulo(a3, b) {
  const r = a3 % b;
  return r * b < 0 ? r + b : r;
}
function lerp(a3, b, x) {
  return a3 + x * (b - a3);
}
function toFixed(n, decimals) {
  const factor = Math.pow(10, decimals);
  return Math.round(n * factor) / factor;
}
function wrap(n, min, max) {
  if (n >= min && n < max) {
    return n;
  }
  const range = max - min;
  return ((n - min) % range + range) % range + min;
}
function add$2(coordinate, delta) {
  coordinate[0] += +delta[0];
  coordinate[1] += +delta[1];
  return coordinate;
}
function equals(coordinate1, coordinate2) {
  let equals2 = true;
  for (let i = coordinate1.length - 1; i >= 0; --i) {
    if (coordinate1[i] != coordinate2[i]) {
      equals2 = false;
      break;
    }
  }
  return equals2;
}
function rotate$1(coordinate, angle) {
  const cosAngle = Math.cos(angle);
  const sinAngle = Math.sin(angle);
  const x = coordinate[0] * cosAngle - coordinate[1] * sinAngle;
  const y = coordinate[1] * cosAngle + coordinate[0] * sinAngle;
  coordinate[0] = x;
  coordinate[1] = y;
  return coordinate;
}
function scale$1(coordinate, scale2) {
  coordinate[0] *= scale2;
  coordinate[1] *= scale2;
  return coordinate;
}
function wrapX(coordinate, projection) {
  if (projection.canWrapX()) {
    const worldWidth = getWidth(projection.getExtent());
    const worldsAway = getWorldsAway(coordinate, projection, worldWidth);
    if (worldsAway) {
      coordinate[0] -= worldsAway * worldWidth;
    }
  }
  return coordinate;
}
function getWorldsAway(coordinate, projection, sourceExtentWidth) {
  const projectionExtent = projection.getExtent();
  let worldsAway = 0;
  if (projection.canWrapX() && (coordinate[0] < projectionExtent[0] || coordinate[0] > projectionExtent[2])) {
    sourceExtentWidth = sourceExtentWidth || getWidth(projectionExtent);
    worldsAway = Math.floor(
      (coordinate[0] - projectionExtent[0]) / sourceExtentWidth
    );
  }
  return worldsAway;
}
const levels = {
  info: 1,
  warn: 2,
  error: 3,
  none: 4
};
let level = levels.info;
function warn(...args) {
  if (level > levels.warn) {
    return;
  }
  console.warn(...args);
}
const METERS_PER_UNIT$1 = {
  "radians": 6370997 / (2 * Math.PI),
  "degrees": 2 * Math.PI * 6370997 / 360,
  "ft": 0.3048,
  "m": 1,
  "us-ft": 1200 / 3937
};
class Projection {
  constructor(options) {
    this.code_ = options.code;
    this.units_ = options.units;
    this.extent_ = options.extent !== void 0 ? options.extent : null;
    this.worldExtent_ = options.worldExtent !== void 0 ? options.worldExtent : null;
    this.axisOrientation_ = options.axisOrientation !== void 0 ? options.axisOrientation : "enu";
    this.global_ = options.global !== void 0 ? options.global : false;
    this.canWrapX_ = !!(this.global_ && this.extent_);
    this.getPointResolutionFunc_ = options.getPointResolution;
    this.defaultTileGrid_ = null;
    this.metersPerUnit_ = options.metersPerUnit;
  }
  canWrapX() {
    return this.canWrapX_;
  }
  getCode() {
    return this.code_;
  }
  getExtent() {
    return this.extent_;
  }
  getUnits() {
    return this.units_;
  }
  getMetersPerUnit() {
    return this.metersPerUnit_ || METERS_PER_UNIT$1[this.units_];
  }
  getWorldExtent() {
    return this.worldExtent_;
  }
  getAxisOrientation() {
    return this.axisOrientation_;
  }
  isGlobal() {
    return this.global_;
  }
  setGlobal(global) {
    this.global_ = global;
    this.canWrapX_ = !!(global && this.extent_);
  }
  getDefaultTileGrid() {
    return this.defaultTileGrid_;
  }
  setDefaultTileGrid(tileGrid) {
    this.defaultTileGrid_ = tileGrid;
  }
  setExtent(extent) {
    this.extent_ = extent;
    this.canWrapX_ = !!(this.global_ && extent);
  }
  setWorldExtent(worldExtent) {
    this.worldExtent_ = worldExtent;
  }
  setGetPointResolution(func) {
    this.getPointResolutionFunc_ = func;
  }
  getPointResolutionFunc() {
    return this.getPointResolutionFunc_;
  }
}
const Projection$1 = Projection;
const RADIUS$1 = 6378137;
const HALF_SIZE = Math.PI * RADIUS$1;
const EXTENT$1 = [-HALF_SIZE, -HALF_SIZE, HALF_SIZE, HALF_SIZE];
const WORLD_EXTENT = [-180, -85, 180, 85];
const MAX_SAFE_Y = RADIUS$1 * Math.log(Math.tan(Math.PI / 2));
class EPSG3857Projection extends Projection$1 {
  constructor(code) {
    super({
      code,
      units: "m",
      extent: EXTENT$1,
      global: true,
      worldExtent: WORLD_EXTENT,
      getPointResolution: function(resolution, point) {
        return resolution / Math.cosh(point[1] / RADIUS$1);
      }
    });
  }
}
const PROJECTIONS$1 = [
  new EPSG3857Projection("EPSG:3857"),
  new EPSG3857Projection("EPSG:102100"),
  new EPSG3857Projection("EPSG:102113"),
  new EPSG3857Projection("EPSG:900913"),
  new EPSG3857Projection("http://www.opengis.net/def/crs/EPSG/0/3857"),
  new EPSG3857Projection("http://www.opengis.net/gml/srs/epsg.xml#3857")
];
function fromEPSG4326(input, output, dimension, stride) {
  const length = input.length;
  dimension = dimension > 1 ? dimension : 2;
  stride = stride != null ? stride : dimension;
  if (output === void 0) {
    if (dimension > 2) {
      output = input.slice();
    } else {
      output = new Array(length);
    }
  }
  for (let i = 0; i < length; i += stride) {
    output[i] = HALF_SIZE * input[i] / 180;
    let y = RADIUS$1 * Math.log(Math.tan(Math.PI * (+input[i + 1] + 90) / 360));
    if (y > MAX_SAFE_Y) {
      y = MAX_SAFE_Y;
    } else if (y < -MAX_SAFE_Y) {
      y = -MAX_SAFE_Y;
    }
    output[i + 1] = y;
  }
  return output;
}
function toEPSG4326(input, output, dimension, stride) {
  const length = input.length;
  dimension = dimension > 1 ? dimension : 2;
  stride = stride != null ? stride : dimension;
  if (output === void 0) {
    if (dimension > 2) {
      output = input.slice();
    } else {
      output = new Array(length);
    }
  }
  for (let i = 0; i < length; i += stride) {
    output[i] = 180 * input[i] / HALF_SIZE;
    output[i + 1] = 360 * Math.atan(Math.exp(input[i + 1] / RADIUS$1)) / Math.PI - 90;
  }
  return output;
}
const RADIUS = 6378137;
const EXTENT = [-180, -90, 180, 90];
const METERS_PER_UNIT = Math.PI * RADIUS / 180;
class EPSG4326Projection extends Projection$1 {
  constructor(code, axisOrientation) {
    super({
      code,
      units: "degrees",
      extent: EXTENT,
      axisOrientation,
      global: true,
      metersPerUnit: METERS_PER_UNIT,
      worldExtent: EXTENT
    });
  }
}
const PROJECTIONS = [
  new EPSG4326Projection("CRS:84"),
  new EPSG4326Projection("EPSG:4326", "neu"),
  new EPSG4326Projection("urn:ogc:def:crs:OGC:1.3:CRS84"),
  new EPSG4326Projection("urn:ogc:def:crs:OGC:2:84"),
  new EPSG4326Projection("http://www.opengis.net/def/crs/OGC/1.3/CRS84"),
  new EPSG4326Projection("http://www.opengis.net/gml/srs/epsg.xml#4326", "neu"),
  new EPSG4326Projection("http://www.opengis.net/def/crs/EPSG/0/4326", "neu")
];
let cache$1 = {};
function get$3(code) {
  return cache$1[code] || cache$1[code.replace(/urn:(x-)?ogc:def:crs:EPSG:(.*:)?(\w+)$/, "EPSG:$3")] || null;
}
function add$1(code, projection) {
  cache$1[code] = projection;
}
let transforms = {};
function add(source, destination, transformFn) {
  const sourceCode = source.getCode();
  const destinationCode = destination.getCode();
  if (!(sourceCode in transforms)) {
    transforms[sourceCode] = {};
  }
  transforms[sourceCode][destinationCode] = transformFn;
}
function get$2(sourceCode, destinationCode) {
  if (sourceCode in transforms && destinationCode in transforms[sourceCode]) {
    return transforms[sourceCode][destinationCode];
  }
  return null;
}
const K0 = 0.9996;
const E = 669438e-8;
const E2 = E * E;
const E3 = E2 * E;
const E_P2 = E / (1 - E);
const SQRT_E = Math.sqrt(1 - E);
const _E = (1 - SQRT_E) / (1 + SQRT_E);
const _E2 = _E * _E;
const _E3 = _E2 * _E;
const _E4 = _E3 * _E;
const _E5 = _E4 * _E;
const M1 = 1 - E / 4 - 3 * E2 / 64 - 5 * E3 / 256;
const M2 = 3 * E / 8 + 3 * E2 / 32 + 45 * E3 / 1024;
const M3 = 15 * E2 / 256 + 45 * E3 / 1024;
const M4 = 35 * E3 / 3072;
const P2 = 3 / 2 * _E - 27 / 32 * _E3 + 269 / 512 * _E5;
const P3 = 21 / 16 * _E2 - 55 / 32 * _E4;
const P4 = 151 / 96 * _E3 - 417 / 128 * _E5;
const P5 = 1097 / 512 * _E4;
const R = 6378137;
function toLonLat(easting, northing, zone) {
  const x = easting - 5e5;
  const y = zone.north ? northing : northing - 1e7;
  const m = y / K0;
  const mu = m / (R * M1);
  const pRad = mu + P2 * Math.sin(2 * mu) + P3 * Math.sin(4 * mu) + P4 * Math.sin(6 * mu) + P5 * Math.sin(8 * mu);
  const pSin = Math.sin(pRad);
  const pSin2 = pSin * pSin;
  const pCos = Math.cos(pRad);
  const pTan = pSin / pCos;
  const pTan2 = pTan * pTan;
  const pTan4 = pTan2 * pTan2;
  const epSin = 1 - E * pSin2;
  const epSinSqrt = Math.sqrt(1 - E * pSin2);
  const n = R / epSinSqrt;
  const r = (1 - E) / epSin;
  const c = E_P2 * pCos ** 2;
  const c2 = c * c;
  const d = x / (n * K0);
  const d2 = d * d;
  const d3 = d2 * d;
  const d4 = d3 * d;
  const d5 = d4 * d;
  const d6 = d5 * d;
  const latitude = pRad - pTan / r * (d2 / 2 - d4 / 24 * (5 + 3 * pTan2 + 10 * c - 4 * c2 - 9 * E_P2)) + d6 / 720 * (61 + 90 * pTan2 + 298 * c + 45 * pTan4 - 252 * E_P2 - 3 * c2);
  let longitude = (d - d3 / 6 * (1 + 2 * pTan2 + c) + d5 / 120 * (5 - 2 * c + 28 * pTan2 - 3 * c2 + 8 * E_P2 + 24 * pTan4)) / pCos;
  longitude = wrap(
    longitude + toRadians(zoneToCentralLongitude(zone.number)),
    -Math.PI,
    Math.PI
  );
  return [toDegrees(longitude), toDegrees(latitude)];
}
const MIN_LATITUDE = -80;
const MAX_LATITUDE = 84;
const MIN_LONGITUDE = -180;
const MAX_LONGITUDE = 180;
function fromLonLat(longitude, latitude, zone) {
  longitude = wrap(longitude, MIN_LONGITUDE, MAX_LONGITUDE);
  if (latitude < MIN_LATITUDE) {
    latitude = MIN_LATITUDE;
  } else if (latitude > MAX_LATITUDE) {
    latitude = MAX_LATITUDE;
  }
  const latRad = toRadians(latitude);
  const latSin = Math.sin(latRad);
  const latCos = Math.cos(latRad);
  const latTan = latSin / latCos;
  const latTan2 = latTan * latTan;
  const latTan4 = latTan2 * latTan2;
  const lonRad = toRadians(longitude);
  const centralLon = zoneToCentralLongitude(zone.number);
  const centralLonRad = toRadians(centralLon);
  const n = R / Math.sqrt(1 - E * latSin ** 2);
  const c = E_P2 * latCos ** 2;
  const a3 = latCos * wrap(lonRad - centralLonRad, -Math.PI, Math.PI);
  const a22 = a3 * a3;
  const a32 = a22 * a3;
  const a4 = a32 * a3;
  const a5 = a4 * a3;
  const a6 = a5 * a3;
  const m = R * (M1 * latRad - M2 * Math.sin(2 * latRad) + M3 * Math.sin(4 * latRad) - M4 * Math.sin(6 * latRad));
  const easting = K0 * n * (a3 + a32 / 6 * (1 - latTan2 + c) + a5 / 120 * (5 - 18 * latTan2 + latTan4 + 72 * c - 58 * E_P2)) + 5e5;
  let northing = K0 * (m + n * latTan * (a22 / 2 + a4 / 24 * (5 - latTan2 + 9 * c + 4 * c ** 2) + a6 / 720 * (61 - 58 * latTan2 + latTan4 + 600 * c - 330 * E_P2)));
  if (!zone.north) {
    northing += 1e7;
  }
  return [easting, northing];
}
function zoneToCentralLongitude(zone) {
  return (zone - 1) * 6 - 180 + 3;
}
const epsgRegExes = [
  /^EPSG:(\d+)$/,
  /^urn:ogc:def:crs:EPSG::(\d+)$/,
  /^http:\/\/www\.opengis\.net\/def\/crs\/EPSG\/0\/(\d+)$/
];
function zoneFromCode(code) {
  let epsgId = 0;
  for (const re of epsgRegExes) {
    const match = code.match(re);
    if (match) {
      epsgId = parseInt(match[1]);
      break;
    }
  }
  if (!epsgId) {
    return null;
  }
  let number = 0;
  let north = false;
  if (epsgId > 32700 && epsgId < 32761) {
    number = epsgId - 32700;
  } else if (epsgId > 32600 && epsgId < 32661) {
    north = true;
    number = epsgId - 32600;
  }
  if (!number) {
    return null;
  }
  return { number, north };
}
function makeTransformFunction(transformer, zone) {
  return function(input, output, dimension, stride) {
    const length = input.length;
    dimension = dimension > 1 ? dimension : 2;
    stride = stride != null ? stride : dimension;
    if (!output) {
      if (dimension > 2) {
        output = input.slice();
      } else {
        output = new Array(length);
      }
    }
    for (let i = 0; i < length; i += stride) {
      const x = input[i];
      const y = input[i + 1];
      const coord = transformer(x, y, zone);
      output[i] = coord[0];
      output[i + 1] = coord[1];
    }
    return output;
  };
}
function makeProjection(code) {
  const zone = zoneFromCode(code);
  if (!zone) {
    return null;
  }
  return new Projection$1({ code, units: "m" });
}
function makeTransforms(projection) {
  const zone = zoneFromCode(projection.getCode());
  if (!zone) {
    return null;
  }
  return {
    forward: makeTransformFunction(fromLonLat, zone),
    inverse: makeTransformFunction(toLonLat, zone)
  };
}
const transformFactories = [makeTransforms];
const projectionFactories = [makeProjection];
let showCoordinateWarning = true;
function disableCoordinateWarning(disable2) {
  const hide = disable2 === void 0 ? true : disable2;
  showCoordinateWarning = !hide;
}
function cloneTransform(input, output) {
  if (output !== void 0) {
    for (let i = 0, ii = input.length; i < ii; ++i) {
      output[i] = input[i];
    }
    output = output;
  } else {
    output = input.slice();
  }
  return output;
}
function addProjection(projection) {
  add$1(projection.getCode(), projection);
  add(projection, projection, cloneTransform);
}
function addProjections(projections) {
  projections.forEach(addProjection);
}
function get$1(projectionLike) {
  if (!(typeof projectionLike === "string")) {
    return projectionLike;
  }
  const projection = get$3(projectionLike);
  if (projection) {
    return projection;
  }
  for (const makeProjection2 of projectionFactories) {
    const projection2 = makeProjection2(projectionLike);
    if (projection2) {
      return projection2;
    }
  }
  return null;
}
function addEquivalentProjections(projections) {
  addProjections(projections);
  projections.forEach(function(source) {
    projections.forEach(function(destination) {
      if (source !== destination) {
        add(source, destination, cloneTransform);
      }
    });
  });
}
function addEquivalentTransforms(projections1, projections2, forwardTransform, inverseTransform) {
  projections1.forEach(function(projection1) {
    projections2.forEach(function(projection2) {
      add(projection1, projection2, forwardTransform);
      add(projection2, projection1, inverseTransform);
    });
  });
}
function createProjection(projection, defaultCode) {
  if (!projection) {
    return get$1(defaultCode);
  }
  if (typeof projection === "string") {
    return get$1(projection);
  }
  return projection;
}
function getTransformFromProjections(source, destination) {
  const sourceCode = source.getCode();
  const destinationCode = destination.getCode();
  let transformFunc = get$2(sourceCode, destinationCode);
  if (transformFunc) {
    return transformFunc;
  }
  let sourceTransforms = null;
  let destinationTransforms = null;
  for (const makeTransforms2 of transformFactories) {
    if (!sourceTransforms) {
      sourceTransforms = makeTransforms2(source);
    }
    if (!destinationTransforms) {
      destinationTransforms = makeTransforms2(destination);
    }
  }
  if (!sourceTransforms && !destinationTransforms) {
    return null;
  }
  const intermediateCode = "EPSG:4326";
  if (!destinationTransforms) {
    const toDestination = get$2(intermediateCode, destinationCode);
    if (toDestination) {
      transformFunc = composeTransformFuncs(
        sourceTransforms.inverse,
        toDestination
      );
    }
  } else if (!sourceTransforms) {
    const fromSource = get$2(sourceCode, intermediateCode);
    if (fromSource) {
      transformFunc = composeTransformFuncs(
        fromSource,
        destinationTransforms.forward
      );
    }
  } else {
    transformFunc = composeTransformFuncs(
      sourceTransforms.inverse,
      destinationTransforms.forward
    );
  }
  if (transformFunc) {
    addProjection(source);
    addProjection(destination);
    add(source, destination, transformFunc);
  }
  return transformFunc;
}
function composeTransformFuncs(t1, t2) {
  return function(input, output, dimensions, stride) {
    output = t1(input, output, dimensions, stride);
    return t2(output, output, dimensions, stride);
  };
}
function getTransform(source, destination) {
  const sourceProjection = get$1(source);
  const destinationProjection = get$1(destination);
  return getTransformFromProjections(sourceProjection, destinationProjection);
}
let userProjection = null;
function getUserProjection() {
  return userProjection;
}
function toUserCoordinate(coordinate, sourceProjection) {
  {
    return coordinate;
  }
}
function fromUserCoordinate(coordinate, destProjection) {
  {
    if (showCoordinateWarning && !equals(coordinate, [0, 0]) && coordinate[0] >= -180 && coordinate[0] <= 180 && coordinate[1] >= -90 && coordinate[1] <= 90) {
      showCoordinateWarning = false;
      warn(
        "Call useGeographic() from ol/proj once to work with [longitude, latitude] coordinates."
      );
    }
    return coordinate;
  }
}
function toUserExtent(extent, sourceProjection) {
  {
    return extent;
  }
}
function fromUserExtent(extent, destProjection) {
  {
    return extent;
  }
}
function addCommon() {
  addEquivalentProjections(PROJECTIONS$1);
  addEquivalentProjections(PROJECTIONS);
  addEquivalentTransforms(
    PROJECTIONS,
    PROJECTIONS$1,
    fromEPSG4326,
    toEPSG4326
  );
}
addCommon();
new Array(6);
function create() {
  return [1, 0, 0, 1, 0, 0];
}
function setFromArray(transform1, transform2) {
  transform1[0] = transform2[0];
  transform1[1] = transform2[1];
  transform1[2] = transform2[2];
  transform1[3] = transform2[3];
  transform1[4] = transform2[4];
  transform1[5] = transform2[5];
  return transform1;
}
function apply(transform, coordinate) {
  const x = coordinate[0];
  const y = coordinate[1];
  coordinate[0] = transform[0] * x + transform[2] * y + transform[4];
  coordinate[1] = transform[1] * x + transform[3] * y + transform[5];
  return coordinate;
}
function compose(transform, dx1, dy1, sx, sy, angle, dx2, dy2) {
  const sin = Math.sin(angle);
  const cos = Math.cos(angle);
  transform[0] = sx * cos;
  transform[1] = sy * sin;
  transform[2] = -sx * sin;
  transform[3] = sy * cos;
  transform[4] = dx2 * sx * cos - dy2 * sx * sin + dx1;
  transform[5] = dx2 * sy * sin + dy2 * sy * cos + dy1;
  return transform;
}
function makeInverse(target, source) {
  const det = determinant(source);
  assert(det !== 0, "Transformation matrix cannot be inverted");
  const a3 = source[0];
  const b = source[1];
  const c = source[2];
  const d = source[3];
  const e = source[4];
  const f = source[5];
  target[0] = d / det;
  target[1] = -b / det;
  target[2] = -c / det;
  target[3] = a3 / det;
  target[4] = (c * f - d * e) / det;
  target[5] = -(a3 * f - b * e) / det;
  return target;
}
function determinant(mat) {
  return mat[0] * mat[3] - mat[1] * mat[2];
}
const matrixPrecision = [1e5, 1e5, 1e5, 1e5, 2, 2];
function toString$1(mat) {
  const transformString = "matrix(" + mat.join(", ") + ")";
  return transformString;
}
function fromString$1(cssTransform) {
  const values = cssTransform.substring(7, cssTransform.length - 1).split(",");
  return values.map(parseFloat);
}
function equivalent(cssTransform1, cssTransform2) {
  const mat1 = fromString$1(cssTransform1);
  const mat2 = fromString$1(cssTransform2);
  for (let i = 0; i < 6; ++i) {
    if (Math.round((mat1[i] - mat2[i]) * matrixPrecision[i]) !== 0) {
      return false;
    }
  }
  return true;
}
function transform2D(flatCoordinates, offset, end, stride, transform, dest, destinationStride) {
  dest = dest ? dest : [];
  destinationStride = destinationStride ? destinationStride : 2;
  let i = 0;
  for (let j = offset; j < end; j += stride) {
    const x = flatCoordinates[j];
    const y = flatCoordinates[j + 1];
    dest[i++] = transform[0] * x + transform[2] * y + transform[4];
    dest[i++] = transform[1] * x + transform[3] * y + transform[5];
    for (let k = 2; k < destinationStride; k++) {
      dest[i++] = flatCoordinates[j + k];
    }
  }
  if (dest && dest.length != i) {
    dest.length = i;
  }
  return dest;
}
function rotate(flatCoordinates, offset, end, stride, angle, anchor, dest) {
  dest = dest ? dest : [];
  const cos = Math.cos(angle);
  const sin = Math.sin(angle);
  const anchorX = anchor[0];
  const anchorY = anchor[1];
  let i = 0;
  for (let j = offset; j < end; j += stride) {
    const deltaX = flatCoordinates[j] - anchorX;
    const deltaY = flatCoordinates[j + 1] - anchorY;
    dest[i++] = anchorX + deltaX * cos - deltaY * sin;
    dest[i++] = anchorY + deltaX * sin + deltaY * cos;
    for (let k = j + 2; k < j + stride; ++k) {
      dest[i++] = flatCoordinates[k];
    }
  }
  if (dest && dest.length != i) {
    dest.length = i;
  }
  return dest;
}
function scale(flatCoordinates, offset, end, stride, sx, sy, anchor, dest) {
  dest = dest ? dest : [];
  const anchorX = anchor[0];
  const anchorY = anchor[1];
  let i = 0;
  for (let j = offset; j < end; j += stride) {
    const deltaX = flatCoordinates[j] - anchorX;
    const deltaY = flatCoordinates[j + 1] - anchorY;
    dest[i++] = anchorX + sx * deltaX;
    dest[i++] = anchorY + sy * deltaY;
    for (let k = j + 2; k < j + stride; ++k) {
      dest[i++] = flatCoordinates[k];
    }
  }
  if (dest && dest.length != i) {
    dest.length = i;
  }
  return dest;
}
function translate(flatCoordinates, offset, end, stride, deltaX, deltaY, dest) {
  dest = dest ? dest : [];
  let i = 0;
  for (let j = offset; j < end; j += stride) {
    dest[i++] = flatCoordinates[j] + deltaX;
    dest[i++] = flatCoordinates[j + 1] + deltaY;
    for (let k = j + 2; k < j + stride; ++k) {
      dest[i++] = flatCoordinates[k];
    }
  }
  if (dest && dest.length != i) {
    dest.length = i;
  }
  return dest;
}
const tmpTransform$1 = create();
const tmpPoint = [NaN, NaN];
class Geometry extends BaseObject$1 {
  constructor() {
    super();
    this.extent_ = createEmpty();
    this.extentRevision_ = -1;
    this.simplifiedGeometryMaxMinSquaredTolerance = 0;
    this.simplifiedGeometryRevision = 0;
    this.simplifyTransformedInternal = memoizeOne(
      (revision, squaredTolerance, transform) => {
        if (!transform) {
          return this.getSimplifiedGeometry(squaredTolerance);
        }
        const clone2 = this.clone();
        clone2.applyTransform(transform);
        return clone2.getSimplifiedGeometry(squaredTolerance);
      }
    );
  }
  simplifyTransformed(squaredTolerance, transform) {
    return this.simplifyTransformedInternal(
      this.getRevision(),
      squaredTolerance,
      transform
    );
  }
  clone() {
    return abstract();
  }
  closestPointXY(x, y, closestPoint, minSquaredDistance) {
    return abstract();
  }
  containsXY(x, y) {
    return this.closestPointXY(x, y, tmpPoint, Number.MIN_VALUE) === 0;
  }
  getClosestPoint(point, closestPoint) {
    closestPoint = closestPoint ? closestPoint : [NaN, NaN];
    this.closestPointXY(point[0], point[1], closestPoint, Infinity);
    return closestPoint;
  }
  intersectsCoordinate(coordinate) {
    return this.containsXY(coordinate[0], coordinate[1]);
  }
  computeExtent(extent) {
    return abstract();
  }
  getExtent(extent) {
    if (this.extentRevision_ != this.getRevision()) {
      const extent2 = this.computeExtent(this.extent_);
      if (isNaN(extent2[0]) || isNaN(extent2[1])) {
        createOrUpdateEmpty(extent2);
      }
      this.extentRevision_ = this.getRevision();
    }
    return returnOrUpdate(this.extent_, extent);
  }
  rotate(angle, anchor) {
    abstract();
  }
  scale(sx, sy, anchor) {
    abstract();
  }
  simplify(tolerance) {
    return this.getSimplifiedGeometry(tolerance * tolerance);
  }
  getSimplifiedGeometry(squaredTolerance) {
    return abstract();
  }
  getType() {
    return abstract();
  }
  applyTransform(transformFn) {
    abstract();
  }
  intersectsExtent(extent) {
    return abstract();
  }
  translate(deltaX, deltaY) {
    abstract();
  }
  transform(source, destination) {
    const sourceProj = get$1(source);
    const transformFn = sourceProj.getUnits() == "tile-pixels" ? function(inCoordinates, outCoordinates, stride) {
      const pixelExtent = sourceProj.getExtent();
      const projectedExtent = sourceProj.getWorldExtent();
      const scale2 = getHeight(projectedExtent) / getHeight(pixelExtent);
      compose(
        tmpTransform$1,
        projectedExtent[0],
        projectedExtent[3],
        scale2,
        -scale2,
        0,
        0,
        0
      );
      const transformed = transform2D(
        inCoordinates,
        0,
        inCoordinates.length,
        stride,
        tmpTransform$1,
        outCoordinates
      );
      const projTransform = getTransform(sourceProj, destination);
      if (projTransform) {
        return projTransform(transformed, transformed, stride);
      }
      return transformed;
    } : getTransform(sourceProj, destination);
    this.applyTransform(transformFn);
    return this;
  }
}
const Geometry$1 = Geometry;
class SimpleGeometry extends Geometry$1 {
  constructor() {
    super();
    this.layout = "XY";
    this.stride = 2;
    this.flatCoordinates;
  }
  computeExtent(extent) {
    return createOrUpdateFromFlatCoordinates(
      this.flatCoordinates,
      0,
      this.flatCoordinates.length,
      this.stride,
      extent
    );
  }
  getCoordinates() {
    return abstract();
  }
  getFirstCoordinate() {
    return this.flatCoordinates.slice(0, this.stride);
  }
  getFlatCoordinates() {
    return this.flatCoordinates;
  }
  getLastCoordinate() {
    return this.flatCoordinates.slice(
      this.flatCoordinates.length - this.stride
    );
  }
  getLayout() {
    return this.layout;
  }
  getSimplifiedGeometry(squaredTolerance) {
    if (this.simplifiedGeometryRevision !== this.getRevision()) {
      this.simplifiedGeometryMaxMinSquaredTolerance = 0;
      this.simplifiedGeometryRevision = this.getRevision();
    }
    if (squaredTolerance < 0 || this.simplifiedGeometryMaxMinSquaredTolerance !== 0 && squaredTolerance <= this.simplifiedGeometryMaxMinSquaredTolerance) {
      return this;
    }
    const simplifiedGeometry = this.getSimplifiedGeometryInternal(squaredTolerance);
    const simplifiedFlatCoordinates = simplifiedGeometry.getFlatCoordinates();
    if (simplifiedFlatCoordinates.length < this.flatCoordinates.length) {
      return simplifiedGeometry;
    }
    this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;
    return this;
  }
  getSimplifiedGeometryInternal(squaredTolerance) {
    return this;
  }
  getStride() {
    return this.stride;
  }
  setFlatCoordinates(layout, flatCoordinates) {
    this.stride = getStrideForLayout(layout);
    this.layout = layout;
    this.flatCoordinates = flatCoordinates;
  }
  setCoordinates(coordinates2, layout) {
    abstract();
  }
  setLayout(layout, coordinates2, nesting) {
    let stride;
    if (layout) {
      stride = getStrideForLayout(layout);
    } else {
      for (let i = 0; i < nesting; ++i) {
        if (coordinates2.length === 0) {
          this.layout = "XY";
          this.stride = 2;
          return;
        }
        coordinates2 = coordinates2[0];
      }
      stride = coordinates2.length;
      layout = getLayoutForStride(stride);
    }
    this.layout = layout;
    this.stride = stride;
  }
  applyTransform(transformFn) {
    if (this.flatCoordinates) {
      transformFn(
        this.flatCoordinates,
        this.flatCoordinates,
        this.layout.startsWith("XYZ") ? 3 : 2,
        this.stride
      );
      this.changed();
    }
  }
  rotate(angle, anchor) {
    const flatCoordinates = this.getFlatCoordinates();
    if (flatCoordinates) {
      const stride = this.getStride();
      rotate(
        flatCoordinates,
        0,
        flatCoordinates.length,
        stride,
        angle,
        anchor,
        flatCoordinates
      );
      this.changed();
    }
  }
  scale(sx, sy, anchor) {
    if (sy === void 0) {
      sy = sx;
    }
    if (!anchor) {
      anchor = getCenter(this.getExtent());
    }
    const flatCoordinates = this.getFlatCoordinates();
    if (flatCoordinates) {
      const stride = this.getStride();
      scale(
        flatCoordinates,
        0,
        flatCoordinates.length,
        stride,
        sx,
        sy,
        anchor,
        flatCoordinates
      );
      this.changed();
    }
  }
  translate(deltaX, deltaY) {
    const flatCoordinates = this.getFlatCoordinates();
    if (flatCoordinates) {
      const stride = this.getStride();
      translate(
        flatCoordinates,
        0,
        flatCoordinates.length,
        stride,
        deltaX,
        deltaY,
        flatCoordinates
      );
      this.changed();
    }
  }
}
function getLayoutForStride(stride) {
  let layout;
  if (stride == 2) {
    layout = "XY";
  } else if (stride == 3) {
    layout = "XYZ";
  } else if (stride == 4) {
    layout = "XYZM";
  }
  return layout;
}
function getStrideForLayout(layout) {
  let stride;
  if (layout == "XY") {
    stride = 2;
  } else if (layout == "XYZ" || layout == "XYM") {
    stride = 3;
  } else if (layout == "XYZM") {
    stride = 4;
  }
  return stride;
}
function transformGeom2D(simpleGeometry, transform, dest) {
  const flatCoordinates = simpleGeometry.getFlatCoordinates();
  if (!flatCoordinates) {
    return null;
  }
  const stride = simpleGeometry.getStride();
  return transform2D(
    flatCoordinates,
    0,
    flatCoordinates.length,
    stride,
    transform,
    dest
  );
}
const SimpleGeometry$1 = SimpleGeometry;
function deflateCoordinate(flatCoordinates, offset, coordinate, stride) {
  for (let i = 0, ii = coordinate.length; i < ii; ++i) {
    flatCoordinates[offset++] = coordinate[i];
  }
  return offset;
}
function deflateCoordinates(flatCoordinates, offset, coordinates2, stride) {
  for (let i = 0, ii = coordinates2.length; i < ii; ++i) {
    const coordinate = coordinates2[i];
    for (let j = 0; j < stride; ++j) {
      flatCoordinates[offset++] = coordinate[j];
    }
  }
  return offset;
}
function deflateCoordinatesArray(flatCoordinates, offset, coordinatess, stride, ends) {
  ends = ends ? ends : [];
  let i = 0;
  for (let j = 0, jj = coordinatess.length; j < jj; ++j) {
    const end = deflateCoordinates(
      flatCoordinates,
      offset,
      coordinatess[j],
      stride
    );
    ends[i++] = end;
    offset = end;
  }
  ends.length = i;
  return ends;
}
class Point extends SimpleGeometry$1 {
  constructor(coordinates2, layout) {
    super();
    this.setCoordinates(coordinates2, layout);
  }
  clone() {
    const point = new Point(this.flatCoordinates.slice(), this.layout);
    point.applyProperties(this);
    return point;
  }
  closestPointXY(x, y, closestPoint, minSquaredDistance) {
    const flatCoordinates = this.flatCoordinates;
    const squaredDistance$1 = squaredDistance(
      x,
      y,
      flatCoordinates[0],
      flatCoordinates[1]
    );
    if (squaredDistance$1 < minSquaredDistance) {
      const stride = this.stride;
      for (let i = 0; i < stride; ++i) {
        closestPoint[i] = flatCoordinates[i];
      }
      closestPoint.length = stride;
      return squaredDistance$1;
    }
    return minSquaredDistance;
  }
  getCoordinates() {
    return this.flatCoordinates.slice();
  }
  computeExtent(extent) {
    return createOrUpdateFromCoordinate(this.flatCoordinates, extent);
  }
  getType() {
    return "Point";
  }
  intersectsExtent(extent) {
    return containsXY(extent, this.flatCoordinates[0], this.flatCoordinates[1]);
  }
  setCoordinates(coordinates2, layout) {
    this.setLayout(layout, coordinates2, 0);
    if (!this.flatCoordinates) {
      this.flatCoordinates = [];
    }
    this.flatCoordinates.length = deflateCoordinate(
      this.flatCoordinates,
      0,
      coordinates2,
      this.stride
    );
    this.changed();
  }
}
const Point$1 = Point;
const CollectionEventType = {
  ADD: "add",
  REMOVE: "remove"
};
const Property$1 = {
  LENGTH: "length"
};
class CollectionEvent extends Event {
  constructor(type, element, index2) {
    super(type);
    this.element = element;
    this.index = index2;
  }
}
class Collection extends BaseObject$1 {
  constructor(array, options) {
    super();
    this.on;
    this.once;
    this.un;
    options = options || {};
    this.unique_ = !!options.unique;
    this.array_ = array ? array : [];
    if (this.unique_) {
      for (let i = 0, ii = this.array_.length; i < ii; ++i) {
        this.assertUnique_(this.array_[i], i);
      }
    }
    this.updateLength_();
  }
  clear() {
    while (this.getLength() > 0) {
      this.pop();
    }
  }
  extend(arr) {
    for (let i = 0, ii = arr.length; i < ii; ++i) {
      this.push(arr[i]);
    }
    return this;
  }
  forEach(f) {
    const array = this.array_;
    for (let i = 0, ii = array.length; i < ii; ++i) {
      f(array[i], i, array);
    }
  }
  getArray() {
    return this.array_;
  }
  item(index2) {
    return this.array_[index2];
  }
  getLength() {
    return this.get(Property$1.LENGTH);
  }
  insertAt(index2, elem) {
    if (index2 < 0 || index2 > this.getLength()) {
      throw new Error("Index out of bounds: " + index2);
    }
    if (this.unique_) {
      this.assertUnique_(elem);
    }
    this.array_.splice(index2, 0, elem);
    this.updateLength_();
    this.dispatchEvent(
      new CollectionEvent(CollectionEventType.ADD, elem, index2)
    );
  }
  pop() {
    return this.removeAt(this.getLength() - 1);
  }
  push(elem) {
    if (this.unique_) {
      this.assertUnique_(elem);
    }
    const n = this.getLength();
    this.insertAt(n, elem);
    return this.getLength();
  }
  remove(elem) {
    const arr = this.array_;
    for (let i = 0, ii = arr.length; i < ii; ++i) {
      if (arr[i] === elem) {
        return this.removeAt(i);
      }
    }
    return void 0;
  }
  removeAt(index2) {
    if (index2 < 0 || index2 >= this.getLength()) {
      return void 0;
    }
    const prev = this.array_[index2];
    this.array_.splice(index2, 1);
    this.updateLength_();
    this.dispatchEvent(
      new CollectionEvent(CollectionEventType.REMOVE, prev, index2)
    );
    return prev;
  }
  setAt(index2, elem) {
    const n = this.getLength();
    if (index2 >= n) {
      this.insertAt(index2, elem);
      return;
    }
    if (index2 < 0) {
      throw new Error("Index out of bounds: " + index2);
    }
    if (this.unique_) {
      this.assertUnique_(elem, index2);
    }
    const prev = this.array_[index2];
    this.array_[index2] = elem;
    this.dispatchEvent(
      new CollectionEvent(CollectionEventType.REMOVE, prev, index2)
    );
    this.dispatchEvent(
      new CollectionEvent(CollectionEventType.ADD, elem, index2)
    );
  }
  updateLength_() {
    this.set(Property$1.LENGTH, this.array_.length);
  }
  assertUnique_(elem, except) {
    for (let i = 0, ii = this.array_.length; i < ii; ++i) {
      if (this.array_[i] === elem && i !== except) {
        throw new Error("Duplicate item added to a unique collection");
      }
    }
  }
}
const Collection$1 = Collection;
let withCredentials = false;
function loadFeaturesXhr(url, format, extent, resolution, projection, success, failure) {
  const xhr2 = new XMLHttpRequest();
  xhr2.open(
    "GET",
    typeof url === "function" ? url(extent, resolution, projection) : url,
    true
  );
  if (format.getType() == "arraybuffer") {
    xhr2.responseType = "arraybuffer";
  }
  xhr2.withCredentials = withCredentials;
  xhr2.onload = function(event) {
    if (!xhr2.status || xhr2.status >= 200 && xhr2.status < 300) {
      const type = format.getType();
      try {
        let source;
        if (type == "text" || type == "json") {
          source = xhr2.responseText;
        } else if (type == "xml") {
          source = xhr2.responseXML || xhr2.responseText;
        } else if (type == "arraybuffer") {
          source = xhr2.response;
        }
        if (source) {
          success(
            format.readFeatures(source, {
              extent,
              featureProjection: projection
            }),
            format.readProjection(source)
          );
        } else {
          failure();
        }
      } catch {
        failure();
      }
    } else {
      failure();
    }
  };
  xhr2.onerror = failure;
  xhr2.send();
}
function xhr(url, format) {
  return function(extent, resolution, projection, success, failure) {
    loadFeaturesXhr(
      url,
      format,
      extent,
      resolution,
      projection,
      (features, dataProjection) => {
        this.addFeatures(features);
        if (success !== void 0) {
          success(features);
        }
      },
      () => {
        this.changed();
        if (failure !== void 0) {
          failure();
        }
      }
    );
  };
}
function all(extent, resolution) {
  return [[-Infinity, -Infinity, Infinity, Infinity]];
}
function linearRingss(flatCoordinates, offset, endss, stride) {
  const flatCenters = [];
  let extent = createEmpty();
  for (let i = 0, ii = endss.length; i < ii; ++i) {
    const ends = endss[i];
    extent = createOrUpdateFromFlatCoordinates(
      flatCoordinates,
      offset,
      ends[0],
      stride
    );
    flatCenters.push((extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2);
    offset = ends[ends.length - 1];
  }
  return flatCenters;
}
function linearRingContainsExtent(flatCoordinates, offset, end, stride, extent) {
  const outside = forEachCorner(
    extent,
    function(coordinate) {
      return !linearRingContainsXY(
        flatCoordinates,
        offset,
        end,
        stride,
        coordinate[0],
        coordinate[1]
      );
    }
  );
  return !outside;
}
function linearRingContainsXY(flatCoordinates, offset, end, stride, x, y) {
  let wn = 0;
  let x1 = flatCoordinates[end - stride];
  let y1 = flatCoordinates[end - stride + 1];
  for (; offset < end; offset += stride) {
    const x2 = flatCoordinates[offset];
    const y2 = flatCoordinates[offset + 1];
    if (y1 <= y) {
      if (y2 > y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) > 0) {
        wn++;
      }
    } else if (y2 <= y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) < 0) {
      wn--;
    }
    x1 = x2;
    y1 = y2;
  }
  return wn !== 0;
}
function linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y) {
  if (ends.length === 0) {
    return false;
  }
  if (!linearRingContainsXY(flatCoordinates, offset, ends[0], stride, x, y)) {
    return false;
  }
  for (let i = 1, ii = ends.length; i < ii; ++i) {
    if (linearRingContainsXY(flatCoordinates, ends[i - 1], ends[i], stride, x, y)) {
      return false;
    }
  }
  return true;
}
function getInteriorPointOfArray(flatCoordinates, offset, ends, stride, flatCenters, flatCentersOffset, dest) {
  let i, ii, x, x1, x2, y1, y2;
  const y = flatCenters[flatCentersOffset + 1];
  const intersections = [];
  for (let r = 0, rr = ends.length; r < rr; ++r) {
    const end = ends[r];
    x1 = flatCoordinates[end - stride];
    y1 = flatCoordinates[end - stride + 1];
    for (i = offset; i < end; i += stride) {
      x2 = flatCoordinates[i];
      y2 = flatCoordinates[i + 1];
      if (y <= y1 && y2 <= y || y1 <= y && y <= y2) {
        x = (y - y1) / (y2 - y1) * (x2 - x1) + x1;
        intersections.push(x);
      }
      x1 = x2;
      y1 = y2;
    }
  }
  let pointX = NaN;
  let maxSegmentLength = -Infinity;
  intersections.sort(ascending);
  x1 = intersections[0];
  for (i = 1, ii = intersections.length; i < ii; ++i) {
    x2 = intersections[i];
    const segmentLength = Math.abs(x2 - x1);
    if (segmentLength > maxSegmentLength) {
      x = (x1 + x2) / 2;
      if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {
        pointX = x;
        maxSegmentLength = segmentLength;
      }
    }
    x1 = x2;
  }
  if (isNaN(pointX)) {
    pointX = flatCenters[flatCentersOffset];
  }
  if (dest) {
    dest.push(pointX, y, maxSegmentLength);
    return dest;
  }
  return [pointX, y, maxSegmentLength];
}
function getInteriorPointsOfMultiArray(flatCoordinates, offset, endss, stride, flatCenters) {
  let interiorPoints = [];
  for (let i = 0, ii = endss.length; i < ii; ++i) {
    const ends = endss[i];
    interiorPoints = getInteriorPointOfArray(
      flatCoordinates,
      offset,
      ends,
      stride,
      flatCenters,
      2 * i,
      interiorPoints
    );
    offset = ends[ends.length - 1];
  }
  return interiorPoints;
}
function interpolatePoint(flatCoordinates, offset, end, stride, fraction, dest, dimension) {
  let o, t;
  const n = (end - offset) / stride;
  if (n === 1) {
    o = offset;
  } else if (n === 2) {
    o = offset;
    t = fraction;
  } else if (n !== 0) {
    let x1 = flatCoordinates[offset];
    let y1 = flatCoordinates[offset + 1];
    let length = 0;
    const cumulativeLengths = [0];
    for (let i = offset + stride; i < end; i += stride) {
      const x2 = flatCoordinates[i];
      const y2 = flatCoordinates[i + 1];
      length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
      cumulativeLengths.push(length);
      x1 = x2;
      y1 = y2;
    }
    const target = fraction * length;
    const index2 = binarySearch(cumulativeLengths, target);
    if (index2 < 0) {
      t = (target - cumulativeLengths[-index2 - 2]) / (cumulativeLengths[-index2 - 1] - cumulativeLengths[-index2 - 2]);
      o = offset + (-index2 - 2) * stride;
    } else {
      o = offset + index2 * stride;
    }
  }
  dimension = dimension > 1 ? dimension : 2;
  dest = dest ? dest : new Array(dimension);
  for (let i = 0; i < dimension; ++i) {
    dest[i] = o === void 0 ? NaN : t === void 0 ? flatCoordinates[o + i] : lerp(flatCoordinates[o + i], flatCoordinates[o + stride + i], t);
  }
  return dest;
}
function coordinates(flatCoordinates, offset, end, stride) {
  while (offset < end - stride) {
    for (let i = 0; i < stride; ++i) {
      const tmp = flatCoordinates[offset + i];
      flatCoordinates[offset + i] = flatCoordinates[end - stride + i];
      flatCoordinates[end - stride + i] = tmp;
    }
    offset += stride;
    end -= stride;
  }
}
function linearRingIsClockwise(flatCoordinates, offset, end, stride) {
  let edge = 0;
  let x1 = flatCoordinates[end - stride];
  let y1 = flatCoordinates[end - stride + 1];
  for (; offset < end; offset += stride) {
    const x2 = flatCoordinates[offset];
    const y2 = flatCoordinates[offset + 1];
    edge += (x2 - x1) * (y2 + y1);
    x1 = x2;
    y1 = y2;
  }
  return edge === 0 ? void 0 : edge > 0;
}
function linearRingsAreOriented(flatCoordinates, offset, ends, stride, right) {
  right = right !== void 0 ? right : false;
  for (let i = 0, ii = ends.length; i < ii; ++i) {
    const end = ends[i];
    const isClockwise = linearRingIsClockwise(
      flatCoordinates,
      offset,
      end,
      stride
    );
    if (i === 0) {
      if (right && isClockwise || !right && !isClockwise) {
        return false;
      }
    } else {
      if (right && !isClockwise || !right && isClockwise) {
        return false;
      }
    }
    offset = end;
  }
  return true;
}
function orientLinearRings(flatCoordinates, offset, ends, stride, right) {
  right = right !== void 0 ? right : false;
  for (let i = 0, ii = ends.length; i < ii; ++i) {
    const end = ends[i];
    const isClockwise = linearRingIsClockwise(
      flatCoordinates,
      offset,
      end,
      stride
    );
    const reverse = i === 0 ? right && isClockwise || !right && !isClockwise : right && !isClockwise || !right && isClockwise;
    if (reverse) {
      coordinates(flatCoordinates, offset, end, stride);
    }
    offset = end;
  }
  return offset;
}
function inflateEnds(flatCoordinates, ends) {
  const endss = [];
  let offset = 0;
  let prevEndIndex = 0;
  let startOrientation;
  for (let i = 0, ii = ends.length; i < ii; ++i) {
    const end = ends[i];
    const orientation = linearRingIsClockwise(flatCoordinates, offset, end, 2);
    if (startOrientation === void 0) {
      startOrientation = orientation;
    }
    if (orientation === startOrientation) {
      endss.push(ends.slice(prevEndIndex, i + 1));
    } else {
      if (endss.length === 0) {
        continue;
      }
      endss[endss.length - 1].push(ends[prevEndIndex]);
    }
    prevEndIndex = i + 1;
    offset = end;
  }
  return endss;
}
function douglasPeucker(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset) {
  const n = (end - offset) / stride;
  if (n < 3) {
    for (; offset < end; offset += stride) {
      simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset];
      simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + 1];
    }
    return simplifiedOffset;
  }
  const markers = new Array(n);
  markers[0] = 1;
  markers[n - 1] = 1;
  const stack = [offset, end - stride];
  let index2 = 0;
  while (stack.length > 0) {
    const last = stack.pop();
    const first = stack.pop();
    let maxSquaredDistance = 0;
    const x1 = flatCoordinates[first];
    const y1 = flatCoordinates[first + 1];
    const x2 = flatCoordinates[last];
    const y2 = flatCoordinates[last + 1];
    for (let i = first + stride; i < last; i += stride) {
      const x = flatCoordinates[i];
      const y = flatCoordinates[i + 1];
      const squaredDistance2 = squaredSegmentDistance(x, y, x1, y1, x2, y2);
      if (squaredDistance2 > maxSquaredDistance) {
        index2 = i;
        maxSquaredDistance = squaredDistance2;
      }
    }
    if (maxSquaredDistance > squaredTolerance) {
      markers[(index2 - offset) / stride] = 1;
      if (first + stride < index2) {
        stack.push(first, index2);
      }
      if (index2 + stride < last) {
        stack.push(index2, last);
      }
    }
  }
  for (let i = 0; i < n; ++i) {
    if (markers[i]) {
      simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + i * stride];
      simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + i * stride + 1];
    }
  }
  return simplifiedOffset;
}
function douglasPeuckerArray(flatCoordinates, offset, ends, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds) {
  for (let i = 0, ii = ends.length; i < ii; ++i) {
    const end = ends[i];
    simplifiedOffset = douglasPeucker(
      flatCoordinates,
      offset,
      end,
      stride,
      squaredTolerance,
      simplifiedFlatCoordinates,
      simplifiedOffset
    );
    simplifiedEnds.push(simplifiedOffset);
    offset = end;
  }
  return simplifiedOffset;
}
function snap(value, tolerance) {
  return tolerance * Math.round(value / tolerance);
}
function quantize(flatCoordinates, offset, end, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset) {
  if (offset == end) {
    return simplifiedOffset;
  }
  let x1 = snap(flatCoordinates[offset], tolerance);
  let y1 = snap(flatCoordinates[offset + 1], tolerance);
  offset += stride;
  simplifiedFlatCoordinates[simplifiedOffset++] = x1;
  simplifiedFlatCoordinates[simplifiedOffset++] = y1;
  let x2, y2;
  do {
    x2 = snap(flatCoordinates[offset], tolerance);
    y2 = snap(flatCoordinates[offset + 1], tolerance);
    offset += stride;
    if (offset == end) {
      simplifiedFlatCoordinates[simplifiedOffset++] = x2;
      simplifiedFlatCoordinates[simplifiedOffset++] = y2;
      return simplifiedOffset;
    }
  } while (x2 == x1 && y2 == y1);
  while (offset < end) {
    const x3 = snap(flatCoordinates[offset], tolerance);
    const y3 = snap(flatCoordinates[offset + 1], tolerance);
    offset += stride;
    if (x3 == x2 && y3 == y2) {
      continue;
    }
    const dx1 = x2 - x1;
    const dy1 = y2 - y1;
    const dx2 = x3 - x1;
    const dy2 = y3 - y1;
    if (dx1 * dy2 == dy1 * dx2 && (dx1 < 0 && dx2 < dx1 || dx1 == dx2 || dx1 > 0 && dx2 > dx1) && (dy1 < 0 && dy2 < dy1 || dy1 == dy2 || dy1 > 0 && dy2 > dy1)) {
      x2 = x3;
      y2 = y3;
      continue;
    }
    simplifiedFlatCoordinates[simplifiedOffset++] = x2;
    simplifiedFlatCoordinates[simplifiedOffset++] = y2;
    x1 = x2;
    y1 = y2;
    x2 = x3;
    y2 = y3;
  }
  simplifiedFlatCoordinates[simplifiedOffset++] = x2;
  simplifiedFlatCoordinates[simplifiedOffset++] = y2;
  return simplifiedOffset;
}
function quantizeArray(flatCoordinates, offset, ends, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds) {
  for (let i = 0, ii = ends.length; i < ii; ++i) {
    const end = ends[i];
    simplifiedOffset = quantize(
      flatCoordinates,
      offset,
      end,
      stride,
      tolerance,
      simplifiedFlatCoordinates,
      simplifiedOffset
    );
    simplifiedEnds.push(simplifiedOffset);
    offset = end;
  }
  return simplifiedOffset;
}
function linearRing(flatCoordinates, offset, end, stride) {
  let twiceArea = 0;
  const x0 = flatCoordinates[end - stride];
  const y0 = flatCoordinates[end - stride + 1];
  let dx1 = 0;
  let dy1 = 0;
  for (; offset < end; offset += stride) {
    const dx2 = flatCoordinates[offset] - x0;
    const dy2 = flatCoordinates[offset + 1] - y0;
    twiceArea += dy1 * dx2 - dx1 * dy2;
    dx1 = dx2;
    dy1 = dy2;
  }
  return twiceArea / 2;
}
function linearRings(flatCoordinates, offset, ends, stride) {
  let area = 0;
  for (let i = 0, ii = ends.length; i < ii; ++i) {
    const end = ends[i];
    area += linearRing(flatCoordinates, offset, end, stride);
    offset = end;
  }
  return area;
}
function assignClosest(flatCoordinates, offset1, offset2, stride, x, y, closestPoint) {
  const x1 = flatCoordinates[offset1];
  const y1 = flatCoordinates[offset1 + 1];
  const dx = flatCoordinates[offset2] - x1;
  const dy = flatCoordinates[offset2 + 1] - y1;
  let offset;
  if (dx === 0 && dy === 0) {
    offset = offset1;
  } else {
    const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
    if (t > 1) {
      offset = offset2;
    } else if (t > 0) {
      for (let i = 0; i < stride; ++i) {
        closestPoint[i] = lerp(
          flatCoordinates[offset1 + i],
          flatCoordinates[offset2 + i],
          t
        );
      }
      closestPoint.length = stride;
      return;
    } else {
      offset = offset1;
    }
  }
  for (let i = 0; i < stride; ++i) {
    closestPoint[i] = flatCoordinates[offset + i];
  }
  closestPoint.length = stride;
}
function maxSquaredDelta(flatCoordinates, offset, end, stride, max) {
  let x1 = flatCoordinates[offset];
  let y1 = flatCoordinates[offset + 1];
  for (offset += stride; offset < end; offset += stride) {
    const x2 = flatCoordinates[offset];
    const y2 = flatCoordinates[offset + 1];
    const squaredDelta = squaredDistance(x1, y1, x2, y2);
    if (squaredDelta > max) {
      max = squaredDelta;
    }
    x1 = x2;
    y1 = y2;
  }
  return max;
}
function arrayMaxSquaredDelta(flatCoordinates, offset, ends, stride, max) {
  for (let i = 0, ii = ends.length; i < ii; ++i) {
    const end = ends[i];
    max = maxSquaredDelta(flatCoordinates, offset, end, stride, max);
    offset = end;
  }
  return max;
}
function assignClosestPoint(flatCoordinates, offset, end, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint2) {
  if (offset == end) {
    return minSquaredDistance;
  }
  let i, squaredDistance$1;
  if (maxDelta === 0) {
    squaredDistance$1 = squaredDistance(
      x,
      y,
      flatCoordinates[offset],
      flatCoordinates[offset + 1]
    );
    if (squaredDistance$1 < minSquaredDistance) {
      for (i = 0; i < stride; ++i) {
        closestPoint[i] = flatCoordinates[offset + i];
      }
      closestPoint.length = stride;
      return squaredDistance$1;
    }
    return minSquaredDistance;
  }
  tmpPoint2 = tmpPoint2 ? tmpPoint2 : [NaN, NaN];
  let index2 = offset + stride;
  while (index2 < end) {
    assignClosest(
      flatCoordinates,
      index2 - stride,
      index2,
      stride,
      x,
      y,
      tmpPoint2
    );
    squaredDistance$1 = squaredDistance(x, y, tmpPoint2[0], tmpPoint2[1]);
    if (squaredDistance$1 < minSquaredDistance) {
      minSquaredDistance = squaredDistance$1;
      for (i = 0; i < stride; ++i) {
        closestPoint[i] = tmpPoint2[i];
      }
      closestPoint.length = stride;
      index2 += stride;
    } else {
      index2 += stride * Math.max(
        (Math.sqrt(squaredDistance$1) - Math.sqrt(minSquaredDistance)) / maxDelta | 0,
        1
      );
    }
  }
  if (isRing) {
    assignClosest(
      flatCoordinates,
      end - stride,
      offset,
      stride,
      x,
      y,
      tmpPoint2
    );
    squaredDistance$1 = squaredDistance(x, y, tmpPoint2[0], tmpPoint2[1]);
    if (squaredDistance$1 < minSquaredDistance) {
      minSquaredDistance = squaredDistance$1;
      for (i = 0; i < stride; ++i) {
        closestPoint[i] = tmpPoint2[i];
      }
      closestPoint.length = stride;
    }
  }
  return minSquaredDistance;
}
function assignClosestArrayPoint(flatCoordinates, offset, ends, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint2) {
  tmpPoint2 = tmpPoint2 ? tmpPoint2 : [NaN, NaN];
  for (let i = 0, ii = ends.length; i < ii; ++i) {
    const end = ends[i];
    minSquaredDistance = assignClosestPoint(
      flatCoordinates,
      offset,
      end,
      stride,
      maxDelta,
      isRing,
      x,
      y,
      closestPoint,
      minSquaredDistance,
      tmpPoint2
    );
    offset = end;
  }
  return minSquaredDistance;
}
function inflateCoordinates(flatCoordinates, offset, end, stride, coordinates2) {
  coordinates2 = coordinates2 !== void 0 ? coordinates2 : [];
  let i = 0;
  for (let j = offset; j < end; j += stride) {
    coordinates2[i++] = flatCoordinates.slice(j, j + stride);
  }
  coordinates2.length = i;
  return coordinates2;
}
function inflateCoordinatesArray(flatCoordinates, offset, ends, stride, coordinatess) {
  coordinatess = coordinatess !== void 0 ? coordinatess : [];
  let i = 0;
  for (let j = 0, jj = ends.length; j < jj; ++j) {
    const end = ends[j];
    coordinatess[i++] = inflateCoordinates(
      flatCoordinates,
      offset,
      end,
      stride,
      coordinatess[i]
    );
    offset = end;
  }
  coordinatess.length = i;
  return coordinatess;
}
function inflateMultiCoordinatesArray(flatCoordinates, offset, endss, stride, coordinatesss) {
  coordinatesss = coordinatesss !== void 0 ? coordinatesss : [];
  let i = 0;
  for (let j = 0, jj = endss.length; j < jj; ++j) {
    const ends = endss[j];
    coordinatesss[i++] = ends.length === 1 && ends[0] === offset ? [] : inflateCoordinatesArray(
      flatCoordinates,
      offset,
      ends,
      stride,
      coordinatesss[i]
    );
    offset = ends[ends.length - 1];
  }
  coordinatesss.length = i;
  return coordinatesss;
}
class LinearRing extends SimpleGeometry$1 {
  constructor(coordinates2, layout) {
    super();
    this.maxDelta_ = -1;
    this.maxDeltaRevision_ = -1;
    if (layout !== void 0 && !Array.isArray(coordinates2[0])) {
      this.setFlatCoordinates(
        layout,
        coordinates2
      );
    } else {
      this.setCoordinates(
        coordinates2,
        layout
      );
    }
  }
  clone() {
    return new LinearRing(this.flatCoordinates.slice(), this.layout);
  }
  closestPointXY(x, y, closestPoint, minSquaredDistance) {
    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
      return minSquaredDistance;
    }
    if (this.maxDeltaRevision_ != this.getRevision()) {
      this.maxDelta_ = Math.sqrt(
        maxSquaredDelta(
          this.flatCoordinates,
          0,
          this.flatCoordinates.length,
          this.stride,
          0
        )
      );
      this.maxDeltaRevision_ = this.getRevision();
    }
    return assignClosestPoint(
      this.flatCoordinates,
      0,
      this.flatCoordinates.length,
      this.stride,
      this.maxDelta_,
      true,
      x,
      y,
      closestPoint,
      minSquaredDistance
    );
  }
  getArea() {
    return linearRing(
      this.flatCoordinates,
      0,
      this.flatCoordinates.length,
      this.stride
    );
  }
  getCoordinates() {
    return inflateCoordinates(
      this.flatCoordinates,
      0,
      this.flatCoordinates.length,
      this.stride
    );
  }
  getSimplifiedGeometryInternal(squaredTolerance) {
    const simplifiedFlatCoordinates = [];
    simplifiedFlatCoordinates.length = douglasPeucker(
      this.flatCoordinates,
      0,
      this.flatCoordinates.length,
      this.stride,
      squaredTolerance,
      simplifiedFlatCoordinates,
      0
    );
    return new LinearRing(simplifiedFlatCoordinates, "XY");
  }
  getType() {
    return "LinearRing";
  }
  intersectsExtent(extent) {
    return false;
  }
  setCoordinates(coordinates2, layout) {
    this.setLayout(layout, coordinates2, 1);
    if (!this.flatCoordinates) {
      this.flatCoordinates = [];
    }
    this.flatCoordinates.length = deflateCoordinates(
      this.flatCoordinates,
      0,
      coordinates2,
      this.stride
    );
    this.changed();
  }
}
const LinearRing$1 = LinearRing;
function forEach(flatCoordinates, offset, end, stride, callback) {
  let ret;
  offset += stride;
  for (; offset < end; offset += stride) {
    ret = callback(
      flatCoordinates.slice(offset - stride, offset),
      flatCoordinates.slice(offset, offset + stride)
    );
    if (ret) {
      return ret;
    }
  }
  return false;
}
function intersectsLineString(flatCoordinates, offset, end, stride, extent, coordinatesExtent) {
  coordinatesExtent = coordinatesExtent != null ? coordinatesExtent : extendFlatCoordinates(createEmpty(), flatCoordinates, offset, end, stride);
  if (!intersects$1(extent, coordinatesExtent)) {
    return false;
  }
  if (coordinatesExtent[0] >= extent[0] && coordinatesExtent[2] <= extent[2] || coordinatesExtent[1] >= extent[1] && coordinatesExtent[3] <= extent[3]) {
    return true;
  }
  return forEach(
    flatCoordinates,
    offset,
    end,
    stride,
    function(point1, point2) {
      return intersectsSegment(extent, point1, point2);
    }
  );
}
function intersectsLinearRing(flatCoordinates, offset, end, stride, extent) {
  if (intersectsLineString(flatCoordinates, offset, end, stride, extent)) {
    return true;
  }
  if (linearRingContainsXY(
    flatCoordinates,
    offset,
    end,
    stride,
    extent[0],
    extent[1]
  )) {
    return true;
  }
  if (linearRingContainsXY(
    flatCoordinates,
    offset,
    end,
    stride,
    extent[0],
    extent[3]
  )) {
    return true;
  }
  if (linearRingContainsXY(
    flatCoordinates,
    offset,
    end,
    stride,
    extent[2],
    extent[1]
  )) {
    return true;
  }
  if (linearRingContainsXY(
    flatCoordinates,
    offset,
    end,
    stride,
    extent[2],
    extent[3]
  )) {
    return true;
  }
  return false;
}
function intersectsLinearRingArray(flatCoordinates, offset, ends, stride, extent) {
  if (!intersectsLinearRing(flatCoordinates, offset, ends[0], stride, extent)) {
    return false;
  }
  if (ends.length === 1) {
    return true;
  }
  for (let i = 1, ii = ends.length; i < ii; ++i) {
    if (linearRingContainsExtent(
      flatCoordinates,
      ends[i - 1],
      ends[i],
      stride,
      extent
    )) {
      if (!intersectsLineString(
        flatCoordinates,
        ends[i - 1],
        ends[i],
        stride,
        extent
      )) {
        return false;
      }
    }
  }
  return true;
}
function lineStringLength(flatCoordinates, offset, end, stride) {
  let x1 = flatCoordinates[offset];
  let y1 = flatCoordinates[offset + 1];
  let length = 0;
  for (let i = offset + stride; i < end; i += stride) {
    const x2 = flatCoordinates[i];
    const y2 = flatCoordinates[i + 1];
    length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
    x1 = x2;
    y1 = y2;
  }
  return length;
}
class Polygon extends SimpleGeometry$1 {
  constructor(coordinates2, layout, ends) {
    super();
    this.ends_ = [];
    this.flatInteriorPointRevision_ = -1;
    this.flatInteriorPoint_ = null;
    this.maxDelta_ = -1;
    this.maxDeltaRevision_ = -1;
    this.orientedRevision_ = -1;
    this.orientedFlatCoordinates_ = null;
    if (layout !== void 0 && ends) {
      this.setFlatCoordinates(
        layout,
        coordinates2
      );
      this.ends_ = ends;
    } else {
      this.setCoordinates(
        coordinates2,
        layout
      );
    }
  }
  appendLinearRing(linearRing2) {
    if (!this.flatCoordinates) {
      this.flatCoordinates = linearRing2.getFlatCoordinates().slice();
    } else {
      extend$2(this.flatCoordinates, linearRing2.getFlatCoordinates());
    }
    this.ends_.push(this.flatCoordinates.length);
    this.changed();
  }
  clone() {
    const polygon = new Polygon(
      this.flatCoordinates.slice(),
      this.layout,
      this.ends_.slice()
    );
    polygon.applyProperties(this);
    return polygon;
  }
  closestPointXY(x, y, closestPoint, minSquaredDistance) {
    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
      return minSquaredDistance;
    }
    if (this.maxDeltaRevision_ != this.getRevision()) {
      this.maxDelta_ = Math.sqrt(
        arrayMaxSquaredDelta(
          this.flatCoordinates,
          0,
          this.ends_,
          this.stride,
          0
        )
      );
      this.maxDeltaRevision_ = this.getRevision();
    }
    return assignClosestArrayPoint(
      this.flatCoordinates,
      0,
      this.ends_,
      this.stride,
      this.maxDelta_,
      true,
      x,
      y,
      closestPoint,
      minSquaredDistance
    );
  }
  containsXY(x, y) {
    return linearRingsContainsXY(
      this.getOrientedFlatCoordinates(),
      0,
      this.ends_,
      this.stride,
      x,
      y
    );
  }
  getArea() {
    return linearRings(
      this.getOrientedFlatCoordinates(),
      0,
      this.ends_,
      this.stride
    );
  }
  getCoordinates(right) {
    let flatCoordinates;
    if (right !== void 0) {
      flatCoordinates = this.getOrientedFlatCoordinates().slice();
      orientLinearRings(flatCoordinates, 0, this.ends_, this.stride, right);
    } else {
      flatCoordinates = this.flatCoordinates;
    }
    return inflateCoordinatesArray(flatCoordinates, 0, this.ends_, this.stride);
  }
  getEnds() {
    return this.ends_;
  }
  getFlatInteriorPoint() {
    if (this.flatInteriorPointRevision_ != this.getRevision()) {
      const flatCenter = getCenter(this.getExtent());
      this.flatInteriorPoint_ = getInteriorPointOfArray(
        this.getOrientedFlatCoordinates(),
        0,
        this.ends_,
        this.stride,
        flatCenter,
        0
      );
      this.flatInteriorPointRevision_ = this.getRevision();
    }
    return this.flatInteriorPoint_;
  }
  getInteriorPoint() {
    return new Point$1(this.getFlatInteriorPoint(), "XYM");
  }
  getLinearRingCount() {
    return this.ends_.length;
  }
  getLinearRing(index2) {
    if (index2 < 0 || this.ends_.length <= index2) {
      return null;
    }
    return new LinearRing$1(
      this.flatCoordinates.slice(
        index2 === 0 ? 0 : this.ends_[index2 - 1],
        this.ends_[index2]
      ),
      this.layout
    );
  }
  getLinearRings() {
    const layout = this.layout;
    const flatCoordinates = this.flatCoordinates;
    const ends = this.ends_;
    const linearRings2 = [];
    let offset = 0;
    for (let i = 0, ii = ends.length; i < ii; ++i) {
      const end = ends[i];
      const linearRing2 = new LinearRing$1(
        flatCoordinates.slice(offset, end),
        layout
      );
      linearRings2.push(linearRing2);
      offset = end;
    }
    return linearRings2;
  }
  getOrientedFlatCoordinates() {
    if (this.orientedRevision_ != this.getRevision()) {
      const flatCoordinates = this.flatCoordinates;
      if (linearRingsAreOriented(flatCoordinates, 0, this.ends_, this.stride)) {
        this.orientedFlatCoordinates_ = flatCoordinates;
      } else {
        this.orientedFlatCoordinates_ = flatCoordinates.slice();
        this.orientedFlatCoordinates_.length = orientLinearRings(
          this.orientedFlatCoordinates_,
          0,
          this.ends_,
          this.stride
        );
      }
      this.orientedRevision_ = this.getRevision();
    }
    return this.orientedFlatCoordinates_;
  }
  getSimplifiedGeometryInternal(squaredTolerance) {
    const simplifiedFlatCoordinates = [];
    const simplifiedEnds = [];
    simplifiedFlatCoordinates.length = quantizeArray(
      this.flatCoordinates,
      0,
      this.ends_,
      this.stride,
      Math.sqrt(squaredTolerance),
      simplifiedFlatCoordinates,
      0,
      simplifiedEnds
    );
    return new Polygon(simplifiedFlatCoordinates, "XY", simplifiedEnds);
  }
  getType() {
    return "Polygon";
  }
  intersectsExtent(extent) {
    return intersectsLinearRingArray(
      this.getOrientedFlatCoordinates(),
      0,
      this.ends_,
      this.stride,
      extent
    );
  }
  setCoordinates(coordinates2, layout) {
    this.setLayout(layout, coordinates2, 2);
    if (!this.flatCoordinates) {
      this.flatCoordinates = [];
    }
    const ends = deflateCoordinatesArray(
      this.flatCoordinates,
      0,
      coordinates2,
      this.stride,
      this.ends_
    );
    this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];
    this.changed();
  }
}
function fromExtent(extent) {
  if (isEmpty(extent)) {
    throw new Error("Cannot create polygon from empty extent");
  }
  const minX = extent[0];
  const minY = extent[1];
  const maxX = extent[2];
  const maxY = extent[3];
  const flatCoordinates = [
    minX,
    minY,
    minX,
    maxY,
    maxX,
    maxY,
    maxX,
    minY,
    minX,
    minY
  ];
  return new Polygon(flatCoordinates, "XY", [flatCoordinates.length]);
}
const tmpTransform = create();
class RenderFeature {
  constructor(type, flatCoordinates, ends, stride, properties, id) {
    this.styleFunction;
    this.extent_;
    this.id_ = id;
    this.type_ = type;
    this.flatCoordinates_ = flatCoordinates;
    this.flatInteriorPoints_ = null;
    this.flatMidpoints_ = null;
    this.ends_ = ends || null;
    this.properties_ = properties;
    this.squaredTolerance_;
    this.stride_ = stride;
    this.simplifiedGeometry_;
  }
  get(key) {
    return this.properties_[key];
  }
  getExtent() {
    if (!this.extent_) {
      this.extent_ = this.type_ === "Point" ? createOrUpdateFromCoordinate(this.flatCoordinates_) : createOrUpdateFromFlatCoordinates(
        this.flatCoordinates_,
        0,
        this.flatCoordinates_.length,
        2
      );
    }
    return this.extent_;
  }
  getFlatInteriorPoint() {
    if (!this.flatInteriorPoints_) {
      const flatCenter = getCenter(this.getExtent());
      this.flatInteriorPoints_ = getInteriorPointOfArray(
        this.flatCoordinates_,
        0,
        this.ends_,
        2,
        flatCenter,
        0
      );
    }
    return this.flatInteriorPoints_;
  }
  getFlatInteriorPoints() {
    if (!this.flatInteriorPoints_) {
      const ends = inflateEnds(this.flatCoordinates_, this.ends_);
      const flatCenters = linearRingss(this.flatCoordinates_, 0, ends, 2);
      this.flatInteriorPoints_ = getInteriorPointsOfMultiArray(
        this.flatCoordinates_,
        0,
        ends,
        2,
        flatCenters
      );
    }
    return this.flatInteriorPoints_;
  }
  getFlatMidpoint() {
    if (!this.flatMidpoints_) {
      this.flatMidpoints_ = interpolatePoint(
        this.flatCoordinates_,
        0,
        this.flatCoordinates_.length,
        2,
        0.5
      );
    }
    return this.flatMidpoints_;
  }
  getFlatMidpoints() {
    if (!this.flatMidpoints_) {
      this.flatMidpoints_ = [];
      const flatCoordinates = this.flatCoordinates_;
      let offset = 0;
      const ends = this.ends_;
      for (let i = 0, ii = ends.length; i < ii; ++i) {
        const end = ends[i];
        const midpoint = interpolatePoint(flatCoordinates, offset, end, 2, 0.5);
        extend$2(this.flatMidpoints_, midpoint);
        offset = end;
      }
    }
    return this.flatMidpoints_;
  }
  getId() {
    return this.id_;
  }
  getOrientedFlatCoordinates() {
    return this.flatCoordinates_;
  }
  getGeometry() {
    return this;
  }
  getSimplifiedGeometry(squaredTolerance) {
    return this;
  }
  simplifyTransformed(squaredTolerance, transform) {
    return this;
  }
  getProperties() {
    return this.properties_;
  }
  getPropertiesInternal() {
    return this.properties_;
  }
  getStride() {
    return this.stride_;
  }
  getStyleFunction() {
    return this.styleFunction;
  }
  getType() {
    return this.type_;
  }
  transform(projection) {
    projection = get$1(projection);
    const pixelExtent = projection.getExtent();
    const projectedExtent = projection.getWorldExtent();
    if (pixelExtent && projectedExtent) {
      const scale2 = getHeight(projectedExtent) / getHeight(pixelExtent);
      compose(
        tmpTransform,
        projectedExtent[0],
        projectedExtent[3],
        scale2,
        -scale2,
        0,
        0,
        0
      );
      transform2D(
        this.flatCoordinates_,
        0,
        this.flatCoordinates_.length,
        2,
        tmpTransform,
        this.flatCoordinates_
      );
    }
  }
  applyTransform(transformFn) {
    transformFn(this.flatCoordinates_, this.flatCoordinates_, this.stride_);
  }
  clone() {
    var _a;
    return new RenderFeature(
      this.type_,
      this.flatCoordinates_.slice(),
      (_a = this.ends_) == null ? void 0 : _a.slice(),
      this.stride_,
      Object.assign({}, this.properties_),
      this.id_
    );
  }
  getEnds() {
    return this.ends_;
  }
  enableSimplifyTransformed() {
    this.simplifyTransformed = memoizeOne((squaredTolerance, transform) => {
      if (squaredTolerance === this.squaredTolerance_) {
        return this.simplifiedGeometry_;
      }
      this.simplifiedGeometry_ = this.clone();
      if (transform) {
        this.simplifiedGeometry_.applyTransform(transform);
      }
      const simplifiedFlatCoordinates = this.simplifiedGeometry_.getFlatCoordinates();
      let simplifiedEnds;
      switch (this.type_) {
        case "LineString":
          simplifiedFlatCoordinates.length = douglasPeucker(
            simplifiedFlatCoordinates,
            0,
            this.simplifiedGeometry_.flatCoordinates_.length,
            this.simplifiedGeometry_.stride_,
            squaredTolerance,
            simplifiedFlatCoordinates,
            0
          );
          simplifiedEnds = [simplifiedFlatCoordinates.length];
          break;
        case "MultiLineString":
          simplifiedEnds = [];
          simplifiedFlatCoordinates.length = douglasPeuckerArray(
            simplifiedFlatCoordinates,
            0,
            this.simplifiedGeometry_.ends_,
            this.simplifiedGeometry_.stride_,
            squaredTolerance,
            simplifiedFlatCoordinates,
            0,
            simplifiedEnds
          );
          break;
        case "Polygon":
          simplifiedEnds = [];
          simplifiedFlatCoordinates.length = quantizeArray(
            simplifiedFlatCoordinates,
            0,
            this.simplifiedGeometry_.ends_,
            this.simplifiedGeometry_.stride_,
            Math.sqrt(squaredTolerance),
            simplifiedFlatCoordinates,
            0,
            simplifiedEnds
          );
          break;
      }
      if (simplifiedEnds) {
        this.simplifiedGeometry_ = new RenderFeature(
          this.type_,
          simplifiedFlatCoordinates,
          simplifiedEnds,
          2,
          this.properties_,
          this.id_
        );
      }
      this.squaredTolerance_ = squaredTolerance;
      return this.simplifiedGeometry_;
    });
    return this;
  }
}
RenderFeature.prototype.getFlatCoordinates = RenderFeature.prototype.getOrientedFlatCoordinates;
const RenderFeature$1 = RenderFeature;
function quickselect(arr, k, left = 0, right = arr.length - 1, compare = defaultCompare) {
  while (right > left) {
    if (right - left > 600) {
      const n = right - left + 1;
      const m = k - left + 1;
      const z = Math.log(n);
      const s = 0.5 * Math.exp(2 * z / 3);
      const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
      const newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
      const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
      quickselect(arr, k, newLeft, newRight, compare);
    }
    const t = arr[k];
    let i = left;
    let j = right;
    swap(arr, left, k);
    if (compare(arr[right], t) > 0)
      swap(arr, left, right);
    while (i < j) {
      swap(arr, i, j);
      i++;
      j--;
      while (compare(arr[i], t) < 0)
        i++;
      while (compare(arr[j], t) > 0)
        j--;
    }
    if (compare(arr[left], t) === 0)
      swap(arr, left, j);
    else {
      j++;
      swap(arr, j, right);
    }
    if (j <= k)
      left = j + 1;
    if (k <= j)
      right = j - 1;
  }
}
function swap(arr, i, j) {
  const tmp = arr[i];
  arr[i] = arr[j];
  arr[j] = tmp;
}
function defaultCompare(a3, b) {
  return a3 < b ? -1 : a3 > b ? 1 : 0;
}
class RBush$2 {
  constructor(maxEntries = 9) {
    this._maxEntries = Math.max(4, maxEntries);
    this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
    this.clear();
  }
  all() {
    return this._all(this.data, []);
  }
  search(bbox) {
    let node = this.data;
    const result = [];
    if (!intersects(bbox, node))
      return result;
    const toBBox = this.toBBox;
    const nodesToSearch = [];
    while (node) {
      for (let i = 0; i < node.children.length; i++) {
        const child = node.children[i];
        const childBBox = node.leaf ? toBBox(child) : child;
        if (intersects(bbox, childBBox)) {
          if (node.leaf)
            result.push(child);
          else if (contains(bbox, childBBox))
            this._all(child, result);
          else
            nodesToSearch.push(child);
        }
      }
      node = nodesToSearch.pop();
    }
    return result;
  }
  collides(bbox) {
    let node = this.data;
    if (!intersects(bbox, node))
      return false;
    const nodesToSearch = [];
    while (node) {
      for (let i = 0; i < node.children.length; i++) {
        const child = node.children[i];
        const childBBox = node.leaf ? this.toBBox(child) : child;
        if (intersects(bbox, childBBox)) {
          if (node.leaf || contains(bbox, childBBox))
            return true;
          nodesToSearch.push(child);
        }
      }
      node = nodesToSearch.pop();
    }
    return false;
  }
  load(data) {
    if (!(data && data.length))
      return this;
    if (data.length < this._minEntries) {
      for (let i = 0; i < data.length; i++) {
        this.insert(data[i]);
      }
      return this;
    }
    let node = this._build(data.slice(), 0, data.length - 1, 0);
    if (!this.data.children.length) {
      this.data = node;
    } else if (this.data.height === node.height) {
      this._splitRoot(this.data, node);
    } else {
      if (this.data.height < node.height) {
        const tmpNode = this.data;
        this.data = node;
        node = tmpNode;
      }
      this._insert(node, this.data.height - node.height - 1, true);
    }
    return this;
  }
  insert(item) {
    if (item)
      this._insert(item, this.data.height - 1);
    return this;
  }
  clear() {
    this.data = createNode([]);
    return this;
  }
  remove(item, equalsFn) {
    if (!item)
      return this;
    let node = this.data;
    const bbox = this.toBBox(item);
    const path = [];
    const indexes = [];
    let i, parent, goingUp;
    while (node || path.length) {
      if (!node) {
        node = path.pop();
        parent = path[path.length - 1];
        i = indexes.pop();
        goingUp = true;
      }
      if (node.leaf) {
        const index2 = findItem(item, node.children, equalsFn);
        if (index2 !== -1) {
          node.children.splice(index2, 1);
          path.push(node);
          this._condense(path);
          return this;
        }
      }
      if (!goingUp && !node.leaf && contains(node, bbox)) {
        path.push(node);
        indexes.push(i);
        i = 0;
        parent = node;
        node = node.children[0];
      } else if (parent) {
        i++;
        node = parent.children[i];
        goingUp = false;
      } else
        node = null;
    }
    return this;
  }
  toBBox(item) {
    return item;
  }
  compareMinX(a3, b) {
    return a3.minX - b.minX;
  }
  compareMinY(a3, b) {
    return a3.minY - b.minY;
  }
  toJSON() {
    return this.data;
  }
  fromJSON(data) {
    this.data = data;
    return this;
  }
  _all(node, result) {
    const nodesToSearch = [];
    while (node) {
      if (node.leaf)
        result.push(...node.children);
      else
        nodesToSearch.push(...node.children);
      node = nodesToSearch.pop();
    }
    return result;
  }
  _build(items, left, right, height) {
    const N = right - left + 1;
    let M = this._maxEntries;
    let node;
    if (N <= M) {
      node = createNode(items.slice(left, right + 1));
      calcBBox(node, this.toBBox);
      return node;
    }
    if (!height) {
      height = Math.ceil(Math.log(N) / Math.log(M));
      M = Math.ceil(N / Math.pow(M, height - 1));
    }
    node = createNode([]);
    node.leaf = false;
    node.height = height;
    const N2 = Math.ceil(N / M);
    const N1 = N2 * Math.ceil(Math.sqrt(M));
    multiSelect(items, left, right, N1, this.compareMinX);
    for (let i = left; i <= right; i += N1) {
      const right2 = Math.min(i + N1 - 1, right);
      multiSelect(items, i, right2, N2, this.compareMinY);
      for (let j = i; j <= right2; j += N2) {
        const right3 = Math.min(j + N2 - 1, right2);
        node.children.push(this._build(items, j, right3, height - 1));
      }
    }
    calcBBox(node, this.toBBox);
    return node;
  }
  _chooseSubtree(bbox, node, level2, path) {
    while (true) {
      path.push(node);
      if (node.leaf || path.length - 1 === level2)
        break;
      let minArea = Infinity;
      let minEnlargement = Infinity;
      let targetNode;
      for (let i = 0; i < node.children.length; i++) {
        const child = node.children[i];
        const area = bboxArea(child);
        const enlargement = enlargedArea(bbox, child) - area;
        if (enlargement < minEnlargement) {
          minEnlargement = enlargement;
          minArea = area < minArea ? area : minArea;
          targetNode = child;
        } else if (enlargement === minEnlargement) {
          if (area < minArea) {
            minArea = area;
            targetNode = child;
          }
        }
      }
      node = targetNode || node.children[0];
    }
    return node;
  }
  _insert(item, level2, isNode) {
    const bbox = isNode ? item : this.toBBox(item);
    const insertPath = [];
    const node = this._chooseSubtree(bbox, this.data, level2, insertPath);
    node.children.push(item);
    extend(node, bbox);
    while (level2 >= 0) {
      if (insertPath[level2].children.length > this._maxEntries) {
        this._split(insertPath, level2);
        level2--;
      } else
        break;
    }
    this._adjustParentBBoxes(bbox, insertPath, level2);
  }
  _split(insertPath, level2) {
    const node = insertPath[level2];
    const M = node.children.length;
    const m = this._minEntries;
    this._chooseSplitAxis(node, m, M);
    const splitIndex = this._chooseSplitIndex(node, m, M);
    const newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
    newNode.height = node.height;
    newNode.leaf = node.leaf;
    calcBBox(node, this.toBBox);
    calcBBox(newNode, this.toBBox);
    if (level2)
      insertPath[level2 - 1].children.push(newNode);
    else
      this._splitRoot(node, newNode);
  }
  _splitRoot(node, newNode) {
    this.data = createNode([node, newNode]);
    this.data.height = node.height + 1;
    this.data.leaf = false;
    calcBBox(this.data, this.toBBox);
  }
  _chooseSplitIndex(node, m, M) {
    let index2;
    let minOverlap = Infinity;
    let minArea = Infinity;
    for (let i = m; i <= M - m; i++) {
      const bbox1 = distBBox(node, 0, i, this.toBBox);
      const bbox2 = distBBox(node, i, M, this.toBBox);
      const overlap = intersectionArea(bbox1, bbox2);
      const area = bboxArea(bbox1) + bboxArea(bbox2);
      if (overlap < minOverlap) {
        minOverlap = overlap;
        index2 = i;
        minArea = area < minArea ? area : minArea;
      } else if (overlap === minOverlap) {
        if (area < minArea) {
          minArea = area;
          index2 = i;
        }
      }
    }
    return index2 || M - m;
  }
  _chooseSplitAxis(node, m, M) {
    const compareMinX = node.leaf ? this.compareMinX : compareNodeMinX;
    const compareMinY = node.leaf ? this.compareMinY : compareNodeMinY;
    const xMargin = this._allDistMargin(node, m, M, compareMinX);
    const yMargin = this._allDistMargin(node, m, M, compareMinY);
    if (xMargin < yMargin)
      node.children.sort(compareMinX);
  }
  _allDistMargin(node, m, M, compare) {
    node.children.sort(compare);
    const toBBox = this.toBBox;
    const leftBBox = distBBox(node, 0, m, toBBox);
    const rightBBox = distBBox(node, M - m, M, toBBox);
    let margin = bboxMargin(leftBBox) + bboxMargin(rightBBox);
    for (let i = m; i < M - m; i++) {
      const child = node.children[i];
      extend(leftBBox, node.leaf ? toBBox(child) : child);
      margin += bboxMargin(leftBBox);
    }
    for (let i = M - m - 1; i >= m; i--) {
      const child = node.children[i];
      extend(rightBBox, node.leaf ? toBBox(child) : child);
      margin += bboxMargin(rightBBox);
    }
    return margin;
  }
  _adjustParentBBoxes(bbox, path, level2) {
    for (let i = level2; i >= 0; i--) {
      extend(path[i], bbox);
    }
  }
  _condense(path) {
    for (let i = path.length - 1, siblings; i >= 0; i--) {
      if (path[i].children.length === 0) {
        if (i > 0) {
          siblings = path[i - 1].children;
          siblings.splice(siblings.indexOf(path[i]), 1);
        } else
          this.clear();
      } else
        calcBBox(path[i], this.toBBox);
    }
  }
}
function findItem(item, items, equalsFn) {
  if (!equalsFn)
    return items.indexOf(item);
  for (let i = 0; i < items.length; i++) {
    if (equalsFn(item, items[i]))
      return i;
  }
  return -1;
}
function calcBBox(node, toBBox) {
  distBBox(node, 0, node.children.length, toBBox, node);
}
function distBBox(node, k, p, toBBox, destNode) {
  if (!destNode)
    destNode = createNode(null);
  destNode.minX = Infinity;
  destNode.minY = Infinity;
  destNode.maxX = -Infinity;
  destNode.maxY = -Infinity;
  for (let i = k; i < p; i++) {
    const child = node.children[i];
    extend(destNode, node.leaf ? toBBox(child) : child);
  }
  return destNode;
}
function extend(a3, b) {
  a3.minX = Math.min(a3.minX, b.minX);
  a3.minY = Math.min(a3.minY, b.minY);
  a3.maxX = Math.max(a3.maxX, b.maxX);
  a3.maxY = Math.max(a3.maxY, b.maxY);
  return a3;
}
function compareNodeMinX(a3, b) {
  return a3.minX - b.minX;
}
function compareNodeMinY(a3, b) {
  return a3.minY - b.minY;
}
function bboxArea(a3) {
  return (a3.maxX - a3.minX) * (a3.maxY - a3.minY);
}
function bboxMargin(a3) {
  return a3.maxX - a3.minX + (a3.maxY - a3.minY);
}
function enlargedArea(a3, b) {
  return (Math.max(b.maxX, a3.maxX) - Math.min(b.minX, a3.minX)) * (Math.max(b.maxY, a3.maxY) - Math.min(b.minY, a3.minY));
}
function intersectionArea(a3, b) {
  const minX = Math.max(a3.minX, b.minX);
  const minY = Math.max(a3.minY, b.minY);
  const maxX = Math.min(a3.maxX, b.maxX);
  const maxY = Math.min(a3.maxY, b.maxY);
  return Math.max(0, maxX - minX) * Math.max(0, maxY - minY);
}
function contains(a3, b) {
  return a3.minX <= b.minX && a3.minY <= b.minY && b.maxX <= a3.maxX && b.maxY <= a3.maxY;
}
function intersects(a3, b) {
  return b.minX <= a3.maxX && b.minY <= a3.maxY && b.maxX >= a3.minX && b.maxY >= a3.minY;
}
function createNode(children) {
  return {
    children,
    height: 1,
    leaf: true,
    minX: Infinity,
    minY: Infinity,
    maxX: -Infinity,
    maxY: -Infinity
  };
}
function multiSelect(arr, left, right, n, compare) {
  const stack = [left, right];
  while (stack.length) {
    right = stack.pop();
    left = stack.pop();
    if (right - left <= n)
      continue;
    const mid = left + Math.ceil((right - left) / n / 2) * n;
    quickselect(arr, mid, left, right, compare);
    stack.push(left, mid, mid, right);
  }
}
class RBush {
  constructor(maxEntries) {
    this.rbush_ = new RBush$2(maxEntries);
    this.items_ = {};
  }
  insert(extent, value) {
    const item = {
      minX: extent[0],
      minY: extent[1],
      maxX: extent[2],
      maxY: extent[3],
      value
    };
    this.rbush_.insert(item);
    this.items_[getUid(value)] = item;
  }
  load(extents, values) {
    const items = new Array(values.length);
    for (let i = 0, l = values.length; i < l; i++) {
      const extent = extents[i];
      const value = values[i];
      const item = {
        minX: extent[0],
        minY: extent[1],
        maxX: extent[2],
        maxY: extent[3],
        value
      };
      items[i] = item;
      this.items_[getUid(value)] = item;
    }
    this.rbush_.load(items);
  }
  remove(value) {
    const uid = getUid(value);
    const item = this.items_[uid];
    delete this.items_[uid];
    return this.rbush_.remove(item) !== null;
  }
  update(extent, value) {
    const item = this.items_[getUid(value)];
    const bbox = [item.minX, item.minY, item.maxX, item.maxY];
    if (!equals$1(bbox, extent)) {
      this.remove(value);
      this.insert(extent, value);
    }
  }
  getAll() {
    const items = this.rbush_.all();
    return items.map(function(item) {
      return item.value;
    });
  }
  getInExtent(extent) {
    const bbox = {
      minX: extent[0],
      minY: extent[1],
      maxX: extent[2],
      maxY: extent[3]
    };
    const items = this.rbush_.search(bbox);
    return items.map(function(item) {
      return item.value;
    });
  }
  forEach(callback) {
    return this.forEach_(this.getAll(), callback);
  }
  forEachInExtent(extent, callback) {
    return this.forEach_(this.getInExtent(extent), callback);
  }
  forEach_(values, callback) {
    let result;
    for (let i = 0, l = values.length; i < l; i++) {
      result = callback(values[i]);
      if (result) {
        return result;
      }
    }
    return result;
  }
  isEmpty() {
    return isEmpty$1(this.items_);
  }
  clear() {
    this.rbush_.clear();
    this.items_ = {};
  }
  getExtent(extent) {
    const data = this.rbush_.toJSON();
    return createOrUpdate(data.minX, data.minY, data.maxX, data.maxY, extent);
  }
  concat(rbush) {
    this.rbush_.load(rbush.rbush_.all());
    for (const i in rbush.items_) {
      this.items_[i] = rbush.items_[i];
    }
  }
}
const RBush$1 = RBush;
class Source extends BaseObject$1 {
  constructor(options) {
    var _a;
    super();
    this.projection = get$1(options.projection);
    this.attributions_ = adaptAttributions(options.attributions);
    this.attributionsCollapsible_ = (_a = options.attributionsCollapsible) != null ? _a : true;
    this.loading = false;
    this.state_ = options.state !== void 0 ? options.state : "ready";
    this.wrapX_ = options.wrapX !== void 0 ? options.wrapX : false;
    this.interpolate_ = !!options.interpolate;
    this.viewResolver = null;
    this.viewRejector = null;
    const self2 = this;
    this.viewPromise_ = new Promise(function(resolve, reject) {
      self2.viewResolver = resolve;
      self2.viewRejector = reject;
    });
  }
  getAttributions() {
    return this.attributions_;
  }
  getAttributionsCollapsible() {
    return this.attributionsCollapsible_;
  }
  getProjection() {
    return this.projection;
  }
  getResolutions(projection) {
    return null;
  }
  getView() {
    return this.viewPromise_;
  }
  getState() {
    return this.state_;
  }
  getWrapX() {
    return this.wrapX_;
  }
  getInterpolate() {
    return this.interpolate_;
  }
  refresh() {
    this.changed();
  }
  setAttributions(attributions) {
    this.attributions_ = adaptAttributions(attributions);
    this.changed();
  }
  setState(state) {
    this.state_ = state;
    this.changed();
  }
}
function adaptAttributions(attributionLike) {
  if (!attributionLike) {
    return null;
  }
  if (typeof attributionLike === "function") {
    return attributionLike;
  }
  if (!Array.isArray(attributionLike)) {
    attributionLike = [attributionLike];
  }
  return (frameState) => attributionLike;
}
const Source$1 = Source;
const VectorEventType = {
  ADDFEATURE: "addfeature",
  CHANGEFEATURE: "changefeature",
  CLEAR: "clear",
  REMOVEFEATURE: "removefeature",
  FEATURESLOADSTART: "featuresloadstart",
  FEATURESLOADEND: "featuresloadend",
  FEATURESLOADERROR: "featuresloaderror"
};
class VectorSourceEvent extends Event {
  constructor(type, feature2, features) {
    super(type);
    this.feature = feature2;
    this.features = features;
  }
}
class VectorSource extends Source$1 {
  constructor(options) {
    options = options || {};
    super({
      attributions: options.attributions,
      interpolate: true,
      projection: void 0,
      state: "ready",
      wrapX: options.wrapX !== void 0 ? options.wrapX : true
    });
    this.on;
    this.once;
    this.un;
    this.loader_ = VOID;
    this.format_ = options.format || null;
    this.overlaps_ = options.overlaps === void 0 ? true : options.overlaps;
    this.url_ = options.url;
    if (options.loader !== void 0) {
      this.loader_ = options.loader;
    } else if (this.url_ !== void 0) {
      assert(this.format_, "`format` must be set when `url` is set");
      this.loader_ = xhr(this.url_, this.format_);
    }
    this.strategy_ = options.strategy !== void 0 ? options.strategy : all;
    const useSpatialIndex = options.useSpatialIndex !== void 0 ? options.useSpatialIndex : true;
    this.featuresRtree_ = useSpatialIndex ? new RBush$1() : null;
    this.loadedExtentsRtree_ = new RBush$1();
    this.loadingExtentsCount_ = 0;
    this.nullGeometryFeatures_ = {};
    this.idIndex_ = {};
    this.uidIndex_ = {};
    this.featureChangeKeys_ = {};
    this.featuresCollection_ = null;
    let collection;
    let features;
    if (Array.isArray(options.features)) {
      features = options.features;
    } else if (options.features) {
      collection = options.features;
      features = collection.getArray();
    }
    if (!useSpatialIndex && collection === void 0) {
      collection = new Collection$1(features);
    }
    if (features !== void 0) {
      this.addFeaturesInternal(features);
    }
    if (collection !== void 0) {
      this.bindFeaturesCollection_(collection);
    }
  }
  addFeature(feature2) {
    this.addFeatureInternal(feature2);
    this.changed();
  }
  addFeatureInternal(feature2) {
    const featureKey = getUid(feature2);
    if (!this.addToIndex_(featureKey, feature2)) {
      if (this.featuresCollection_) {
        this.featuresCollection_.remove(feature2);
      }
      return;
    }
    this.setupChangeEvents_(featureKey, feature2);
    const geometry = feature2.getGeometry();
    if (geometry) {
      const extent = geometry.getExtent();
      if (this.featuresRtree_) {
        this.featuresRtree_.insert(extent, feature2);
      }
    } else {
      this.nullGeometryFeatures_[featureKey] = feature2;
    }
    this.dispatchEvent(
      new VectorSourceEvent(VectorEventType.ADDFEATURE, feature2)
    );
  }
  setupChangeEvents_(featureKey, feature2) {
    if (feature2 instanceof RenderFeature$1) {
      return;
    }
    this.featureChangeKeys_[featureKey] = [
      listen(feature2, EventType.CHANGE, this.handleFeatureChange_, this),
      listen(
        feature2,
        ObjectEventType.PROPERTYCHANGE,
        this.handleFeatureChange_,
        this
      )
    ];
  }
  addToIndex_(featureKey, feature2) {
    let valid = true;
    if (feature2.getId() !== void 0) {
      const id = String(feature2.getId());
      if (!(id in this.idIndex_)) {
        this.idIndex_[id] = feature2;
      } else if (feature2 instanceof RenderFeature$1) {
        const indexedFeature = this.idIndex_[id];
        if (!(indexedFeature instanceof RenderFeature$1)) {
          valid = false;
        } else if (!Array.isArray(indexedFeature)) {
          this.idIndex_[id] = [indexedFeature, feature2];
        } else {
          indexedFeature.push(feature2);
        }
      } else {
        valid = false;
      }
    }
    if (valid) {
      assert(
        !(featureKey in this.uidIndex_),
        "The passed `feature` was already added to the source"
      );
      this.uidIndex_[featureKey] = feature2;
    }
    return valid;
  }
  addFeatures(features) {
    this.addFeaturesInternal(features);
    this.changed();
  }
  addFeaturesInternal(features) {
    const extents = [];
    const newFeatures = [];
    const geometryFeatures = [];
    for (let i = 0, length = features.length; i < length; i++) {
      const feature2 = features[i];
      const featureKey = getUid(feature2);
      if (this.addToIndex_(featureKey, feature2)) {
        newFeatures.push(feature2);
      }
    }
    for (let i = 0, length = newFeatures.length; i < length; i++) {
      const feature2 = newFeatures[i];
      const featureKey = getUid(feature2);
      this.setupChangeEvents_(featureKey, feature2);
      const geometry = feature2.getGeometry();
      if (geometry) {
        const extent = geometry.getExtent();
        extents.push(extent);
        geometryFeatures.push(feature2);
      } else {
        this.nullGeometryFeatures_[featureKey] = feature2;
      }
    }
    if (this.featuresRtree_) {
      this.featuresRtree_.load(extents, geometryFeatures);
    }
    if (this.hasListener(VectorEventType.ADDFEATURE)) {
      for (let i = 0, length = newFeatures.length; i < length; i++) {
        this.dispatchEvent(
          new VectorSourceEvent(VectorEventType.ADDFEATURE, newFeatures[i])
        );
      }
    }
  }
  bindFeaturesCollection_(collection) {
    let modifyingCollection = false;
    this.addEventListener(
      VectorEventType.ADDFEATURE,
      function(evt) {
        if (!modifyingCollection) {
          modifyingCollection = true;
          collection.push(evt.feature);
          modifyingCollection = false;
        }
      }
    );
    this.addEventListener(
      VectorEventType.REMOVEFEATURE,
      function(evt) {
        if (!modifyingCollection) {
          modifyingCollection = true;
          collection.remove(evt.feature);
          modifyingCollection = false;
        }
      }
    );
    collection.addEventListener(
      CollectionEventType.ADD,
      (evt) => {
        if (!modifyingCollection) {
          modifyingCollection = true;
          this.addFeature(evt.element);
          modifyingCollection = false;
        }
      }
    );
    collection.addEventListener(
      CollectionEventType.REMOVE,
      (evt) => {
        if (!modifyingCollection) {
          modifyingCollection = true;
          this.removeFeature(evt.element);
          modifyingCollection = false;
        }
      }
    );
    this.featuresCollection_ = collection;
  }
  clear(fast) {
    if (fast) {
      for (const featureId in this.featureChangeKeys_) {
        const keys = this.featureChangeKeys_[featureId];
        keys.forEach(unlistenByKey);
      }
      if (!this.featuresCollection_) {
        this.featureChangeKeys_ = {};
        this.idIndex_ = {};
        this.uidIndex_ = {};
      }
    } else {
      if (this.featuresRtree_) {
        this.featuresRtree_.forEach((feature2) => {
          this.removeFeatureInternal(feature2);
        });
        for (const id in this.nullGeometryFeatures_) {
          this.removeFeatureInternal(this.nullGeometryFeatures_[id]);
        }
      }
    }
    if (this.featuresCollection_) {
      this.featuresCollection_.clear();
    }
    if (this.featuresRtree_) {
      this.featuresRtree_.clear();
    }
    this.nullGeometryFeatures_ = {};
    const clearEvent = new VectorSourceEvent(VectorEventType.CLEAR);
    this.dispatchEvent(clearEvent);
    this.changed();
  }
  forEachFeature(callback) {
    if (this.featuresRtree_) {
      return this.featuresRtree_.forEach(callback);
    }
    if (this.featuresCollection_) {
      this.featuresCollection_.forEach(callback);
    }
  }
  forEachFeatureAtCoordinateDirect(coordinate, callback) {
    const extent = [coordinate[0], coordinate[1], coordinate[0], coordinate[1]];
    return this.forEachFeatureInExtent(extent, function(feature2) {
      const geometry = feature2.getGeometry();
      if (geometry instanceof RenderFeature$1 || geometry.intersectsCoordinate(coordinate)) {
        return callback(feature2);
      }
      return void 0;
    });
  }
  forEachFeatureInExtent(extent, callback) {
    if (this.featuresRtree_) {
      return this.featuresRtree_.forEachInExtent(extent, callback);
    }
    if (this.featuresCollection_) {
      this.featuresCollection_.forEach(callback);
    }
  }
  forEachFeatureIntersectingExtent(extent, callback) {
    return this.forEachFeatureInExtent(
      extent,
      function(feature2) {
        const geometry = feature2.getGeometry();
        if (geometry instanceof RenderFeature$1 || geometry.intersectsExtent(extent)) {
          const result = callback(feature2);
          if (result) {
            return result;
          }
        }
      }
    );
  }
  getFeaturesCollection() {
    return this.featuresCollection_;
  }
  getFeatures() {
    let features;
    if (this.featuresCollection_) {
      features = this.featuresCollection_.getArray().slice(0);
    } else if (this.featuresRtree_) {
      features = this.featuresRtree_.getAll();
      if (!isEmpty$1(this.nullGeometryFeatures_)) {
        extend$2(features, Object.values(this.nullGeometryFeatures_));
      }
    }
    return features;
  }
  getFeaturesAtCoordinate(coordinate) {
    const features = [];
    this.forEachFeatureAtCoordinateDirect(coordinate, function(feature2) {
      features.push(feature2);
    });
    return features;
  }
  getFeaturesInExtent(extent, projection) {
    if (this.featuresRtree_) {
      const multiWorld = projection && projection.canWrapX() && this.getWrapX();
      if (!multiWorld) {
        return this.featuresRtree_.getInExtent(extent);
      }
      const extents = wrapAndSliceX(extent, projection);
      return [].concat(
        ...extents.map((anExtent) => this.featuresRtree_.getInExtent(anExtent))
      );
    }
    if (this.featuresCollection_) {
      return this.featuresCollection_.getArray().slice(0);
    }
    return [];
  }
  getClosestFeatureToCoordinate(coordinate, filter) {
    const x = coordinate[0];
    const y = coordinate[1];
    let closestFeature = null;
    const closestPoint = [NaN, NaN];
    let minSquaredDistance = Infinity;
    const extent = [-Infinity, -Infinity, Infinity, Infinity];
    filter = filter ? filter : TRUE;
    this.featuresRtree_.forEachInExtent(
      extent,
      function(feature2) {
        if (filter(feature2)) {
          const geometry = feature2.getGeometry();
          const previousMinSquaredDistance = minSquaredDistance;
          minSquaredDistance = geometry instanceof RenderFeature$1 ? 0 : geometry.closestPointXY(x, y, closestPoint, minSquaredDistance);
          if (minSquaredDistance < previousMinSquaredDistance) {
            closestFeature = feature2;
            const minDistance = Math.sqrt(minSquaredDistance);
            extent[0] = x - minDistance;
            extent[1] = y - minDistance;
            extent[2] = x + minDistance;
            extent[3] = y + minDistance;
          }
        }
      }
    );
    return closestFeature;
  }
  getExtent(extent) {
    return this.featuresRtree_.getExtent(extent);
  }
  getFeatureById(id) {
    const feature2 = this.idIndex_[id.toString()];
    return feature2 !== void 0 ? feature2 : null;
  }
  getFeatureByUid(uid) {
    const feature2 = this.uidIndex_[uid];
    return feature2 !== void 0 ? feature2 : null;
  }
  getFormat() {
    return this.format_;
  }
  getOverlaps() {
    return this.overlaps_;
  }
  getUrl() {
    return this.url_;
  }
  handleFeatureChange_(event) {
    const feature2 = event.target;
    const featureKey = getUid(feature2);
    const geometry = feature2.getGeometry();
    if (!geometry) {
      if (!(featureKey in this.nullGeometryFeatures_)) {
        if (this.featuresRtree_) {
          this.featuresRtree_.remove(feature2);
        }
        this.nullGeometryFeatures_[featureKey] = feature2;
      }
    } else {
      const extent = geometry.getExtent();
      if (featureKey in this.nullGeometryFeatures_) {
        delete this.nullGeometryFeatures_[featureKey];
        if (this.featuresRtree_) {
          this.featuresRtree_.insert(extent, feature2);
        }
      } else {
        if (this.featuresRtree_) {
          this.featuresRtree_.update(extent, feature2);
        }
      }
    }
    const id = feature2.getId();
    if (id !== void 0) {
      const sid = id.toString();
      if (this.idIndex_[sid] !== feature2) {
        this.removeFromIdIndex_(feature2);
        this.idIndex_[sid] = feature2;
      }
    } else {
      this.removeFromIdIndex_(feature2);
      this.uidIndex_[featureKey] = feature2;
    }
    this.changed();
    this.dispatchEvent(
      new VectorSourceEvent(VectorEventType.CHANGEFEATURE, feature2)
    );
  }
  hasFeature(feature2) {
    const id = feature2.getId();
    if (id !== void 0) {
      return id in this.idIndex_;
    }
    return getUid(feature2) in this.uidIndex_;
  }
  isEmpty() {
    if (this.featuresRtree_) {
      return this.featuresRtree_.isEmpty() && isEmpty$1(this.nullGeometryFeatures_);
    }
    if (this.featuresCollection_) {
      return this.featuresCollection_.getLength() === 0;
    }
    return true;
  }
  loadFeatures(extent, resolution, projection) {
    const loadedExtentsRtree = this.loadedExtentsRtree_;
    const extentsToLoad = this.strategy_(extent, resolution, projection);
    for (let i = 0, ii = extentsToLoad.length; i < ii; ++i) {
      const extentToLoad = extentsToLoad[i];
      const alreadyLoaded = loadedExtentsRtree.forEachInExtent(
        extentToLoad,
        function(object) {
          return containsExtent(object.extent, extentToLoad);
        }
      );
      if (!alreadyLoaded) {
        ++this.loadingExtentsCount_;
        this.dispatchEvent(
          new VectorSourceEvent(VectorEventType.FEATURESLOADSTART)
        );
        this.loader_.call(
          this,
          extentToLoad,
          resolution,
          projection,
          (features) => {
            --this.loadingExtentsCount_;
            this.dispatchEvent(
              new VectorSourceEvent(
                VectorEventType.FEATURESLOADEND,
                void 0,
                features
              )
            );
          },
          () => {
            --this.loadingExtentsCount_;
            this.dispatchEvent(
              new VectorSourceEvent(VectorEventType.FEATURESLOADERROR)
            );
          }
        );
        loadedExtentsRtree.insert(extentToLoad, { extent: extentToLoad.slice() });
      }
    }
    this.loading = this.loader_.length < 4 ? false : this.loadingExtentsCount_ > 0;
  }
  refresh() {
    this.clear(true);
    this.loadedExtentsRtree_.clear();
    super.refresh();
  }
  removeLoadedExtent(extent) {
    const loadedExtentsRtree = this.loadedExtentsRtree_;
    const obj = loadedExtentsRtree.forEachInExtent(extent, function(object) {
      if (equals$1(object.extent, extent)) {
        return object;
      }
    });
    if (obj) {
      loadedExtentsRtree.remove(obj);
    }
  }
  removeFeatures(features) {
    let removed = false;
    for (let i = 0, ii = features.length; i < ii; ++i) {
      removed = this.removeFeatureInternal(features[i]) || removed;
    }
    if (removed) {
      this.changed();
    }
  }
  removeFeature(feature2) {
    if (!feature2) {
      return;
    }
    const removed = this.removeFeatureInternal(feature2);
    if (removed) {
      this.changed();
    }
  }
  removeFeatureInternal(feature2) {
    const featureKey = getUid(feature2);
    if (!(featureKey in this.uidIndex_)) {
      return false;
    }
    if (featureKey in this.nullGeometryFeatures_) {
      delete this.nullGeometryFeatures_[featureKey];
    } else {
      if (this.featuresRtree_) {
        this.featuresRtree_.remove(feature2);
      }
    }
    const featureChangeKeys = this.featureChangeKeys_[featureKey];
    featureChangeKeys == null ? void 0 : featureChangeKeys.forEach(unlistenByKey);
    delete this.featureChangeKeys_[featureKey];
    const id = feature2.getId();
    if (id !== void 0) {
      const idString = id.toString();
      const indexedFeature = this.idIndex_[idString];
      if (indexedFeature === feature2) {
        delete this.idIndex_[idString];
      } else if (Array.isArray(indexedFeature)) {
        indexedFeature.splice(indexedFeature.indexOf(feature2), 1);
        if (indexedFeature.length === 1) {
          this.idIndex_[idString] = indexedFeature[0];
        }
      }
    }
    delete this.uidIndex_[featureKey];
    if (this.hasListener(VectorEventType.REMOVEFEATURE)) {
      this.dispatchEvent(
        new VectorSourceEvent(VectorEventType.REMOVEFEATURE, feature2)
      );
    }
    return true;
  }
  removeFromIdIndex_(feature2) {
    for (const id in this.idIndex_) {
      if (this.idIndex_[id] === feature2) {
        delete this.idIndex_[id];
        break;
      }
    }
  }
  setLoader(loader) {
    this.loader_ = loader;
  }
  setUrl(url) {
    assert(this.format_, "`format` must be set when `url` is set");
    this.url_ = url;
    this.setLoader(xhr(url, this.format_));
  }
  setOverlaps(overlaps) {
    this.overlaps_ = overlaps;
    this.changed();
  }
}
const VectorSource$1 = VectorSource;
class Cluster extends VectorSource$1 {
  constructor(options) {
    options = options || {};
    super({
      attributions: options.attributions,
      wrapX: options.wrapX
    });
    this.resolution = void 0;
    this.distance = options.distance !== void 0 ? options.distance : 20;
    this.minDistance = options.minDistance || 0;
    this.interpolationRatio = 0;
    this.features = [];
    this.geometryFunction = options.geometryFunction || function(feature2) {
      const geometry = feature2.getGeometry();
      assert(
        !geometry || geometry.getType() === "Point",
        "The default `geometryFunction` can only handle `Point` or null geometries"
      );
      return geometry;
    };
    this.createCustomCluster_ = options.createCluster;
    this.source = null;
    this.boundRefresh_ = this.refresh.bind(this);
    this.updateDistance(this.distance, this.minDistance);
    this.setSource(options.source || null);
  }
  clear(fast) {
    this.features.length = 0;
    super.clear(fast);
  }
  getDistance() {
    return this.distance;
  }
  getSource() {
    return this.source;
  }
  loadFeatures(extent, resolution, projection) {
    var _a;
    (_a = this.source) == null ? void 0 : _a.loadFeatures(extent, resolution, projection);
    if (resolution !== this.resolution) {
      this.resolution = resolution;
      this.refresh();
    }
  }
  setDistance(distance) {
    this.updateDistance(distance, this.minDistance);
  }
  setMinDistance(minDistance) {
    this.updateDistance(this.distance, minDistance);
  }
  getMinDistance() {
    return this.minDistance;
  }
  setSource(source) {
    if (this.source) {
      this.source.removeEventListener(EventType.CHANGE, this.boundRefresh_);
    }
    this.source = source;
    if (source) {
      source.addEventListener(EventType.CHANGE, this.boundRefresh_);
    }
    this.refresh();
  }
  refresh() {
    this.clear();
    this.cluster();
    this.addFeatures(this.features);
  }
  updateDistance(distance, minDistance) {
    const ratio = distance === 0 ? 0 : Math.min(minDistance, distance) / distance;
    const changed = distance !== this.distance || this.interpolationRatio !== ratio;
    this.distance = distance;
    this.minDistance = minDistance;
    this.interpolationRatio = ratio;
    if (changed) {
      this.refresh();
    }
  }
  cluster() {
    if (this.resolution === void 0 || !this.source) {
      return;
    }
    const extent = createEmpty();
    const mapDistance = this.distance * this.resolution;
    const features = this.source.getFeatures();
    const clustered = {};
    for (let i = 0, ii = features.length; i < ii; i++) {
      const feature2 = features[i];
      if (!(getUid(feature2) in clustered)) {
        const geometry = this.geometryFunction(feature2);
        if (geometry) {
          const coordinates2 = geometry.getCoordinates();
          createOrUpdateFromCoordinate(coordinates2, extent);
          buffer(extent, mapDistance, extent);
          const neighbors = this.source.getFeaturesInExtent(extent).filter(function(neighbor) {
            const uid = getUid(neighbor);
            if (uid in clustered) {
              return false;
            }
            clustered[uid] = true;
            return true;
          });
          this.features.push(this.createCluster(neighbors, extent));
        }
      }
    }
  }
  createCluster(features, extent) {
    const centroid = [0, 0];
    for (let i = features.length - 1; i >= 0; --i) {
      const geometry2 = this.geometryFunction(features[i]);
      if (geometry2) {
        add$2(centroid, geometry2.getCoordinates());
      } else {
        features.splice(i, 1);
      }
    }
    scale$1(centroid, 1 / features.length);
    const searchCenter = getCenter(extent);
    const ratio = this.interpolationRatio;
    const geometry = new Point$1([
      centroid[0] * (1 - ratio) + searchCenter[0] * ratio,
      centroid[1] * (1 - ratio) + searchCenter[1] * ratio
    ]);
    if (this.createCustomCluster_) {
      return this.createCustomCluster_(geometry, features);
    }
    return new Feature$1({
      geometry,
      features
    });
  }
}
const Cluster$1 = Cluster;
const MapBrowserEventType = {
  SINGLECLICK: "singleclick",
  CLICK: EventType.CLICK,
  DBLCLICK: EventType.DBLCLICK,
  POINTERDRAG: "pointerdrag",
  POINTERMOVE: "pointermove",
  POINTERDOWN: "pointerdown",
  POINTERUP: "pointerup",
  POINTEROVER: "pointerover",
  POINTEROUT: "pointerout",
  POINTERENTER: "pointerenter",
  POINTERLEAVE: "pointerleave",
  POINTERCANCEL: "pointercancel"
};
const ua = typeof navigator !== "undefined" && typeof navigator.userAgent !== "undefined" ? navigator.userAgent.toLowerCase() : "";
const SAFARI = ua.includes("safari") && !ua.includes("chrom");
SAFARI && (ua.includes("version/15.4") || /cpu (os|iphone os) 15_4 like mac os x/.test(ua));
ua.includes("webkit") && !ua.includes("edge");
ua.includes("macintosh");
const WORKER_OFFSCREEN_CANVAS = typeof WorkerGlobalScope !== "undefined" && typeof OffscreenCanvas !== "undefined" && self instanceof WorkerGlobalScope;
const IMAGE_DECODE = typeof Image !== "undefined" && Image.prototype.decode;
(function() {
  let passive = false;
  try {
    const options = Object.defineProperty({}, "passive", {
      get: function() {
        passive = true;
      }
    });
    window.addEventListener("_", null, options);
    window.removeEventListener("_", null, options);
  } catch {
  }
  return passive;
})();
const never = FALSE;
const singleClick = function(mapBrowserEvent) {
  return mapBrowserEvent.type == MapBrowserEventType.SINGLECLICK;
};
const shiftKeyOnly = function(mapBrowserEvent) {
  const originalEvent = mapBrowserEvent.originalEvent;
  return !originalEvent.altKey && !(originalEvent.metaKey || originalEvent.ctrlKey) && originalEvent.shiftKey;
};
const ViewHint = {
  ANIMATING: 0,
  INTERACTING: 1
};
function createCanvasContext2D(width, height, canvasPool2, settings) {
  let canvas;
  if (canvasPool2 && canvasPool2.length) {
    canvas = canvasPool2.shift();
  } else if (WORKER_OFFSCREEN_CANVAS) {
    canvas = new OffscreenCanvas(width || 300, height || 300);
  } else {
    canvas = document.createElement("canvas");
  }
  if (width) {
    canvas.width = width;
  }
  if (height) {
    canvas.height = height;
  }
  return canvas.getContext("2d", settings);
}
let sharedCanvasContext;
function getSharedCanvasContext2D() {
  if (!sharedCanvasContext) {
    sharedCanvasContext = createCanvasContext2D(1, 1);
  }
  return sharedCanvasContext;
}
function releaseCanvas(context) {
  const canvas = context.canvas;
  canvas.width = 1;
  canvas.height = 1;
  context.clearRect(0, 0, 1, 1);
}
function replaceNode(newNode, oldNode) {
  const parent = oldNode.parentNode;
  if (parent) {
    parent.replaceChild(newNode, oldNode);
  }
}
function removeChildren(node) {
  while (node.lastChild) {
    node.lastChild.remove();
  }
}
const RenderEventType = {
  PRERENDER: "prerender",
  POSTRENDER: "postrender",
  PRECOMPOSE: "precompose",
  POSTCOMPOSE: "postcompose",
  RENDERCOMPLETE: "rendercomplete"
};
const ImageState = {
  IDLE: 0,
  LOADING: 1,
  LOADED: 2,
  ERROR: 3,
  EMPTY: 4
};
const NO_COLOR = [NaN, NaN, NaN, 0];
let colorParseContext;
function getColorParseContext() {
  if (!colorParseContext) {
    colorParseContext = createCanvasContext2D(1, 1, void 0, {
      willReadFrequently: true,
      desynchronized: true
    });
  }
  return colorParseContext;
}
const rgbModernRegEx = /^rgba?\(\s*(\d+%?)\s+(\d+%?)\s+(\d+%?)(?:\s*\/\s*(\d+%|\d*\.\d+|[01]))?\s*\)$/i;
const rgbLegacyAbsoluteRegEx = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*(\d+%|\d*\.\d+|[01]))?\s*\)$/i;
const rgbLegacyPercentageRegEx = /^rgba?\(\s*(\d+%)\s*,\s*(\d+%)\s*,\s*(\d+%)(?:\s*,\s*(\d+%|\d*\.\d+|[01]))?\s*\)$/i;
const hexRegEx = /^#([\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/i;
function toColorComponent(s, divider) {
  return s.endsWith("%") ? Number(s.substring(0, s.length - 1)) / divider : Number(s);
}
function throwInvalidColor(color) {
  throw new Error('failed to parse "' + color + '" as color');
}
function parseRgba(color) {
  if (color.toLowerCase().startsWith("rgb")) {
    const rgb = color.match(rgbLegacyAbsoluteRegEx) || color.match(rgbModernRegEx) || color.match(rgbLegacyPercentageRegEx);
    if (rgb) {
      const alpha = rgb[4];
      const rgbDivider = 100 / 255;
      return [
        clamp(toColorComponent(rgb[1], rgbDivider) + 0.5 | 0, 0, 255),
        clamp(toColorComponent(rgb[2], rgbDivider) + 0.5 | 0, 0, 255),
        clamp(toColorComponent(rgb[3], rgbDivider) + 0.5 | 0, 0, 255),
        alpha !== void 0 ? clamp(toColorComponent(alpha, 100), 0, 1) : 1
      ];
    }
    throwInvalidColor(color);
  }
  if (color.startsWith("#")) {
    if (hexRegEx.test(color)) {
      const hex = color.substring(1);
      const step = hex.length <= 4 ? 1 : 2;
      const colorFromHex = [0, 0, 0, 255];
      for (let i = 0, ii = hex.length; i < ii; i += step) {
        let colorComponent = parseInt(hex.substring(i, i + step), 16);
        if (step === 1) {
          colorComponent += colorComponent << 4;
        }
        colorFromHex[i / step] = colorComponent;
      }
      colorFromHex[3] = colorFromHex[3] / 255;
      return colorFromHex;
    }
    throwInvalidColor(color);
  }
  const context = getColorParseContext();
  context.fillStyle = "#abcdef";
  let invalidCheckFillStyle = context.fillStyle;
  context.fillStyle = color;
  if (context.fillStyle === invalidCheckFillStyle) {
    context.fillStyle = "#fedcba";
    invalidCheckFillStyle = context.fillStyle;
    context.fillStyle = color;
    if (context.fillStyle === invalidCheckFillStyle) {
      throwInvalidColor(color);
    }
  }
  const colorString = context.fillStyle;
  if (colorString.startsWith("#") || colorString.startsWith("rgba")) {
    return parseRgba(colorString);
  }
  context.clearRect(0, 0, 1, 1);
  context.fillRect(0, 0, 1, 1);
  const colorFromImage = Array.from(context.getImageData(0, 0, 1, 1).data);
  colorFromImage[3] = toFixed(colorFromImage[3] / 255, 3);
  return colorFromImage;
}
function asString(color) {
  if (typeof color === "string") {
    return color;
  }
  return toString(color);
}
const MAX_CACHE_SIZE = 1024;
const cache = {};
let cacheSize = 0;
function withAlpha(color) {
  if (color.length === 4) {
    return color;
  }
  const output = color.slice();
  output[3] = 1;
  return output;
}
function b1(v) {
  return v > 31308e-7 ? Math.pow(v, 1 / 2.4) * 269.025 - 14.025 : v * 3294.6;
}
function b2(v) {
  return v > 0.2068965 ? Math.pow(v, 3) : (v - 4 / 29) * (108 / 841);
}
function a1(v) {
  return v > 10.314724 ? Math.pow((v + 14.025) / 269.025, 2.4) : v / 3294.6;
}
function a2(v) {
  return v > 88564e-7 ? Math.pow(v, 1 / 3) : v / (108 / 841) + 4 / 29;
}
function rgbaToLcha(color) {
  const r = a1(color[0]);
  const g = a1(color[1]);
  const b = a1(color[2]);
  const y = a2(r * 0.222488403 + g * 0.716873169 + b * 0.06060791);
  const l = 500 * (a2(r * 0.452247074 + g * 0.399439023 + b * 0.148375274) - y);
  const q = 200 * (y - a2(r * 0.016863605 + g * 0.117638439 + b * 0.865350722));
  const h = Math.atan2(q, l) * (180 / Math.PI);
  return [
    116 * y - 16,
    Math.sqrt(l * l + q * q),
    h < 0 ? h + 360 : h,
    color[3]
  ];
}
function lchaToRgba(color) {
  const l = (color[0] + 16) / 116;
  const c = color[1];
  const h = color[2] * Math.PI / 180;
  const y = b2(l);
  const x = b2(l + c / 500 * Math.cos(h));
  const z = b2(l - c / 200 * Math.sin(h));
  const r = b1(x * 3.021973625 - y * 1.617392459 - z * 0.404875592);
  const g = b1(x * -0.943766287 + y * 1.916279586 + z * 0.027607165);
  const b = b1(x * 0.069407491 - y * 0.22898585 + z * 1.159737864);
  return [
    clamp(r + 0.5 | 0, 0, 255),
    clamp(g + 0.5 | 0, 0, 255),
    clamp(b + 0.5 | 0, 0, 255),
    color[3]
  ];
}
function fromString(s) {
  if (s === "none") {
    return NO_COLOR;
  }
  if (cache.hasOwnProperty(s)) {
    return cache[s];
  }
  if (cacheSize >= MAX_CACHE_SIZE) {
    let i = 0;
    for (const key in cache) {
      if ((i++ & 3) === 0) {
        delete cache[key];
        --cacheSize;
      }
    }
  }
  const color = parseRgba(s);
  if (color.length !== 4) {
    throwInvalidColor(s);
  }
  for (const c of color) {
    if (isNaN(c)) {
      throwInvalidColor(s);
    }
  }
  cache[s] = color;
  ++cacheSize;
  return color;
}
function asArray(color) {
  if (Array.isArray(color)) {
    return color;
  }
  return fromString(color);
}
function toString(color) {
  let r = color[0];
  if (r != (r | 0)) {
    r = r + 0.5 | 0;
  }
  let g = color[1];
  if (g != (g | 0)) {
    g = g + 0.5 | 0;
  }
  let b = color[2];
  if (b != (b | 0)) {
    b = b + 0.5 | 0;
  }
  const a3 = color[3] === void 0 ? 1 : Math.round(color[3] * 1e3) / 1e3;
  return "rgba(" + r + "," + g + "," + b + "," + a3 + ")";
}
function load(image, src) {
  return new Promise((resolve, reject) => {
    function handleLoad() {
      unlisten();
      resolve(image);
    }
    function handleError() {
      unlisten();
      reject(new Error("Image load error"));
    }
    function unlisten() {
      image.removeEventListener("load", handleLoad);
      image.removeEventListener("error", handleError);
    }
    image.addEventListener("load", handleLoad);
    image.addEventListener("error", handleError);
    if (src) {
      image.src = src;
    }
  });
}
function decodeFallback(image, src) {
  if (src) {
    image.src = src;
  }
  return image.src && IMAGE_DECODE ? new Promise(
    (resolve, reject) => image.decode().then(() => resolve(image)).catch(
      (e) => image.complete && image.width ? resolve(image) : reject(e)
    )
  ) : load(image);
}
class IconImageCache {
  constructor() {
    this.cache_ = {};
    this.patternCache_ = {};
    this.cacheSize_ = 0;
    this.maxCacheSize_ = 1024;
  }
  clear() {
    this.cache_ = {};
    this.patternCache_ = {};
    this.cacheSize_ = 0;
  }
  canExpireCache() {
    return this.cacheSize_ > this.maxCacheSize_;
  }
  expire() {
    if (this.canExpireCache()) {
      let i = 0;
      for (const key in this.cache_) {
        const iconImage = this.cache_[key];
        if ((i++ & 3) === 0 && !iconImage.hasListener()) {
          delete this.cache_[key];
          delete this.patternCache_[key];
          --this.cacheSize_;
        }
      }
    }
  }
  get(src, crossOrigin, color) {
    const key = getCacheKey(src, crossOrigin, color);
    return key in this.cache_ ? this.cache_[key] : null;
  }
  getPattern(src, crossOrigin, color) {
    const key = getCacheKey(src, crossOrigin, color);
    return key in this.patternCache_ ? this.patternCache_[key] : null;
  }
  set(src, crossOrigin, color, iconImage, pattern) {
    const key = getCacheKey(src, crossOrigin, color);
    const update = key in this.cache_;
    this.cache_[key] = iconImage;
    if (pattern) {
      if (iconImage.getImageState() === ImageState.IDLE) {
        iconImage.load();
      }
      if (iconImage.getImageState() === ImageState.LOADING) {
        iconImage.ready().then(() => {
          this.patternCache_[key] = getSharedCanvasContext2D().createPattern(
            iconImage.getImage(1),
            "repeat"
          );
        });
      } else {
        this.patternCache_[key] = getSharedCanvasContext2D().createPattern(
          iconImage.getImage(1),
          "repeat"
        );
      }
    }
    if (!update) {
      ++this.cacheSize_;
    }
  }
  setSize(maxCacheSize) {
    this.maxCacheSize_ = maxCacheSize;
    this.expire();
  }
}
function getCacheKey(src, crossOrigin, color) {
  const colorString = color ? asArray(color) : "null";
  return crossOrigin + ":" + src + ":" + colorString;
}
const shared = new IconImageCache();
let taintedTestContext = null;
class IconImage extends EventTarget {
  constructor(image, src, crossOrigin, imageState, color) {
    super();
    this.hitDetectionImage_ = null;
    this.image_ = image;
    this.crossOrigin_ = crossOrigin;
    this.canvas_ = {};
    this.color_ = color;
    this.imageState_ = imageState === void 0 ? ImageState.IDLE : imageState;
    this.size_ = image && image.width && image.height ? [image.width, image.height] : null;
    this.src_ = src;
    this.tainted_;
    this.ready_ = null;
  }
  initializeImage_() {
    this.image_ = new Image();
    if (this.crossOrigin_ !== null) {
      this.image_.crossOrigin = this.crossOrigin_;
    }
  }
  isTainted_() {
    if (this.tainted_ === void 0 && this.imageState_ === ImageState.LOADED) {
      if (!taintedTestContext) {
        taintedTestContext = createCanvasContext2D(1, 1, void 0, {
          willReadFrequently: true
        });
      }
      taintedTestContext.drawImage(this.image_, 0, 0);
      try {
        taintedTestContext.getImageData(0, 0, 1, 1);
        this.tainted_ = false;
      } catch {
        taintedTestContext = null;
        this.tainted_ = true;
      }
    }
    return this.tainted_ === true;
  }
  dispatchChangeEvent_() {
    this.dispatchEvent(EventType.CHANGE);
  }
  handleImageError_() {
    this.imageState_ = ImageState.ERROR;
    this.dispatchChangeEvent_();
  }
  handleImageLoad_() {
    this.imageState_ = ImageState.LOADED;
    this.size_ = [this.image_.width, this.image_.height];
    this.dispatchChangeEvent_();
  }
  getImage(pixelRatio) {
    if (!this.image_) {
      this.initializeImage_();
    }
    this.replaceColor_(pixelRatio);
    return this.canvas_[pixelRatio] ? this.canvas_[pixelRatio] : this.image_;
  }
  getPixelRatio(pixelRatio) {
    this.replaceColor_(pixelRatio);
    return this.canvas_[pixelRatio] ? pixelRatio : 1;
  }
  getImageState() {
    return this.imageState_;
  }
  getHitDetectionImage() {
    if (!this.image_) {
      this.initializeImage_();
    }
    if (!this.hitDetectionImage_) {
      if (this.isTainted_()) {
        const width = this.size_[0];
        const height = this.size_[1];
        const context = createCanvasContext2D(width, height);
        context.fillRect(0, 0, width, height);
        this.hitDetectionImage_ = context.canvas;
      } else {
        this.hitDetectionImage_ = this.image_;
      }
    }
    return this.hitDetectionImage_;
  }
  getSize() {
    return this.size_;
  }
  getSrc() {
    return this.src_;
  }
  load() {
    if (this.imageState_ !== ImageState.IDLE) {
      return;
    }
    if (!this.image_) {
      this.initializeImage_();
    }
    this.imageState_ = ImageState.LOADING;
    try {
      if (this.src_ !== void 0) {
        this.image_.src = this.src_;
      }
    } catch {
      this.handleImageError_();
    }
    if (this.image_ instanceof HTMLImageElement) {
      decodeFallback(this.image_, this.src_).then((image) => {
        this.image_ = image;
        this.handleImageLoad_();
      }).catch(this.handleImageError_.bind(this));
    }
  }
  replaceColor_(pixelRatio) {
    if (!this.color_ || this.canvas_[pixelRatio] || this.imageState_ !== ImageState.LOADED) {
      return;
    }
    const image = this.image_;
    const ctx = createCanvasContext2D(
      Math.ceil(image.width * pixelRatio),
      Math.ceil(image.height * pixelRatio)
    );
    const canvas = ctx.canvas;
    ctx.scale(pixelRatio, pixelRatio);
    ctx.drawImage(image, 0, 0);
    ctx.globalCompositeOperation = "multiply";
    ctx.fillStyle = asString(this.color_);
    ctx.fillRect(0, 0, canvas.width / pixelRatio, canvas.height / pixelRatio);
    ctx.globalCompositeOperation = "destination-in";
    ctx.drawImage(image, 0, 0);
    this.canvas_[pixelRatio] = canvas;
  }
  ready() {
    if (!this.ready_) {
      this.ready_ = new Promise((resolve) => {
        if (this.imageState_ === ImageState.LOADED || this.imageState_ === ImageState.ERROR) {
          resolve();
        } else {
          const onChange = () => {
            if (this.imageState_ === ImageState.LOADED || this.imageState_ === ImageState.ERROR) {
              this.removeEventListener(EventType.CHANGE, onChange);
              resolve();
            }
          };
          this.addEventListener(EventType.CHANGE, onChange);
        }
      });
    }
    return this.ready_;
  }
}
function get(image, cacheKey, crossOrigin, imageState, color, pattern) {
  let iconImage = cacheKey === void 0 ? void 0 : shared.get(cacheKey, crossOrigin, color);
  if (!iconImage) {
    iconImage = new IconImage(
      image,
      image && "src" in image ? image.src || void 0 : cacheKey,
      crossOrigin,
      imageState,
      color
    );
    shared.set(cacheKey, crossOrigin, color, iconImage, pattern);
  }
  if (pattern && iconImage && !shared.getPattern(cacheKey, crossOrigin, color)) {
    shared.set(cacheKey, crossOrigin, color, iconImage, pattern);
  }
  return iconImage;
}
function asColorLike(color) {
  if (!color) {
    return null;
  }
  if (Array.isArray(color)) {
    return toString(color);
  }
  if (typeof color === "object" && "src" in color) {
    return asCanvasPattern(color);
  }
  return color;
}
function asCanvasPattern(pattern) {
  if (!pattern.offset || !pattern.size) {
    return shared.getPattern(pattern.src, "anonymous", pattern.color);
  }
  const cacheKey = pattern.src + ":" + pattern.offset;
  const canvasPattern = shared.getPattern(
    cacheKey,
    void 0,
    pattern.color
  );
  if (canvasPattern) {
    return canvasPattern;
  }
  const iconImage = shared.get(pattern.src, "anonymous", null);
  if (iconImage.getImageState() !== ImageState.LOADED) {
    return null;
  }
  const patternCanvasContext = createCanvasContext2D(
    pattern.size[0],
    pattern.size[1]
  );
  patternCanvasContext.drawImage(
    iconImage.getImage(1),
    pattern.offset[0],
    pattern.offset[1],
    pattern.size[0],
    pattern.size[1],
    0,
    0,
    pattern.size[0],
    pattern.size[1]
  );
  get(
    patternCanvasContext.canvas,
    cacheKey,
    void 0,
    ImageState.LOADED,
    pattern.color,
    true
  );
  return shared.getPattern(cacheKey, void 0, pattern.color);
}
class VectorContext {
  drawCustom(geometry, feature2, renderer, hitDetectionRenderer, index2) {
  }
  drawGeometry(geometry) {
  }
  setStyle(style) {
  }
  drawCircle(circleGeometry, feature2, index2) {
  }
  drawFeature(feature2, style, index2) {
  }
  drawGeometryCollection(geometryCollectionGeometry, feature2, index2) {
  }
  drawLineString(lineStringGeometry, feature2, index2) {
  }
  drawMultiLineString(multiLineStringGeometry, feature2, index2) {
  }
  drawMultiPoint(multiPointGeometry, feature2, index2) {
  }
  drawMultiPolygon(multiPolygonGeometry, feature2, index2) {
  }
  drawPoint(pointGeometry, feature2, index2) {
  }
  drawPolygon(polygonGeometry, feature2, index2) {
  }
  drawText(geometry, feature2, index2) {
  }
  setFillStrokeStyle(fillStyle, strokeStyle) {
  }
  setImageStyle(imageStyle, declutterImageWithText) {
  }
  setTextStyle(textStyle, declutterImageWithText) {
  }
}
const VectorContext$1 = VectorContext;
const CLASS_HIDDEN = "ol-hidden";
const CLASS_UNSELECTABLE = "ol-unselectable";
const CLASS_CONTROL = "ol-control";
const CLASS_COLLAPSED = "ol-collapsed";
const fontRegEx = new RegExp(
  [
    "^\\s*(?=(?:(?:[-a-z]+\\s*){0,2}(italic|oblique))?)",
    "(?=(?:(?:[-a-z]+\\s*){0,2}(small-caps))?)",
    "(?=(?:(?:[-a-z]+\\s*){0,2}(bold(?:er)?|lighter|[1-9]00 ))?)",
    "(?:(?:normal|\\1|\\2|\\3)\\s*){0,3}((?:xx?-)?",
    "(?:small|large)|medium|smaller|larger|[\\.\\d]+(?:\\%|in|[cem]m|ex|p[ctx]))",
    "(?:\\s*\\/\\s*(normal|[\\.\\d]+(?:\\%|in|[cem]m|ex|p[ctx])?))",
    `?\\s*([-,\\"\\'\\sa-z0-9]+?)\\s*$`
  ].join(""),
  "i"
);
const fontRegExMatchIndex = [
  "style",
  "variant",
  "weight",
  "size",
  "lineHeight",
  "family"
];
const fontWeights = {
  normal: 400,
  bold: 700
};
const getFontParameters = function(fontSpec) {
  const match = fontSpec.match(fontRegEx);
  if (!match) {
    return null;
  }
  const style = {
    lineHeight: "normal",
    size: "1.2em",
    style: "normal",
    weight: "400",
    variant: "normal"
  };
  for (let i = 0, ii = fontRegExMatchIndex.length; i < ii; ++i) {
    const value = match[i + 1];
    if (value !== void 0) {
      style[fontRegExMatchIndex[i]] = typeof value === "string" ? value.trim() : value;
    }
  }
  if (isNaN(Number(style.weight)) && style.weight in fontWeights) {
    style.weight = fontWeights[style.weight];
  }
  style.families = style.family.split(/,\s?/).map((f) => f.trim().replace(/^['"]|['"]$/g, ""));
  return style;
};
const defaultFont = "10px sans-serif";
const defaultFillStyle = "#000";
const defaultLineCap = "round";
const defaultLineDash = [];
const defaultLineDashOffset = 0;
const defaultLineJoin = "round";
const defaultMiterLimit = 10;
const defaultStrokeStyle = "#000";
const defaultTextAlign = "center";
const defaultTextBaseline = "middle";
const defaultPadding = [0, 0, 0, 0];
const defaultLineWidth = 1;
const checkedFonts = new BaseObject$1();
let measureContext = null;
let measureFont;
const textHeights = {};
const genericFontFamilies = /* @__PURE__ */ new Set([
  "serif",
  "sans-serif",
  "monospace",
  "cursive",
  "fantasy",
  "system-ui",
  "ui-serif",
  "ui-sans-serif",
  "ui-monospace",
  "ui-rounded",
  "emoji",
  "math",
  "fangsong"
]);
function getFontKey(style, weight, family) {
  return `${style} ${weight} 16px "${family}"`;
}
const registerFont = function() {
  const retries = 100;
  let timeout, fontFaceSet;
  async function isAvailable(fontSpec) {
    await fontFaceSet.ready;
    const fontFaces = await fontFaceSet.load(fontSpec);
    if (fontFaces.length === 0) {
      return false;
    }
    const font = getFontParameters(fontSpec);
    const checkFamily = font.families[0].toLowerCase();
    const checkWeight = font.weight;
    return fontFaces.some(
      (f) => {
        const family = f.family.replace(/^['"]|['"]$/g, "").toLowerCase();
        const weight = fontWeights[f.weight] || f.weight;
        return family === checkFamily && f.style === font.style && weight == checkWeight;
      }
    );
  }
  async function check() {
    await fontFaceSet.ready;
    let done = true;
    const checkedFontsProperties = checkedFonts.getProperties();
    const fonts = Object.keys(checkedFontsProperties).filter(
      (key) => checkedFontsProperties[key] < retries
    );
    for (let i = fonts.length - 1; i >= 0; --i) {
      const font = fonts[i];
      let currentRetries = checkedFontsProperties[font];
      if (currentRetries < retries) {
        if (await isAvailable(font)) {
          clear(textHeights);
          checkedFonts.set(font, retries);
        } else {
          currentRetries += 10;
          checkedFonts.set(font, currentRetries, true);
          if (currentRetries < retries) {
            done = false;
          }
        }
      }
    }
    timeout = void 0;
    if (!done) {
      timeout = setTimeout(check, 100);
    }
  }
  return async function(fontSpec) {
    if (!fontFaceSet) {
      fontFaceSet = WORKER_OFFSCREEN_CANVAS ? self.fonts : document.fonts;
    }
    const font = getFontParameters(fontSpec);
    if (!font) {
      return;
    }
    const families = font.families;
    let needCheck = false;
    for (const family of families) {
      if (genericFontFamilies.has(family)) {
        continue;
      }
      const key = getFontKey(font.style, font.weight, family);
      if (checkedFonts.get(key) !== void 0) {
        continue;
      }
      checkedFonts.set(key, 0, true);
      needCheck = true;
    }
    if (needCheck) {
      clearTimeout(timeout);
      timeout = setTimeout(check, 100);
    }
  };
}();
const measureTextHeight = function() {
  let measureElement;
  return function(fontSpec) {
    let height = textHeights[fontSpec];
    if (height == void 0) {
      if (WORKER_OFFSCREEN_CANVAS) {
        const font = getFontParameters(fontSpec);
        const metrics = measureText(fontSpec, "\u017Dg");
        const lineHeight = isNaN(Number(font.lineHeight)) ? 1.2 : Number(font.lineHeight);
        height = lineHeight * (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent);
      } else {
        if (!measureElement) {
          measureElement = document.createElement("div");
          measureElement.innerHTML = "M";
          measureElement.style.minHeight = "0";
          measureElement.style.maxHeight = "none";
          measureElement.style.height = "auto";
          measureElement.style.padding = "0";
          measureElement.style.border = "none";
          measureElement.style.position = "absolute";
          measureElement.style.display = "block";
          measureElement.style.left = "-99999px";
        }
        measureElement.style.font = fontSpec;
        document.body.appendChild(measureElement);
        height = measureElement.offsetHeight;
        document.body.removeChild(measureElement);
      }
      textHeights[fontSpec] = height;
    }
    return height;
  };
}();
function measureText(font, text) {
  if (!measureContext) {
    measureContext = createCanvasContext2D(1, 1);
  }
  if (font != measureFont) {
    measureContext.font = font;
    measureFont = measureContext.font;
  }
  return measureContext.measureText(text);
}
function measureTextWidth(font, text) {
  return measureText(font, text).width;
}
function measureAndCacheTextWidth(font, text, cache2) {
  if (text in cache2) {
    return cache2[text];
  }
  const width = text.split("\n").reduce((prev, curr) => Math.max(prev, measureTextWidth(font, curr)), 0);
  cache2[text] = width;
  return width;
}
function getTextDimensions(baseStyle, chunks) {
  const widths = [];
  const heights = [];
  const lineWidths = [];
  let width = 0;
  let lineWidth = 0;
  let height = 0;
  let lineHeight = 0;
  for (let i = 0, ii = chunks.length; i <= ii; i += 2) {
    const text = chunks[i];
    if (text === "\n" || i === ii) {
      width = Math.max(width, lineWidth);
      lineWidths.push(lineWidth);
      lineWidth = 0;
      height += lineHeight;
      lineHeight = 0;
      continue;
    }
    const font = chunks[i + 1] || baseStyle.font;
    const currentWidth = measureTextWidth(font, text);
    widths.push(currentWidth);
    lineWidth += currentWidth;
    const currentHeight = measureTextHeight(font);
    heights.push(currentHeight);
    lineHeight = Math.max(lineHeight, currentHeight);
  }
  return { width, height, widths, heights, lineWidths };
}
function drawImageOrLabel(context, transform, opacity, labelOrImage, originX, originY, w, h, x, y, scale2) {
  context.save();
  if (opacity !== 1) {
    if (context.globalAlpha === void 0) {
      context.globalAlpha = (context2) => context2.globalAlpha *= opacity;
    } else {
      context.globalAlpha *= opacity;
    }
  }
  if (transform) {
    context.transform.apply(context, transform);
  }
  if (labelOrImage.contextInstructions) {
    context.translate(x, y);
    context.scale(scale2[0], scale2[1]);
    executeLabelInstructions(labelOrImage, context);
  } else if (scale2[0] < 0 || scale2[1] < 0) {
    context.translate(x, y);
    context.scale(scale2[0], scale2[1]);
    context.drawImage(
      labelOrImage,
      originX,
      originY,
      w,
      h,
      0,
      0,
      w,
      h
    );
  } else {
    context.drawImage(
      labelOrImage,
      originX,
      originY,
      w,
      h,
      x,
      y,
      w * scale2[0],
      h * scale2[1]
    );
  }
  context.restore();
}
function executeLabelInstructions(label, context) {
  const contextInstructions = label.contextInstructions;
  for (let i = 0, ii = contextInstructions.length; i < ii; i += 2) {
    if (Array.isArray(contextInstructions[i + 1])) {
      context[contextInstructions[i]].apply(
        context,
        contextInstructions[i + 1]
      );
    } else {
      context[contextInstructions[i]] = contextInstructions[i + 1];
    }
  }
}
const Instruction = {
  BEGIN_GEOMETRY: 0,
  BEGIN_PATH: 1,
  CIRCLE: 2,
  CLOSE_PATH: 3,
  CUSTOM: 4,
  DRAW_CHARS: 5,
  DRAW_IMAGE: 6,
  END_GEOMETRY: 7,
  FILL: 8,
  MOVE_TO_LINE_TO: 9,
  SET_FILL_STYLE: 10,
  SET_STROKE_STYLE: 11,
  STROKE: 12
};
const fillInstruction = [Instruction.FILL];
const strokeInstruction = [Instruction.STROKE];
const beginPathInstruction = [Instruction.BEGIN_PATH];
const closePathInstruction = [Instruction.CLOSE_PATH];
const CanvasInstruction = Instruction;
class CanvasBuilder extends VectorContext$1 {
  constructor(tolerance, maxExtent, resolution, pixelRatio) {
    super();
    this.tolerance = tolerance;
    this.maxExtent = maxExtent;
    this.pixelRatio = pixelRatio;
    this.maxLineWidth = 0;
    this.resolution = resolution;
    this.beginGeometryInstruction1_ = null;
    this.beginGeometryInstruction2_ = null;
    this.bufferedMaxExtent_ = null;
    this.instructions = [];
    this.coordinates = [];
    this.tmpCoordinate_ = [];
    this.hitDetectionInstructions = [];
    this.state = {};
  }
  applyPixelRatio(dashArray) {
    const pixelRatio = this.pixelRatio;
    return pixelRatio == 1 ? dashArray : dashArray.map(function(dash) {
      return dash * pixelRatio;
    });
  }
  appendFlatPointCoordinates(flatCoordinates, stride) {
    const extent = this.getBufferedMaxExtent();
    const tmpCoord = this.tmpCoordinate_;
    const coordinates2 = this.coordinates;
    let myEnd = coordinates2.length;
    for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
      tmpCoord[0] = flatCoordinates[i];
      tmpCoord[1] = flatCoordinates[i + 1];
      if (containsCoordinate(extent, tmpCoord)) {
        coordinates2[myEnd++] = tmpCoord[0];
        coordinates2[myEnd++] = tmpCoord[1];
      }
    }
    return myEnd;
  }
  appendFlatLineCoordinates(flatCoordinates, offset, end, stride, closed, skipFirst) {
    const coordinates2 = this.coordinates;
    let myEnd = coordinates2.length;
    const extent = this.getBufferedMaxExtent();
    if (skipFirst) {
      offset += stride;
    }
    let lastXCoord = flatCoordinates[offset];
    let lastYCoord = flatCoordinates[offset + 1];
    const nextCoord = this.tmpCoordinate_;
    let skipped = true;
    let i, lastRel, nextRel;
    for (i = offset + stride; i < end; i += stride) {
      nextCoord[0] = flatCoordinates[i];
      nextCoord[1] = flatCoordinates[i + 1];
      nextRel = coordinateRelationship(extent, nextCoord);
      if (nextRel !== lastRel) {
        if (skipped) {
          coordinates2[myEnd++] = lastXCoord;
          coordinates2[myEnd++] = lastYCoord;
          skipped = false;
        }
        coordinates2[myEnd++] = nextCoord[0];
        coordinates2[myEnd++] = nextCoord[1];
      } else if (nextRel === Relationship.INTERSECTING) {
        coordinates2[myEnd++] = nextCoord[0];
        coordinates2[myEnd++] = nextCoord[1];
        skipped = false;
      } else {
        skipped = true;
      }
      lastXCoord = nextCoord[0];
      lastYCoord = nextCoord[1];
      lastRel = nextRel;
    }
    if (closed && skipped || i === offset + stride) {
      coordinates2[myEnd++] = lastXCoord;
      coordinates2[myEnd++] = lastYCoord;
    }
    return myEnd;
  }
  drawCustomCoordinates_(flatCoordinates, offset, ends, stride, builderEnds) {
    for (let i = 0, ii = ends.length; i < ii; ++i) {
      const end = ends[i];
      const builderEnd = this.appendFlatLineCoordinates(
        flatCoordinates,
        offset,
        end,
        stride,
        false,
        false
      );
      builderEnds.push(builderEnd);
      offset = end;
    }
    return offset;
  }
  drawCustom(geometry, feature2, renderer, hitDetectionRenderer, index2) {
    this.beginGeometry(geometry, feature2, index2);
    const type = geometry.getType();
    const stride = geometry.getStride();
    const builderBegin = this.coordinates.length;
    let flatCoordinates, builderEnd, builderEnds, builderEndss;
    let offset;
    switch (type) {
      case "MultiPolygon":
        flatCoordinates = geometry.getOrientedFlatCoordinates();
        builderEndss = [];
        const endss = geometry.getEndss();
        offset = 0;
        for (let i = 0, ii = endss.length; i < ii; ++i) {
          const myEnds = [];
          offset = this.drawCustomCoordinates_(
            flatCoordinates,
            offset,
            endss[i],
            stride,
            myEnds
          );
          builderEndss.push(myEnds);
        }
        this.instructions.push([
          CanvasInstruction.CUSTOM,
          builderBegin,
          builderEndss,
          geometry,
          renderer,
          inflateMultiCoordinatesArray,
          index2
        ]);
        this.hitDetectionInstructions.push([
          CanvasInstruction.CUSTOM,
          builderBegin,
          builderEndss,
          geometry,
          hitDetectionRenderer || renderer,
          inflateMultiCoordinatesArray,
          index2
        ]);
        break;
      case "Polygon":
      case "MultiLineString":
        builderEnds = [];
        flatCoordinates = type == "Polygon" ? geometry.getOrientedFlatCoordinates() : geometry.getFlatCoordinates();
        offset = this.drawCustomCoordinates_(
          flatCoordinates,
          0,
          geometry.getEnds(),
          stride,
          builderEnds
        );
        this.instructions.push([
          CanvasInstruction.CUSTOM,
          builderBegin,
          builderEnds,
          geometry,
          renderer,
          inflateCoordinatesArray,
          index2
        ]);
        this.hitDetectionInstructions.push([
          CanvasInstruction.CUSTOM,
          builderBegin,
          builderEnds,
          geometry,
          hitDetectionRenderer || renderer,
          inflateCoordinatesArray,
          index2
        ]);
        break;
      case "LineString":
      case "Circle":
        flatCoordinates = geometry.getFlatCoordinates();
        builderEnd = this.appendFlatLineCoordinates(
          flatCoordinates,
          0,
          flatCoordinates.length,
          stride,
          false,
          false
        );
        this.instructions.push([
          CanvasInstruction.CUSTOM,
          builderBegin,
          builderEnd,
          geometry,
          renderer,
          inflateCoordinates,
          index2
        ]);
        this.hitDetectionInstructions.push([
          CanvasInstruction.CUSTOM,
          builderBegin,
          builderEnd,
          geometry,
          hitDetectionRenderer || renderer,
          inflateCoordinates,
          index2
        ]);
        break;
      case "MultiPoint":
        flatCoordinates = geometry.getFlatCoordinates();
        builderEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);
        if (builderEnd > builderBegin) {
          this.instructions.push([
            CanvasInstruction.CUSTOM,
            builderBegin,
            builderEnd,
            geometry,
            renderer,
            inflateCoordinates,
            index2
          ]);
          this.hitDetectionInstructions.push([
            CanvasInstruction.CUSTOM,
            builderBegin,
            builderEnd,
            geometry,
            hitDetectionRenderer || renderer,
            inflateCoordinates,
            index2
          ]);
        }
        break;
      case "Point":
        flatCoordinates = geometry.getFlatCoordinates();
        this.coordinates.push(flatCoordinates[0], flatCoordinates[1]);
        builderEnd = this.coordinates.length;
        this.instructions.push([
          CanvasInstruction.CUSTOM,
          builderBegin,
          builderEnd,
          geometry,
          renderer,
          void 0,
          index2
        ]);
        this.hitDetectionInstructions.push([
          CanvasInstruction.CUSTOM,
          builderBegin,
          builderEnd,
          geometry,
          hitDetectionRenderer || renderer,
          void 0,
          index2
        ]);
        break;
    }
    this.endGeometry(feature2);
  }
  beginGeometry(geometry, feature2, index2) {
    this.beginGeometryInstruction1_ = [
      CanvasInstruction.BEGIN_GEOMETRY,
      feature2,
      0,
      geometry,
      index2
    ];
    this.instructions.push(this.beginGeometryInstruction1_);
    this.beginGeometryInstruction2_ = [
      CanvasInstruction.BEGIN_GEOMETRY,
      feature2,
      0,
      geometry,
      index2
    ];
    this.hitDetectionInstructions.push(this.beginGeometryInstruction2_);
  }
  finish() {
    return {
      instructions: this.instructions,
      hitDetectionInstructions: this.hitDetectionInstructions,
      coordinates: this.coordinates
    };
  }
  reverseHitDetectionInstructions() {
    const hitDetectionInstructions = this.hitDetectionInstructions;
    hitDetectionInstructions.reverse();
    let i;
    const n = hitDetectionInstructions.length;
    let instruction;
    let type;
    let begin = -1;
    for (i = 0; i < n; ++i) {
      instruction = hitDetectionInstructions[i];
      type = instruction[0];
      if (type == CanvasInstruction.END_GEOMETRY) {
        begin = i;
      } else if (type == CanvasInstruction.BEGIN_GEOMETRY) {
        instruction[2] = i;
        reverseSubArray(this.hitDetectionInstructions, begin, i);
        begin = -1;
      }
    }
  }
  fillStyleToState(fillStyle, state = {}) {
    if (fillStyle) {
      const fillStyleColor = fillStyle.getColor();
      state.fillPatternScale = fillStyleColor && typeof fillStyleColor === "object" && "src" in fillStyleColor ? this.pixelRatio : 1;
      state.fillStyle = asColorLike(
        fillStyleColor ? fillStyleColor : defaultFillStyle
      );
    } else {
      state.fillStyle = void 0;
    }
    return state;
  }
  strokeStyleToState(strokeStyle, state = {}) {
    if (strokeStyle) {
      const strokeStyleColor = strokeStyle.getColor();
      state.strokeStyle = asColorLike(
        strokeStyleColor ? strokeStyleColor : defaultStrokeStyle
      );
      const strokeStyleLineCap = strokeStyle.getLineCap();
      state.lineCap = strokeStyleLineCap !== void 0 ? strokeStyleLineCap : defaultLineCap;
      const strokeStyleLineDash = strokeStyle.getLineDash();
      state.lineDash = strokeStyleLineDash ? strokeStyleLineDash.slice() : defaultLineDash;
      const strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
      state.lineDashOffset = strokeStyleLineDashOffset ? strokeStyleLineDashOffset : defaultLineDashOffset;
      const strokeStyleLineJoin = strokeStyle.getLineJoin();
      state.lineJoin = strokeStyleLineJoin !== void 0 ? strokeStyleLineJoin : defaultLineJoin;
      const strokeStyleWidth = strokeStyle.getWidth();
      state.lineWidth = strokeStyleWidth !== void 0 ? strokeStyleWidth : defaultLineWidth;
      const strokeStyleMiterLimit = strokeStyle.getMiterLimit();
      state.miterLimit = strokeStyleMiterLimit !== void 0 ? strokeStyleMiterLimit : defaultMiterLimit;
      if (state.lineWidth > this.maxLineWidth) {
        this.maxLineWidth = state.lineWidth;
        this.bufferedMaxExtent_ = null;
      }
    } else {
      state.strokeStyle = void 0;
      state.lineCap = void 0;
      state.lineDash = null;
      state.lineDashOffset = void 0;
      state.lineJoin = void 0;
      state.lineWidth = void 0;
      state.miterLimit = void 0;
    }
    return state;
  }
  setFillStrokeStyle(fillStyle, strokeStyle) {
    const state = this.state;
    this.fillStyleToState(fillStyle, state);
    this.strokeStyleToState(strokeStyle, state);
  }
  createFill(state) {
    const fillStyle = state.fillStyle;
    const fillInstruction2 = [CanvasInstruction.SET_FILL_STYLE, fillStyle];
    if (typeof fillStyle !== "string") {
      fillInstruction2.push(state.fillPatternScale);
    }
    return fillInstruction2;
  }
  applyStroke(state) {
    this.instructions.push(this.createStroke(state));
  }
  createStroke(state) {
    return [
      CanvasInstruction.SET_STROKE_STYLE,
      state.strokeStyle,
      state.lineWidth * this.pixelRatio,
      state.lineCap,
      state.lineJoin,
      state.miterLimit,
      state.lineDash ? this.applyPixelRatio(state.lineDash) : null,
      state.lineDashOffset * this.pixelRatio
    ];
  }
  updateFillStyle(state, createFill) {
    const fillStyle = state.fillStyle;
    if (typeof fillStyle !== "string" || state.currentFillStyle != fillStyle) {
      this.instructions.push(createFill.call(this, state));
      state.currentFillStyle = fillStyle;
    }
  }
  updateStrokeStyle(state, applyStroke) {
    const strokeStyle = state.strokeStyle;
    const lineCap = state.lineCap;
    const lineDash = state.lineDash;
    const lineDashOffset = state.lineDashOffset;
    const lineJoin = state.lineJoin;
    const lineWidth = state.lineWidth;
    const miterLimit = state.miterLimit;
    if (state.currentStrokeStyle != strokeStyle || state.currentLineCap != lineCap || lineDash != state.currentLineDash && !equals$2(state.currentLineDash, lineDash) || state.currentLineDashOffset != lineDashOffset || state.currentLineJoin != lineJoin || state.currentLineWidth != lineWidth || state.currentMiterLimit != miterLimit) {
      applyStroke.call(this, state);
      state.currentStrokeStyle = strokeStyle;
      state.currentLineCap = lineCap;
      state.currentLineDash = lineDash;
      state.currentLineDashOffset = lineDashOffset;
      state.currentLineJoin = lineJoin;
      state.currentLineWidth = lineWidth;
      state.currentMiterLimit = miterLimit;
    }
  }
  endGeometry(feature2) {
    this.beginGeometryInstruction1_[2] = this.instructions.length;
    this.beginGeometryInstruction1_ = null;
    this.beginGeometryInstruction2_[2] = this.hitDetectionInstructions.length;
    this.beginGeometryInstruction2_ = null;
    const endGeometryInstruction = [CanvasInstruction.END_GEOMETRY, feature2];
    this.instructions.push(endGeometryInstruction);
    this.hitDetectionInstructions.push(endGeometryInstruction);
  }
  getBufferedMaxExtent() {
    if (!this.bufferedMaxExtent_) {
      this.bufferedMaxExtent_ = clone(this.maxExtent);
      if (this.maxLineWidth > 0) {
        const width = this.resolution * (this.maxLineWidth + 1) / 2;
        buffer(this.bufferedMaxExtent_, width, this.bufferedMaxExtent_);
      }
    }
    return this.bufferedMaxExtent_;
  }
}
const Builder = CanvasBuilder;
class CanvasImageBuilder extends Builder {
  constructor(tolerance, maxExtent, resolution, pixelRatio) {
    super(tolerance, maxExtent, resolution, pixelRatio);
    this.hitDetectionImage_ = null;
    this.image_ = null;
    this.imagePixelRatio_ = void 0;
    this.anchorX_ = void 0;
    this.anchorY_ = void 0;
    this.height_ = void 0;
    this.opacity_ = void 0;
    this.originX_ = void 0;
    this.originY_ = void 0;
    this.rotateWithView_ = void 0;
    this.rotation_ = void 0;
    this.scale_ = void 0;
    this.width_ = void 0;
    this.declutterMode_ = void 0;
    this.declutterImageWithText_ = void 0;
  }
  drawPoint(pointGeometry, feature2, index2) {
    if (!this.image_ || this.maxExtent && !containsCoordinate(this.maxExtent, pointGeometry.getFlatCoordinates())) {
      return;
    }
    this.beginGeometry(pointGeometry, feature2, index2);
    const flatCoordinates = pointGeometry.getFlatCoordinates();
    const stride = pointGeometry.getStride();
    const myBegin = this.coordinates.length;
    const myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);
    this.instructions.push([
      CanvasInstruction.DRAW_IMAGE,
      myBegin,
      myEnd,
      this.image_,
      this.anchorX_ * this.imagePixelRatio_,
      this.anchorY_ * this.imagePixelRatio_,
      Math.ceil(this.height_ * this.imagePixelRatio_),
      this.opacity_,
      this.originX_ * this.imagePixelRatio_,
      this.originY_ * this.imagePixelRatio_,
      this.rotateWithView_,
      this.rotation_,
      [
        this.scale_[0] * this.pixelRatio / this.imagePixelRatio_,
        this.scale_[1] * this.pixelRatio / this.imagePixelRatio_
      ],
      Math.ceil(this.width_ * this.imagePixelRatio_),
      this.declutterMode_,
      this.declutterImageWithText_
    ]);
    this.hitDetectionInstructions.push([
      CanvasInstruction.DRAW_IMAGE,
      myBegin,
      myEnd,
      this.hitDetectionImage_,
      this.anchorX_,
      this.anchorY_,
      this.height_,
      1,
      this.originX_,
      this.originY_,
      this.rotateWithView_,
      this.rotation_,
      this.scale_,
      this.width_,
      this.declutterMode_,
      this.declutterImageWithText_
    ]);
    this.endGeometry(feature2);
  }
  drawMultiPoint(multiPointGeometry, feature2, index2) {
    if (!this.image_) {
      return;
    }
    this.beginGeometry(multiPointGeometry, feature2, index2);
    const flatCoordinates = multiPointGeometry.getFlatCoordinates();
    const filteredFlatCoordinates = [];
    for (let i = 0, ii = flatCoordinates.length; i < ii; i += multiPointGeometry.getStride()) {
      if (!this.maxExtent || containsCoordinate(this.maxExtent, flatCoordinates.slice(i, i + 2))) {
        filteredFlatCoordinates.push(
          flatCoordinates[i],
          flatCoordinates[i + 1]
        );
      }
    }
    const myBegin = this.coordinates.length;
    const myEnd = this.appendFlatPointCoordinates(filteredFlatCoordinates, 2);
    this.instructions.push([
      CanvasInstruction.DRAW_IMAGE,
      myBegin,
      myEnd,
      this.image_,
      this.anchorX_ * this.imagePixelRatio_,
      this.anchorY_ * this.imagePixelRatio_,
      Math.ceil(this.height_ * this.imagePixelRatio_),
      this.opacity_,
      this.originX_ * this.imagePixelRatio_,
      this.originY_ * this.imagePixelRatio_,
      this.rotateWithView_,
      this.rotation_,
      [
        this.scale_[0] * this.pixelRatio / this.imagePixelRatio_,
        this.scale_[1] * this.pixelRatio / this.imagePixelRatio_
      ],
      Math.ceil(this.width_ * this.imagePixelRatio_),
      this.declutterMode_,
      this.declutterImageWithText_
    ]);
    this.hitDetectionInstructions.push([
      CanvasInstruction.DRAW_IMAGE,
      myBegin,
      myEnd,
      this.hitDetectionImage_,
      this.anchorX_,
      this.anchorY_,
      this.height_,
      1,
      this.originX_,
      this.originY_,
      this.rotateWithView_,
      this.rotation_,
      this.scale_,
      this.width_,
      this.declutterMode_,
      this.declutterImageWithText_
    ]);
    this.endGeometry(feature2);
  }
  finish() {
    this.reverseHitDetectionInstructions();
    this.anchorX_ = void 0;
    this.anchorY_ = void 0;
    this.hitDetectionImage_ = null;
    this.image_ = null;
    this.imagePixelRatio_ = void 0;
    this.height_ = void 0;
    this.scale_ = void 0;
    this.opacity_ = void 0;
    this.originX_ = void 0;
    this.originY_ = void 0;
    this.rotateWithView_ = void 0;
    this.rotation_ = void 0;
    this.width_ = void 0;
    return super.finish();
  }
  setImageStyle(imageStyle, sharedData) {
    const anchor = imageStyle.getAnchor();
    const size = imageStyle.getSize();
    const origin = imageStyle.getOrigin();
    this.imagePixelRatio_ = imageStyle.getPixelRatio(this.pixelRatio);
    this.anchorX_ = anchor[0];
    this.anchorY_ = anchor[1];
    this.hitDetectionImage_ = imageStyle.getHitDetectionImage();
    this.image_ = imageStyle.getImage(this.pixelRatio);
    this.height_ = size[1];
    this.opacity_ = imageStyle.getOpacity();
    this.originX_ = origin[0];
    this.originY_ = origin[1];
    this.rotateWithView_ = imageStyle.getRotateWithView();
    this.rotation_ = imageStyle.getRotation();
    this.scale_ = imageStyle.getScaleArray();
    this.width_ = size[0];
    this.declutterMode_ = imageStyle.getDeclutterMode();
    this.declutterImageWithText_ = sharedData;
  }
}
const ImageBuilder = CanvasImageBuilder;
class CanvasLineStringBuilder extends Builder {
  constructor(tolerance, maxExtent, resolution, pixelRatio) {
    super(tolerance, maxExtent, resolution, pixelRatio);
  }
  drawFlatCoordinates_(flatCoordinates, offset, end, stride) {
    const myBegin = this.coordinates.length;
    const myEnd = this.appendFlatLineCoordinates(
      flatCoordinates,
      offset,
      end,
      stride,
      false,
      false
    );
    const moveToLineToInstruction = [
      CanvasInstruction.MOVE_TO_LINE_TO,
      myBegin,
      myEnd
    ];
    this.instructions.push(moveToLineToInstruction);
    this.hitDetectionInstructions.push(moveToLineToInstruction);
    return end;
  }
  drawLineString(lineStringGeometry, feature2, index2) {
    const state = this.state;
    const strokeStyle = state.strokeStyle;
    const lineWidth = state.lineWidth;
    if (strokeStyle === void 0 || lineWidth === void 0) {
      return;
    }
    this.updateStrokeStyle(state, this.applyStroke);
    this.beginGeometry(lineStringGeometry, feature2, index2);
    this.hitDetectionInstructions.push(
      [
        CanvasInstruction.SET_STROKE_STYLE,
        state.strokeStyle,
        state.lineWidth,
        state.lineCap,
        state.lineJoin,
        state.miterLimit,
        defaultLineDash,
        defaultLineDashOffset
      ],
      beginPathInstruction
    );
    const flatCoordinates = lineStringGeometry.getFlatCoordinates();
    const stride = lineStringGeometry.getStride();
    this.drawFlatCoordinates_(
      flatCoordinates,
      0,
      flatCoordinates.length,
      stride
    );
    this.hitDetectionInstructions.push(strokeInstruction);
    this.endGeometry(feature2);
  }
  drawMultiLineString(multiLineStringGeometry, feature2, index2) {
    const state = this.state;
    const strokeStyle = state.strokeStyle;
    const lineWidth = state.lineWidth;
    if (strokeStyle === void 0 || lineWidth === void 0) {
      return;
    }
    this.updateStrokeStyle(state, this.applyStroke);
    this.beginGeometry(multiLineStringGeometry, feature2, index2);
    this.hitDetectionInstructions.push(
      [
        CanvasInstruction.SET_STROKE_STYLE,
        state.strokeStyle,
        state.lineWidth,
        state.lineCap,
        state.lineJoin,
        state.miterLimit,
        defaultLineDash,
        defaultLineDashOffset
      ],
      beginPathInstruction
    );
    const ends = multiLineStringGeometry.getEnds();
    const flatCoordinates = multiLineStringGeometry.getFlatCoordinates();
    const stride = multiLineStringGeometry.getStride();
    let offset = 0;
    for (let i = 0, ii = ends.length; i < ii; ++i) {
      offset = this.drawFlatCoordinates_(
        flatCoordinates,
        offset,
        ends[i],
        stride
      );
    }
    this.hitDetectionInstructions.push(strokeInstruction);
    this.endGeometry(feature2);
  }
  finish() {
    const state = this.state;
    if (state.lastStroke != void 0 && state.lastStroke != this.coordinates.length) {
      this.instructions.push(strokeInstruction);
    }
    this.reverseHitDetectionInstructions();
    this.state = null;
    return super.finish();
  }
  applyStroke(state) {
    if (state.lastStroke != void 0 && state.lastStroke != this.coordinates.length) {
      this.instructions.push(strokeInstruction);
      state.lastStroke = this.coordinates.length;
    }
    state.lastStroke = 0;
    super.applyStroke(state);
    this.instructions.push(beginPathInstruction);
  }
}
const LineStringBuilder = CanvasLineStringBuilder;
class CanvasPolygonBuilder extends Builder {
  constructor(tolerance, maxExtent, resolution, pixelRatio) {
    super(tolerance, maxExtent, resolution, pixelRatio);
  }
  drawFlatCoordinatess_(flatCoordinates, offset, ends, stride) {
    const state = this.state;
    const fill = state.fillStyle !== void 0;
    const stroke = state.strokeStyle !== void 0;
    const numEnds = ends.length;
    this.instructions.push(beginPathInstruction);
    this.hitDetectionInstructions.push(beginPathInstruction);
    for (let i = 0; i < numEnds; ++i) {
      const end = ends[i];
      const myBegin = this.coordinates.length;
      const myEnd = this.appendFlatLineCoordinates(
        flatCoordinates,
        offset,
        end,
        stride,
        true,
        !stroke
      );
      const moveToLineToInstruction = [
        CanvasInstruction.MOVE_TO_LINE_TO,
        myBegin,
        myEnd
      ];
      this.instructions.push(moveToLineToInstruction);
      this.hitDetectionInstructions.push(moveToLineToInstruction);
      if (stroke) {
        this.instructions.push(closePathInstruction);
        this.hitDetectionInstructions.push(closePathInstruction);
      }
      offset = end;
    }
    if (fill) {
      this.instructions.push(fillInstruction);
      this.hitDetectionInstructions.push(fillInstruction);
    }
    if (stroke) {
      this.instructions.push(strokeInstruction);
      this.hitDetectionInstructions.push(strokeInstruction);
    }
    return offset;
  }
  drawCircle(circleGeometry, feature2, index2) {
    const state = this.state;
    const fillStyle = state.fillStyle;
    const strokeStyle = state.strokeStyle;
    if (fillStyle === void 0 && strokeStyle === void 0) {
      return;
    }
    this.setFillStrokeStyles_();
    this.beginGeometry(circleGeometry, feature2, index2);
    if (state.fillStyle !== void 0) {
      this.hitDetectionInstructions.push([
        CanvasInstruction.SET_FILL_STYLE,
        defaultFillStyle
      ]);
    }
    if (state.strokeStyle !== void 0) {
      this.hitDetectionInstructions.push([
        CanvasInstruction.SET_STROKE_STYLE,
        state.strokeStyle,
        state.lineWidth,
        state.lineCap,
        state.lineJoin,
        state.miterLimit,
        defaultLineDash,
        defaultLineDashOffset
      ]);
    }
    const flatCoordinates = circleGeometry.getFlatCoordinates();
    const stride = circleGeometry.getStride();
    const myBegin = this.coordinates.length;
    this.appendFlatLineCoordinates(
      flatCoordinates,
      0,
      flatCoordinates.length,
      stride,
      false,
      false
    );
    const circleInstruction = [CanvasInstruction.CIRCLE, myBegin];
    this.instructions.push(beginPathInstruction, circleInstruction);
    this.hitDetectionInstructions.push(beginPathInstruction, circleInstruction);
    if (state.fillStyle !== void 0) {
      this.instructions.push(fillInstruction);
      this.hitDetectionInstructions.push(fillInstruction);
    }
    if (state.strokeStyle !== void 0) {
      this.instructions.push(strokeInstruction);
      this.hitDetectionInstructions.push(strokeInstruction);
    }
    this.endGeometry(feature2);
  }
  drawPolygon(polygonGeometry, feature2, index2) {
    const state = this.state;
    const fillStyle = state.fillStyle;
    const strokeStyle = state.strokeStyle;
    if (fillStyle === void 0 && strokeStyle === void 0) {
      return;
    }
    this.setFillStrokeStyles_();
    this.beginGeometry(polygonGeometry, feature2, index2);
    if (state.fillStyle !== void 0) {
      this.hitDetectionInstructions.push([
        CanvasInstruction.SET_FILL_STYLE,
        defaultFillStyle
      ]);
    }
    if (state.strokeStyle !== void 0) {
      this.hitDetectionInstructions.push([
        CanvasInstruction.SET_STROKE_STYLE,
        state.strokeStyle,
        state.lineWidth,
        state.lineCap,
        state.lineJoin,
        state.miterLimit,
        defaultLineDash,
        defaultLineDashOffset
      ]);
    }
    const ends = polygonGeometry.getEnds();
    const flatCoordinates = polygonGeometry.getOrientedFlatCoordinates();
    const stride = polygonGeometry.getStride();
    this.drawFlatCoordinatess_(
      flatCoordinates,
      0,
      ends,
      stride
    );
    this.endGeometry(feature2);
  }
  drawMultiPolygon(multiPolygonGeometry, feature2, index2) {
    const state = this.state;
    const fillStyle = state.fillStyle;
    const strokeStyle = state.strokeStyle;
    if (fillStyle === void 0 && strokeStyle === void 0) {
      return;
    }
    this.setFillStrokeStyles_();
    this.beginGeometry(multiPolygonGeometry, feature2, index2);
    if (state.fillStyle !== void 0) {
      this.hitDetectionInstructions.push([
        CanvasInstruction.SET_FILL_STYLE,
        defaultFillStyle
      ]);
    }
    if (state.strokeStyle !== void 0) {
      this.hitDetectionInstructions.push([
        CanvasInstruction.SET_STROKE_STYLE,
        state.strokeStyle,
        state.lineWidth,
        state.lineCap,
        state.lineJoin,
        state.miterLimit,
        defaultLineDash,
        defaultLineDashOffset
      ]);
    }
    const endss = multiPolygonGeometry.getEndss();
    const flatCoordinates = multiPolygonGeometry.getOrientedFlatCoordinates();
    const stride = multiPolygonGeometry.getStride();
    let offset = 0;
    for (let i = 0, ii = endss.length; i < ii; ++i) {
      offset = this.drawFlatCoordinatess_(
        flatCoordinates,
        offset,
        endss[i],
        stride
      );
    }
    this.endGeometry(feature2);
  }
  finish() {
    this.reverseHitDetectionInstructions();
    this.state = null;
    const tolerance = this.tolerance;
    if (tolerance !== 0) {
      const coordinates2 = this.coordinates;
      for (let i = 0, ii = coordinates2.length; i < ii; ++i) {
        coordinates2[i] = snap(coordinates2[i], tolerance);
      }
    }
    return super.finish();
  }
  setFillStrokeStyles_() {
    const state = this.state;
    this.updateFillStyle(state, this.createFill);
    this.updateStrokeStyle(state, this.applyStroke);
  }
}
const PolygonBuilder = CanvasPolygonBuilder;
function lineChunk(chunkLength, flatCoordinates, offset, end, stride) {
  const chunks = [];
  let cursor = offset;
  let chunkM = 0;
  let currentChunk = flatCoordinates.slice(offset, 2);
  while (chunkM < chunkLength && cursor + stride < end) {
    const [x1, y1] = currentChunk.slice(-2);
    const x2 = flatCoordinates[cursor + stride];
    const y2 = flatCoordinates[cursor + stride + 1];
    const segmentLength = Math.sqrt(
      (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)
    );
    chunkM += segmentLength;
    if (chunkM >= chunkLength) {
      const m = (chunkLength - chunkM + segmentLength) / segmentLength;
      const x = lerp(x1, x2, m);
      const y = lerp(y1, y2, m);
      currentChunk.push(x, y);
      chunks.push(currentChunk);
      currentChunk = [x, y];
      if (chunkM == chunkLength) {
        cursor += stride;
      }
      chunkM = 0;
    } else if (chunkM < chunkLength) {
      currentChunk.push(
        flatCoordinates[cursor + stride],
        flatCoordinates[cursor + stride + 1]
      );
      cursor += stride;
    } else {
      const missing = segmentLength - chunkM;
      const x = lerp(x1, x2, missing / segmentLength);
      const y = lerp(y1, y2, missing / segmentLength);
      currentChunk.push(x, y);
      chunks.push(currentChunk);
      currentChunk = [x, y];
      chunkM = 0;
      cursor += stride;
    }
  }
  if (chunkM > 0) {
    chunks.push(currentChunk);
  }
  return chunks;
}
function matchingChunk(maxAngle, flatCoordinates, offset, end, stride) {
  let chunkStart = offset;
  let chunkEnd = offset;
  let chunkM = 0;
  let m = 0;
  let start = offset;
  let acos, i, m12, m23, x1, y1, x12, y12, x23, y23;
  for (i = offset; i < end; i += stride) {
    const x2 = flatCoordinates[i];
    const y2 = flatCoordinates[i + 1];
    if (x1 !== void 0) {
      x23 = x2 - x1;
      y23 = y2 - y1;
      m23 = Math.sqrt(x23 * x23 + y23 * y23);
      if (x12 !== void 0) {
        m += m12;
        acos = Math.acos((x12 * x23 + y12 * y23) / (m12 * m23));
        if (acos > maxAngle) {
          if (m > chunkM) {
            chunkM = m;
            chunkStart = start;
            chunkEnd = i;
          }
          m = 0;
          start = i - stride;
        }
      }
      m12 = m23;
      x12 = x23;
      y12 = y23;
    }
    x1 = x2;
    y1 = y2;
  }
  m += m23;
  return m > chunkM ? [start, i] : [chunkStart, chunkEnd];
}
const TEXT_ALIGN = {
  "left": 0,
  "center": 0.5,
  "right": 1,
  "top": 0,
  "middle": 0.5,
  "hanging": 0.2,
  "alphabetic": 0.8,
  "ideographic": 0.8,
  "bottom": 1
};
class CanvasTextBuilder extends Builder {
  constructor(tolerance, maxExtent, resolution, pixelRatio) {
    super(tolerance, maxExtent, resolution, pixelRatio);
    this.labels_ = null;
    this.text_ = "";
    this.textOffsetX_ = 0;
    this.textOffsetY_ = 0;
    this.textRotateWithView_ = void 0;
    this.textKeepUpright_ = void 0;
    this.textRotation_ = 0;
    this.textFillState_ = null;
    this.fillStates = {};
    this.fillStates[defaultFillStyle] = { fillStyle: defaultFillStyle };
    this.textStrokeState_ = null;
    this.strokeStates = {};
    this.textState_ = {};
    this.textStates = {};
    this.textKey_ = "";
    this.fillKey_ = "";
    this.strokeKey_ = "";
    this.declutterMode_ = void 0;
    this.declutterImageWithText_ = void 0;
  }
  finish() {
    const instructions = super.finish();
    instructions.textStates = this.textStates;
    instructions.fillStates = this.fillStates;
    instructions.strokeStates = this.strokeStates;
    return instructions;
  }
  drawText(geometry, feature2, index2) {
    const fillState = this.textFillState_;
    const strokeState = this.textStrokeState_;
    const textState = this.textState_;
    if (this.text_ === "" || !textState || !fillState && !strokeState) {
      return;
    }
    const coordinates2 = this.coordinates;
    let begin = coordinates2.length;
    const geometryType = geometry.getType();
    let flatCoordinates = null;
    let stride = geometry.getStride();
    if (textState.placement === "line" && (geometryType == "LineString" || geometryType == "MultiLineString" || geometryType == "Polygon" || geometryType == "MultiPolygon")) {
      if (!intersects$1(this.maxExtent, geometry.getExtent())) {
        return;
      }
      let ends;
      flatCoordinates = geometry.getFlatCoordinates();
      if (geometryType == "LineString") {
        ends = [flatCoordinates.length];
      } else if (geometryType == "MultiLineString") {
        ends = geometry.getEnds();
      } else if (geometryType == "Polygon") {
        ends = geometry.getEnds().slice(0, 1);
      } else if (geometryType == "MultiPolygon") {
        const endss = geometry.getEndss();
        ends = [];
        for (let i = 0, ii = endss.length; i < ii; ++i) {
          ends.push(endss[i][0]);
        }
      }
      this.beginGeometry(geometry, feature2, index2);
      const repeat = textState.repeat;
      const textAlign = repeat ? void 0 : textState.textAlign;
      let flatOffset = 0;
      for (let o = 0, oo = ends.length; o < oo; ++o) {
        let chunks;
        if (repeat) {
          chunks = lineChunk(
            repeat * this.resolution,
            flatCoordinates,
            flatOffset,
            ends[o],
            stride
          );
        } else {
          chunks = [flatCoordinates.slice(flatOffset, ends[o])];
        }
        for (let c = 0, cc = chunks.length; c < cc; ++c) {
          const chunk = chunks[c];
          let chunkBegin = 0;
          let chunkEnd = chunk.length;
          if (textAlign == void 0) {
            const range = matchingChunk(
              textState.maxAngle,
              chunk,
              0,
              chunk.length,
              2
            );
            chunkBegin = range[0];
            chunkEnd = range[1];
          }
          for (let i = chunkBegin; i < chunkEnd; i += stride) {
            coordinates2.push(chunk[i], chunk[i + 1]);
          }
          const end = coordinates2.length;
          flatOffset = ends[o];
          this.drawChars_(begin, end);
          begin = end;
        }
      }
      this.endGeometry(feature2);
    } else {
      let geometryWidths = textState.overflow ? null : [];
      switch (geometryType) {
        case "Point":
        case "MultiPoint":
          flatCoordinates = geometry.getFlatCoordinates();
          break;
        case "LineString":
          flatCoordinates = geometry.getFlatMidpoint();
          break;
        case "Circle":
          flatCoordinates = geometry.getCenter();
          break;
        case "MultiLineString":
          flatCoordinates = geometry.getFlatMidpoints();
          stride = 2;
          break;
        case "Polygon":
          flatCoordinates = geometry.getFlatInteriorPoint();
          if (!textState.overflow) {
            geometryWidths.push(flatCoordinates[2] / this.resolution);
          }
          stride = 3;
          break;
        case "MultiPolygon":
          const interiorPoints = geometry.getFlatInteriorPoints();
          flatCoordinates = [];
          for (let i = 0, ii = interiorPoints.length; i < ii; i += 3) {
            if (!textState.overflow) {
              geometryWidths.push(interiorPoints[i + 2] / this.resolution);
            }
            flatCoordinates.push(interiorPoints[i], interiorPoints[i + 1]);
          }
          if (flatCoordinates.length === 0) {
            return;
          }
          stride = 2;
          break;
      }
      const end = this.appendFlatPointCoordinates(flatCoordinates, stride);
      if (end === begin) {
        return;
      }
      if (geometryWidths && (end - begin) / 2 !== flatCoordinates.length / stride) {
        let beg = begin / 2;
        geometryWidths = geometryWidths.filter((w, i) => {
          const keep = coordinates2[(beg + i) * 2] === flatCoordinates[i * stride] && coordinates2[(beg + i) * 2 + 1] === flatCoordinates[i * stride + 1];
          if (!keep) {
            --beg;
          }
          return keep;
        });
      }
      this.saveTextStates_();
      const backgroundFill = textState.backgroundFill ? this.createFill(this.fillStyleToState(textState.backgroundFill)) : null;
      const backgroundStroke = textState.backgroundStroke ? this.createStroke(this.strokeStyleToState(textState.backgroundStroke)) : null;
      this.beginGeometry(geometry, feature2, index2);
      let padding = textState.padding;
      if (padding != defaultPadding && (textState.scale[0] < 0 || textState.scale[1] < 0)) {
        let p0 = textState.padding[0];
        let p12 = textState.padding[1];
        let p22 = textState.padding[2];
        let p32 = textState.padding[3];
        if (textState.scale[0] < 0) {
          p12 = -p12;
          p32 = -p32;
        }
        if (textState.scale[1] < 0) {
          p0 = -p0;
          p22 = -p22;
        }
        padding = [p0, p12, p22, p32];
      }
      const pixelRatio = this.pixelRatio;
      this.instructions.push([
        CanvasInstruction.DRAW_IMAGE,
        begin,
        end,
        null,
        NaN,
        NaN,
        NaN,
        1,
        0,
        0,
        this.textRotateWithView_,
        this.textRotation_,
        [1, 1],
        NaN,
        this.declutterMode_,
        this.declutterImageWithText_,
        padding == defaultPadding ? defaultPadding : padding.map(function(p) {
          return p * pixelRatio;
        }),
        backgroundFill,
        backgroundStroke,
        this.text_,
        this.textKey_,
        this.strokeKey_,
        this.fillKey_,
        this.textOffsetX_,
        this.textOffsetY_,
        geometryWidths
      ]);
      const scale2 = 1 / pixelRatio;
      const hitDetectionBackgroundFill = backgroundFill ? backgroundFill.slice(0) : null;
      if (hitDetectionBackgroundFill) {
        hitDetectionBackgroundFill[1] = defaultFillStyle;
      }
      this.hitDetectionInstructions.push([
        CanvasInstruction.DRAW_IMAGE,
        begin,
        end,
        null,
        NaN,
        NaN,
        NaN,
        1,
        0,
        0,
        this.textRotateWithView_,
        this.textRotation_,
        [scale2, scale2],
        NaN,
        this.declutterMode_,
        this.declutterImageWithText_,
        padding,
        hitDetectionBackgroundFill,
        backgroundStroke,
        this.text_,
        this.textKey_,
        this.strokeKey_,
        this.fillKey_ ? defaultFillStyle : this.fillKey_,
        this.textOffsetX_,
        this.textOffsetY_,
        geometryWidths
      ]);
      this.endGeometry(feature2);
    }
  }
  saveTextStates_() {
    const strokeState = this.textStrokeState_;
    const textState = this.textState_;
    const fillState = this.textFillState_;
    const strokeKey = this.strokeKey_;
    if (strokeState) {
      if (!(strokeKey in this.strokeStates)) {
        this.strokeStates[strokeKey] = {
          strokeStyle: strokeState.strokeStyle,
          lineCap: strokeState.lineCap,
          lineDashOffset: strokeState.lineDashOffset,
          lineWidth: strokeState.lineWidth,
          lineJoin: strokeState.lineJoin,
          miterLimit: strokeState.miterLimit,
          lineDash: strokeState.lineDash
        };
      }
    }
    const textKey = this.textKey_;
    if (!(textKey in this.textStates)) {
      this.textStates[textKey] = {
        font: textState.font,
        textAlign: textState.textAlign || defaultTextAlign,
        justify: textState.justify,
        textBaseline: textState.textBaseline || defaultTextBaseline,
        scale: textState.scale
      };
    }
    const fillKey = this.fillKey_;
    if (fillState) {
      if (!(fillKey in this.fillStates)) {
        this.fillStates[fillKey] = {
          fillStyle: fillState.fillStyle
        };
      }
    }
  }
  drawChars_(begin, end) {
    const strokeState = this.textStrokeState_;
    const textState = this.textState_;
    const strokeKey = this.strokeKey_;
    const textKey = this.textKey_;
    const fillKey = this.fillKey_;
    this.saveTextStates_();
    const pixelRatio = this.pixelRatio;
    const baseline = TEXT_ALIGN[textState.textBaseline];
    const offsetY = this.textOffsetY_ * pixelRatio;
    const text = this.text_;
    const strokeWidth = strokeState ? strokeState.lineWidth * Math.abs(textState.scale[0]) / 2 : 0;
    this.instructions.push([
      CanvasInstruction.DRAW_CHARS,
      begin,
      end,
      baseline,
      textState.overflow,
      fillKey,
      textState.maxAngle,
      pixelRatio,
      offsetY,
      strokeKey,
      strokeWidth * pixelRatio,
      text,
      textKey,
      1,
      this.declutterMode_,
      this.textKeepUpright_
    ]);
    this.hitDetectionInstructions.push([
      CanvasInstruction.DRAW_CHARS,
      begin,
      end,
      baseline,
      textState.overflow,
      fillKey ? defaultFillStyle : fillKey,
      textState.maxAngle,
      pixelRatio,
      offsetY,
      strokeKey,
      strokeWidth * pixelRatio,
      text,
      textKey,
      1 / pixelRatio,
      this.declutterMode_,
      this.textKeepUpright_
    ]);
  }
  setTextStyle(textStyle, sharedData) {
    let textState, fillState, strokeState;
    if (!textStyle) {
      this.text_ = "";
    } else {
      const textFillStyle = textStyle.getFill();
      if (!textFillStyle) {
        fillState = null;
        this.textFillState_ = fillState;
      } else {
        fillState = this.textFillState_;
        if (!fillState) {
          fillState = {};
          this.textFillState_ = fillState;
        }
        fillState.fillStyle = asColorLike(
          textFillStyle.getColor() || defaultFillStyle
        );
      }
      const textStrokeStyle = textStyle.getStroke();
      if (!textStrokeStyle) {
        strokeState = null;
        this.textStrokeState_ = strokeState;
      } else {
        strokeState = this.textStrokeState_;
        if (!strokeState) {
          strokeState = {};
          this.textStrokeState_ = strokeState;
        }
        const lineDash = textStrokeStyle.getLineDash();
        const lineDashOffset = textStrokeStyle.getLineDashOffset();
        const lineWidth = textStrokeStyle.getWidth();
        const miterLimit = textStrokeStyle.getMiterLimit();
        strokeState.lineCap = textStrokeStyle.getLineCap() || defaultLineCap;
        strokeState.lineDash = lineDash ? lineDash.slice() : defaultLineDash;
        strokeState.lineDashOffset = lineDashOffset === void 0 ? defaultLineDashOffset : lineDashOffset;
        strokeState.lineJoin = textStrokeStyle.getLineJoin() || defaultLineJoin;
        strokeState.lineWidth = lineWidth === void 0 ? defaultLineWidth : lineWidth;
        strokeState.miterLimit = miterLimit === void 0 ? defaultMiterLimit : miterLimit;
        strokeState.strokeStyle = asColorLike(
          textStrokeStyle.getColor() || defaultStrokeStyle
        );
      }
      textState = this.textState_;
      const font = textStyle.getFont() || defaultFont;
      registerFont(font);
      const textScale = textStyle.getScaleArray();
      textState.overflow = textStyle.getOverflow();
      textState.font = font;
      textState.maxAngle = textStyle.getMaxAngle();
      textState.placement = textStyle.getPlacement();
      textState.textAlign = textStyle.getTextAlign();
      textState.repeat = textStyle.getRepeat();
      textState.justify = textStyle.getJustify();
      textState.textBaseline = textStyle.getTextBaseline() || defaultTextBaseline;
      textState.backgroundFill = textStyle.getBackgroundFill();
      textState.backgroundStroke = textStyle.getBackgroundStroke();
      textState.padding = textStyle.getPadding() || defaultPadding;
      textState.scale = textScale === void 0 ? [1, 1] : textScale;
      const textOffsetX = textStyle.getOffsetX();
      const textOffsetY = textStyle.getOffsetY();
      const textRotateWithView = textStyle.getRotateWithView();
      const textKeepUpright = textStyle.getKeepUpright();
      const textRotation = textStyle.getRotation();
      this.text_ = textStyle.getText() || "";
      this.textOffsetX_ = textOffsetX === void 0 ? 0 : textOffsetX;
      this.textOffsetY_ = textOffsetY === void 0 ? 0 : textOffsetY;
      this.textRotateWithView_ = textRotateWithView === void 0 ? false : textRotateWithView;
      this.textKeepUpright_ = textKeepUpright === void 0 ? true : textKeepUpright;
      this.textRotation_ = textRotation === void 0 ? 0 : textRotation;
      this.strokeKey_ = strokeState ? (typeof strokeState.strokeStyle == "string" ? strokeState.strokeStyle : getUid(strokeState.strokeStyle)) + strokeState.lineCap + strokeState.lineDashOffset + "|" + strokeState.lineWidth + strokeState.lineJoin + strokeState.miterLimit + "[" + strokeState.lineDash.join() + "]" : "";
      this.textKey_ = textState.font + textState.scale + (textState.textAlign || "?") + (textState.repeat || "?") + (textState.justify || "?") + (textState.textBaseline || "?");
      this.fillKey_ = fillState && fillState.fillStyle ? typeof fillState.fillStyle == "string" ? fillState.fillStyle : "|" + getUid(fillState.fillStyle) : "";
    }
    this.declutterMode_ = textStyle.getDeclutterMode();
    this.declutterImageWithText_ = sharedData;
  }
}
const BATCH_CONSTRUCTORS = {
  "Circle": PolygonBuilder,
  "Default": Builder,
  "Image": ImageBuilder,
  "LineString": LineStringBuilder,
  "Polygon": PolygonBuilder,
  "Text": CanvasTextBuilder
};
class BuilderGroup {
  constructor(tolerance, maxExtent, resolution, pixelRatio) {
    this.tolerance_ = tolerance;
    this.maxExtent_ = maxExtent;
    this.pixelRatio_ = pixelRatio;
    this.resolution_ = resolution;
    this.buildersByZIndex_ = {};
  }
  finish() {
    const builderInstructions = {};
    for (const zKey in this.buildersByZIndex_) {
      builderInstructions[zKey] = builderInstructions[zKey] || {};
      const builders = this.buildersByZIndex_[zKey];
      for (const builderKey in builders) {
        const builderInstruction = builders[builderKey].finish();
        builderInstructions[zKey][builderKey] = builderInstruction;
      }
    }
    return builderInstructions;
  }
  getBuilder(zIndex, builderType) {
    const zIndexKey = zIndex !== void 0 ? zIndex.toString() : "0";
    let replays = this.buildersByZIndex_[zIndexKey];
    if (replays === void 0) {
      replays = {};
      this.buildersByZIndex_[zIndexKey] = replays;
    }
    let replay = replays[builderType];
    if (replay === void 0) {
      const Constructor = BATCH_CONSTRUCTORS[builderType];
      replay = new Constructor(
        this.tolerance_,
        this.maxExtent_,
        this.resolution_,
        this.pixelRatio_
      );
      replays[builderType] = replay;
    }
    return replay;
  }
}
const CanvasBuilderGroup = BuilderGroup;
function drawTextOnPath(flatCoordinates, offset, end, stride, text, startM, maxAngle, scale2, measureAndCacheTextWidth2, font, cache2, rotation, keepUpright = true) {
  let x2 = flatCoordinates[offset];
  let y2 = flatCoordinates[offset + 1];
  let x1 = 0;
  let y1 = 0;
  let segmentLength = 0;
  let segmentM = 0;
  function advance() {
    x1 = x2;
    y1 = y2;
    offset += stride;
    x2 = flatCoordinates[offset];
    y2 = flatCoordinates[offset + 1];
    segmentM += segmentLength;
    segmentLength = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
  }
  do {
    advance();
  } while (offset < end - stride && segmentM + segmentLength < startM);
  let interpolate = segmentLength === 0 ? 0 : (startM - segmentM) / segmentLength;
  const beginX = lerp(x1, x2, interpolate);
  const beginY = lerp(y1, y2, interpolate);
  const startOffset = offset - stride;
  const startLength = segmentM;
  const endM = startM + scale2 * measureAndCacheTextWidth2(font, text, cache2);
  while (offset < end - stride && segmentM + segmentLength < endM) {
    advance();
  }
  interpolate = segmentLength === 0 ? 0 : (endM - segmentM) / segmentLength;
  const endX = lerp(x1, x2, interpolate);
  const endY = lerp(y1, y2, interpolate);
  let reverse = false;
  if (keepUpright) {
    if (rotation) {
      const flat = [beginX, beginY, endX, endY];
      rotate(flat, 0, 4, 2, rotation, flat, flat);
      reverse = flat[0] > flat[2];
    } else {
      reverse = beginX > endX;
    }
  }
  const PI2 = Math.PI;
  const result = [];
  const singleSegment = startOffset + stride === offset;
  offset = startOffset;
  segmentLength = 0;
  segmentM = startLength;
  x2 = flatCoordinates[offset];
  y2 = flatCoordinates[offset + 1];
  let previousAngle;
  if (singleSegment) {
    advance();
    previousAngle = Math.atan2(y2 - y1, x2 - x1);
    if (reverse) {
      previousAngle += previousAngle > 0 ? -PI2 : PI2;
    }
    const x = (endX + beginX) / 2;
    const y = (endY + beginY) / 2;
    result[0] = [x, y, (endM - startM) / 2, previousAngle, text];
    return result;
  }
  text = text.replace(/\n/g, " ");
  for (let i = 0, ii = text.length; i < ii; ) {
    advance();
    let angle = Math.atan2(y2 - y1, x2 - x1);
    if (reverse) {
      angle += angle > 0 ? -PI2 : PI2;
    }
    if (previousAngle !== void 0) {
      let delta = angle - previousAngle;
      delta += delta > PI2 ? -2 * PI2 : delta < -PI2 ? 2 * PI2 : 0;
      if (Math.abs(delta) > maxAngle) {
        return null;
      }
    }
    previousAngle = angle;
    const iStart = i;
    let charLength = 0;
    for (; i < ii; ++i) {
      const index2 = reverse ? ii - i - 1 : i;
      const len = scale2 * measureAndCacheTextWidth2(font, text[index2], cache2);
      if (offset + stride < end && segmentM + segmentLength < startM + charLength + len / 2) {
        break;
      }
      charLength += len;
    }
    if (i === iStart) {
      continue;
    }
    const chars = reverse ? text.substring(ii - iStart, ii - i) : text.substring(iStart, i);
    interpolate = segmentLength === 0 ? 0 : (startM + charLength / 2 - segmentM) / segmentLength;
    const x = lerp(x1, x2, interpolate);
    const y = lerp(y1, y2, interpolate);
    result.push([x, y, charLength / 2, angle, chars]);
    startM += charLength;
  }
  return result;
}
class ZIndexContext {
  constructor() {
    __publicField(this, "pushMethodArgs_", (...args) => {
      this.push_(args);
      return this;
    });
    this.instructions_ = [];
    this.zIndex = 0;
    this.offset_ = 0;
    this.context_ = new Proxy(getSharedCanvasContext2D(), {
      get: (target, property) => {
        if (typeof getSharedCanvasContext2D()[property] !== "function") {
          return void 0;
        }
        this.push_(property);
        return this.pushMethodArgs_;
      },
      set: (target, property, value) => {
        this.push_(property, value);
        return true;
      }
    });
  }
  push_(...args) {
    const instructions = this.instructions_;
    const index2 = this.zIndex + this.offset_;
    if (!instructions[index2]) {
      instructions[index2] = [];
    }
    instructions[index2].push(...args);
  }
  pushFunction(render2) {
    this.push_(render2);
  }
  getContext() {
    return this.context_;
  }
  draw(context) {
    this.instructions_.forEach((instructionsAtIndex) => {
      for (let i = 0, ii = instructionsAtIndex.length; i < ii; ++i) {
        const property = instructionsAtIndex[i];
        if (typeof property === "function") {
          property(context);
          continue;
        }
        const instructionAtIndex = instructionsAtIndex[++i];
        if (typeof context[property] === "function") {
          context[property](...instructionAtIndex);
        } else {
          if (typeof instructionAtIndex === "function") {
            context[property] = instructionAtIndex(context);
            continue;
          }
          context[property] = instructionAtIndex;
        }
      }
    });
  }
  clear() {
    this.instructions_.length = 0;
    this.zIndex = 0;
    this.offset_ = 0;
  }
  offset() {
    this.offset_ = this.instructions_.length;
    this.zIndex = 0;
  }
}
const ZIndexContext$1 = ZIndexContext;
const tmpExtent = createEmpty();
const p1 = [];
const p2 = [];
const p3 = [];
const p4 = [];
function getDeclutterBox(replayImageOrLabelArgs) {
  return replayImageOrLabelArgs[3].declutterBox;
}
const rtlRegEx = new RegExp(
  "[" + String.fromCharCode(1425) + "-" + String.fromCharCode(2303) + String.fromCharCode(64285) + "-" + String.fromCharCode(65023) + String.fromCharCode(65136) + "-" + String.fromCharCode(65276) + String.fromCharCode(67584) + "-" + String.fromCharCode(69631) + String.fromCharCode(124928) + "-" + String.fromCharCode(126975) + "]"
);
function horizontalTextAlign(text, align) {
  if (align === "start") {
    align = rtlRegEx.test(text) ? "right" : "left";
  } else if (align === "end") {
    align = rtlRegEx.test(text) ? "left" : "right";
  }
  return TEXT_ALIGN[align];
}
function createTextChunks(acc, line, i) {
  if (i > 0) {
    acc.push("\n", "");
  }
  acc.push(line, "");
  return acc;
}
function richTextToPlainText(result, part, index2) {
  if (index2 % 2 === 0) {
    result += part;
  }
  return result;
}
class Executor {
  constructor(resolution, pixelRatio, overlaps, instructions, deferredRendering) {
    this.overlaps = overlaps;
    this.pixelRatio = pixelRatio;
    this.resolution = resolution;
    this.alignAndScaleFill_;
    this.instructions = instructions.instructions;
    this.coordinates = instructions.coordinates;
    this.coordinateCache_ = {};
    this.renderedTransform_ = create();
    this.hitDetectionInstructions = instructions.hitDetectionInstructions;
    this.pixelCoordinates_ = null;
    this.viewRotation_ = 0;
    this.fillStates = instructions.fillStates || {};
    this.strokeStates = instructions.strokeStates || {};
    this.textStates = instructions.textStates || {};
    this.widths_ = {};
    this.labels_ = {};
    this.zIndexContext_ = deferredRendering ? new ZIndexContext$1() : null;
  }
  getZIndexContext() {
    return this.zIndexContext_;
  }
  createLabel(text, textKey, fillKey, strokeKey) {
    const key = text + textKey + fillKey + strokeKey;
    if (this.labels_[key]) {
      return this.labels_[key];
    }
    const strokeState = strokeKey ? this.strokeStates[strokeKey] : null;
    const fillState = fillKey ? this.fillStates[fillKey] : null;
    const textState = this.textStates[textKey];
    const pixelRatio = this.pixelRatio;
    const scale2 = [
      textState.scale[0] * pixelRatio,
      textState.scale[1] * pixelRatio
    ];
    const align = textState.justify ? TEXT_ALIGN[textState.justify] : horizontalTextAlign(
      Array.isArray(text) ? text[0] : text,
      textState.textAlign || defaultTextAlign
    );
    const strokeWidth = strokeKey && strokeState.lineWidth ? strokeState.lineWidth : 0;
    const chunks = Array.isArray(text) ? text : String(text).split("\n").reduce(createTextChunks, []);
    const { width, height, widths, heights, lineWidths } = getTextDimensions(
      textState,
      chunks
    );
    const renderWidth = width + strokeWidth;
    const contextInstructions = [];
    const w = (renderWidth + 2) * scale2[0];
    const h = (height + strokeWidth) * scale2[1];
    const label = {
      width: w < 0 ? Math.floor(w) : Math.ceil(w),
      height: h < 0 ? Math.floor(h) : Math.ceil(h),
      contextInstructions
    };
    if (scale2[0] != 1 || scale2[1] != 1) {
      contextInstructions.push("scale", scale2);
    }
    if (strokeKey) {
      contextInstructions.push("strokeStyle", strokeState.strokeStyle);
      contextInstructions.push("lineWidth", strokeWidth);
      contextInstructions.push("lineCap", strokeState.lineCap);
      contextInstructions.push("lineJoin", strokeState.lineJoin);
      contextInstructions.push("miterLimit", strokeState.miterLimit);
      contextInstructions.push("setLineDash", [strokeState.lineDash]);
      contextInstructions.push("lineDashOffset", strokeState.lineDashOffset);
    }
    if (fillKey) {
      contextInstructions.push("fillStyle", fillState.fillStyle);
    }
    contextInstructions.push("textBaseline", "middle");
    contextInstructions.push("textAlign", "center");
    const leftRight = 0.5 - align;
    let x = align * renderWidth + leftRight * strokeWidth;
    const strokeInstructions = [];
    const fillInstructions = [];
    let lineHeight = 0;
    let lineOffset = 0;
    let widthHeightIndex = 0;
    let lineWidthIndex = 0;
    let previousFont;
    for (let i = 0, ii = chunks.length; i < ii; i += 2) {
      const text2 = chunks[i];
      if (text2 === "\n") {
        lineOffset += lineHeight;
        lineHeight = 0;
        x = align * renderWidth + leftRight * strokeWidth;
        ++lineWidthIndex;
        continue;
      }
      const font = chunks[i + 1] || textState.font;
      if (font !== previousFont) {
        if (strokeKey) {
          strokeInstructions.push("font", font);
        }
        if (fillKey) {
          fillInstructions.push("font", font);
        }
        previousFont = font;
      }
      lineHeight = Math.max(lineHeight, heights[widthHeightIndex]);
      const fillStrokeArgs = [
        text2,
        x + leftRight * widths[widthHeightIndex] + align * (widths[widthHeightIndex] - lineWidths[lineWidthIndex]),
        0.5 * (strokeWidth + lineHeight) + lineOffset
      ];
      x += widths[widthHeightIndex];
      if (strokeKey) {
        strokeInstructions.push("strokeText", fillStrokeArgs);
      }
      if (fillKey) {
        fillInstructions.push("fillText", fillStrokeArgs);
      }
      ++widthHeightIndex;
    }
    Array.prototype.push.apply(contextInstructions, strokeInstructions);
    Array.prototype.push.apply(contextInstructions, fillInstructions);
    this.labels_[key] = label;
    return label;
  }
  replayTextBackground_(context, p12, p22, p32, p42, fillInstruction2, strokeInstruction2) {
    context.beginPath();
    context.moveTo.apply(context, p12);
    context.lineTo.apply(context, p22);
    context.lineTo.apply(context, p32);
    context.lineTo.apply(context, p42);
    context.lineTo.apply(context, p12);
    if (fillInstruction2) {
      this.alignAndScaleFill_ = fillInstruction2[2];
      context.fillStyle = fillInstruction2[1];
      this.fill_(context);
    }
    if (strokeInstruction2) {
      this.setStrokeStyle_(
        context,
        strokeInstruction2
      );
      context.stroke();
    }
  }
  calculateImageOrLabelDimensions_(sheetWidth, sheetHeight, centerX, centerY, width, height, anchorX, anchorY, originX, originY, rotation, scale2, snapToPixel, padding, fillStroke, feature2) {
    anchorX *= scale2[0];
    anchorY *= scale2[1];
    let x = centerX - anchorX;
    let y = centerY - anchorY;
    const w = width + originX > sheetWidth ? sheetWidth - originX : width;
    const h = height + originY > sheetHeight ? sheetHeight - originY : height;
    const boxW = padding[3] + w * scale2[0] + padding[1];
    const boxH = padding[0] + h * scale2[1] + padding[2];
    const boxX = x - padding[3];
    const boxY = y - padding[0];
    if (fillStroke || rotation !== 0) {
      p1[0] = boxX;
      p4[0] = boxX;
      p1[1] = boxY;
      p2[1] = boxY;
      p2[0] = boxX + boxW;
      p3[0] = p2[0];
      p3[1] = boxY + boxH;
      p4[1] = p3[1];
    }
    let transform;
    if (rotation !== 0) {
      transform = compose(
        create(),
        centerX,
        centerY,
        1,
        1,
        rotation,
        -centerX,
        -centerY
      );
      apply(transform, p1);
      apply(transform, p2);
      apply(transform, p3);
      apply(transform, p4);
      createOrUpdate(
        Math.min(p1[0], p2[0], p3[0], p4[0]),
        Math.min(p1[1], p2[1], p3[1], p4[1]),
        Math.max(p1[0], p2[0], p3[0], p4[0]),
        Math.max(p1[1], p2[1], p3[1], p4[1]),
        tmpExtent
      );
    } else {
      createOrUpdate(
        Math.min(boxX, boxX + boxW),
        Math.min(boxY, boxY + boxH),
        Math.max(boxX, boxX + boxW),
        Math.max(boxY, boxY + boxH),
        tmpExtent
      );
    }
    if (snapToPixel) {
      x = Math.round(x);
      y = Math.round(y);
    }
    return {
      drawImageX: x,
      drawImageY: y,
      drawImageW: w,
      drawImageH: h,
      originX,
      originY,
      declutterBox: {
        minX: tmpExtent[0],
        minY: tmpExtent[1],
        maxX: tmpExtent[2],
        maxY: tmpExtent[3],
        value: feature2
      },
      canvasTransform: transform,
      scale: scale2
    };
  }
  replayImageOrLabel_(context, scaledCanvasSize, imageOrLabel, dimensions, opacity, fillInstruction2, strokeInstruction2) {
    const fillStroke = !!(fillInstruction2 || strokeInstruction2);
    const box = dimensions.declutterBox;
    const strokePadding = strokeInstruction2 ? strokeInstruction2[2] * dimensions.scale[0] / 2 : 0;
    const intersects2 = box.minX - strokePadding <= scaledCanvasSize[0] && box.maxX + strokePadding >= 0 && box.minY - strokePadding <= scaledCanvasSize[1] && box.maxY + strokePadding >= 0;
    if (intersects2) {
      if (fillStroke) {
        this.replayTextBackground_(
          context,
          p1,
          p2,
          p3,
          p4,
          fillInstruction2,
          strokeInstruction2
        );
      }
      drawImageOrLabel(
        context,
        dimensions.canvasTransform,
        opacity,
        imageOrLabel,
        dimensions.originX,
        dimensions.originY,
        dimensions.drawImageW,
        dimensions.drawImageH,
        dimensions.drawImageX,
        dimensions.drawImageY,
        dimensions.scale
      );
    }
    return true;
  }
  fill_(context) {
    const alignAndScale = this.alignAndScaleFill_;
    if (alignAndScale) {
      const origin = apply(this.renderedTransform_, [0, 0]);
      const repeatSize = 512 * this.pixelRatio;
      context.save();
      context.translate(origin[0] % repeatSize, origin[1] % repeatSize);
      if (alignAndScale !== 1) {
        context.scale(alignAndScale, alignAndScale);
      }
      context.rotate(this.viewRotation_);
    }
    context.fill();
    if (alignAndScale) {
      context.restore();
    }
  }
  setStrokeStyle_(context, instruction) {
    context.strokeStyle = instruction[1];
    if (!instruction[1]) {
      return;
    }
    context.lineWidth = instruction[2];
    context.lineCap = instruction[3];
    context.lineJoin = instruction[4];
    context.miterLimit = instruction[5];
    context.lineDashOffset = instruction[7];
    context.setLineDash(instruction[6]);
  }
  drawLabelWithPointPlacement_(text, textKey, strokeKey, fillKey) {
    const textState = this.textStates[textKey];
    const label = this.createLabel(text, textKey, fillKey, strokeKey);
    const strokeState = this.strokeStates[strokeKey];
    const pixelRatio = this.pixelRatio;
    const align = horizontalTextAlign(
      Array.isArray(text) ? text[0] : text,
      textState.textAlign || defaultTextAlign
    );
    const baseline = TEXT_ALIGN[textState.textBaseline || defaultTextBaseline];
    const strokeWidth = strokeState && strokeState.lineWidth ? strokeState.lineWidth : 0;
    const width = label.width / pixelRatio - 2 * textState.scale[0];
    const anchorX = align * width + 2 * (0.5 - align) * strokeWidth;
    const anchorY = baseline * label.height / pixelRatio + 2 * (0.5 - baseline) * strokeWidth;
    return {
      label,
      anchorX,
      anchorY
    };
  }
  execute_(context, scaledCanvasSize, transform, instructions, snapToPixel, featureCallback, hitExtent, declutterTree) {
    const zIndexContext = this.zIndexContext_;
    let pixelCoordinates;
    if (this.pixelCoordinates_ && equals$2(transform, this.renderedTransform_)) {
      pixelCoordinates = this.pixelCoordinates_;
    } else {
      if (!this.pixelCoordinates_) {
        this.pixelCoordinates_ = [];
      }
      pixelCoordinates = transform2D(
        this.coordinates,
        0,
        this.coordinates.length,
        2,
        transform,
        this.pixelCoordinates_
      );
      setFromArray(this.renderedTransform_, transform);
    }
    let i = 0;
    const ii = instructions.length;
    let d = 0;
    let dd;
    let anchorX, anchorY, declutterMode, prevX, prevY, roundX, roundY, image, text, textKey, strokeKey, fillKey;
    let pendingFill = 0;
    let pendingStroke = 0;
    const coordinateCache = this.coordinateCache_;
    const viewRotation = this.viewRotation_;
    const viewRotationFromTransform = Math.round(Math.atan2(-transform[1], transform[0]) * 1e12) / 1e12;
    const state = {
      context,
      pixelRatio: this.pixelRatio,
      resolution: this.resolution,
      rotation: viewRotation
    };
    const batchSize = this.instructions != instructions || this.overlaps ? 0 : 200;
    let feature2;
    let x, y, currentGeometry;
    while (i < ii) {
      const instruction = instructions[i];
      const type = instruction[0];
      switch (type) {
        case CanvasInstruction.BEGIN_GEOMETRY:
          feature2 = instruction[1];
          currentGeometry = instruction[3];
          if (!feature2.getGeometry()) {
            i = instruction[2];
          } else if (hitExtent !== void 0 && !intersects$1(hitExtent, currentGeometry.getExtent())) {
            i = instruction[2] + 1;
          } else {
            ++i;
          }
          if (zIndexContext) {
            zIndexContext.zIndex = instruction[4];
          }
          break;
        case CanvasInstruction.BEGIN_PATH:
          if (pendingFill > batchSize) {
            this.fill_(context);
            pendingFill = 0;
          }
          if (pendingStroke > batchSize) {
            context.stroke();
            pendingStroke = 0;
          }
          if (!pendingFill && !pendingStroke) {
            context.beginPath();
            prevX = NaN;
            prevY = NaN;
          }
          ++i;
          break;
        case CanvasInstruction.CIRCLE:
          d = instruction[1];
          const x1 = pixelCoordinates[d];
          const y1 = pixelCoordinates[d + 1];
          const x2 = pixelCoordinates[d + 2];
          const y2 = pixelCoordinates[d + 3];
          const dx = x2 - x1;
          const dy = y2 - y1;
          const r = Math.sqrt(dx * dx + dy * dy);
          context.moveTo(x1 + r, y1);
          context.arc(x1, y1, r, 0, 2 * Math.PI, true);
          ++i;
          break;
        case CanvasInstruction.CLOSE_PATH:
          context.closePath();
          ++i;
          break;
        case CanvasInstruction.CUSTOM:
          d = instruction[1];
          dd = instruction[2];
          const geometry = instruction[3];
          const renderer = instruction[4];
          const fn = instruction[5];
          state.geometry = geometry;
          state.feature = feature2;
          if (!(i in coordinateCache)) {
            coordinateCache[i] = [];
          }
          const coords = coordinateCache[i];
          if (fn) {
            fn(pixelCoordinates, d, dd, 2, coords);
          } else {
            coords[0] = pixelCoordinates[d];
            coords[1] = pixelCoordinates[d + 1];
            coords.length = 2;
          }
          if (zIndexContext) {
            zIndexContext.zIndex = instruction[6];
          }
          renderer(coords, state);
          ++i;
          break;
        case CanvasInstruction.DRAW_IMAGE:
          d = instruction[1];
          dd = instruction[2];
          image = instruction[3];
          anchorX = instruction[4];
          anchorY = instruction[5];
          let height = instruction[6];
          const opacity = instruction[7];
          const originX = instruction[8];
          const originY = instruction[9];
          const rotateWithView = instruction[10];
          let rotation = instruction[11];
          const scale2 = instruction[12];
          let width = instruction[13];
          declutterMode = instruction[14] || "declutter";
          const declutterImageWithText = instruction[15];
          if (!image && instruction.length >= 20) {
            text = instruction[19];
            textKey = instruction[20];
            strokeKey = instruction[21];
            fillKey = instruction[22];
            const labelWithAnchor = this.drawLabelWithPointPlacement_(
              text,
              textKey,
              strokeKey,
              fillKey
            );
            image = labelWithAnchor.label;
            instruction[3] = image;
            const textOffsetX = instruction[23];
            anchorX = (labelWithAnchor.anchorX - textOffsetX) * this.pixelRatio;
            instruction[4] = anchorX;
            const textOffsetY = instruction[24];
            anchorY = (labelWithAnchor.anchorY - textOffsetY) * this.pixelRatio;
            instruction[5] = anchorY;
            height = image.height;
            instruction[6] = height;
            width = image.width;
            instruction[13] = width;
          }
          let geometryWidths;
          if (instruction.length > 25) {
            geometryWidths = instruction[25];
          }
          let padding, backgroundFillInstruction, backgroundStrokeInstruction;
          if (instruction.length > 17) {
            padding = instruction[16];
            backgroundFillInstruction = instruction[17];
            backgroundStrokeInstruction = instruction[18];
          } else {
            padding = defaultPadding;
            backgroundFillInstruction = null;
            backgroundStrokeInstruction = null;
          }
          if (rotateWithView && viewRotationFromTransform) {
            rotation += viewRotation;
          } else if (!rotateWithView && !viewRotationFromTransform) {
            rotation -= viewRotation;
          }
          let widthIndex = 0;
          for (; d < dd; d += 2) {
            if (geometryWidths && geometryWidths[widthIndex++] < width / this.pixelRatio) {
              continue;
            }
            const dimensions = this.calculateImageOrLabelDimensions_(
              image.width,
              image.height,
              pixelCoordinates[d],
              pixelCoordinates[d + 1],
              width,
              height,
              anchorX,
              anchorY,
              originX,
              originY,
              rotation,
              scale2,
              snapToPixel,
              padding,
              !!backgroundFillInstruction || !!backgroundStrokeInstruction,
              feature2
            );
            const args = [
              context,
              scaledCanvasSize,
              image,
              dimensions,
              opacity,
              backgroundFillInstruction,
              backgroundStrokeInstruction
            ];
            if (declutterTree) {
              let imageArgs, imageDeclutterMode, imageDeclutterBox;
              if (declutterImageWithText) {
                const index2 = dd - d;
                if (!declutterImageWithText[index2]) {
                  declutterImageWithText[index2] = { args, declutterMode };
                  continue;
                }
                const imageDeclutter = declutterImageWithText[index2];
                imageArgs = imageDeclutter.args;
                imageDeclutterMode = imageDeclutter.declutterMode;
                delete declutterImageWithText[index2];
                imageDeclutterBox = getDeclutterBox(imageArgs);
              }
              let renderImage, renderText;
              if (imageArgs && (imageDeclutterMode !== "declutter" || !declutterTree.collides(imageDeclutterBox))) {
                renderImage = true;
              }
              if (declutterMode !== "declutter" || !declutterTree.collides(dimensions.declutterBox)) {
                renderText = true;
              }
              if (imageDeclutterMode === "declutter" && declutterMode === "declutter") {
                const render2 = renderImage && renderText;
                renderImage = render2;
                renderText = render2;
              }
              if (renderImage) {
                if (imageDeclutterMode !== "none") {
                  declutterTree.insert(imageDeclutterBox);
                }
                this.replayImageOrLabel_.apply(this, imageArgs);
              }
              if (renderText) {
                if (declutterMode !== "none") {
                  declutterTree.insert(dimensions.declutterBox);
                }
                this.replayImageOrLabel_.apply(this, args);
              }
            } else {
              this.replayImageOrLabel_.apply(this, args);
            }
          }
          ++i;
          break;
        case CanvasInstruction.DRAW_CHARS:
          const begin = instruction[1];
          const end = instruction[2];
          const baseline = instruction[3];
          const overflow = instruction[4];
          fillKey = instruction[5];
          const maxAngle = instruction[6];
          const measurePixelRatio = instruction[7];
          const offsetY = instruction[8];
          strokeKey = instruction[9];
          const strokeWidth = instruction[10];
          text = instruction[11];
          if (Array.isArray(text)) {
            text = text.reduce(richTextToPlainText, "");
          }
          textKey = instruction[12];
          const pixelRatioScale = [
            instruction[13],
            instruction[13]
          ];
          declutterMode = instruction[14] || "declutter";
          const textKeepUpright = instruction[15];
          const textState = this.textStates[textKey];
          const font = textState.font;
          const textScale = [
            textState.scale[0] * measurePixelRatio,
            textState.scale[1] * measurePixelRatio
          ];
          let cachedWidths;
          if (font in this.widths_) {
            cachedWidths = this.widths_[font];
          } else {
            cachedWidths = {};
            this.widths_[font] = cachedWidths;
          }
          const pathLength = lineStringLength(pixelCoordinates, begin, end, 2);
          const textLength = Math.abs(textScale[0]) * measureAndCacheTextWidth(font, text, cachedWidths);
          if (overflow || textLength <= pathLength) {
            const textAlign = this.textStates[textKey].textAlign;
            const startM = (pathLength - textLength) * horizontalTextAlign(text, textAlign);
            const parts = drawTextOnPath(
              pixelCoordinates,
              begin,
              end,
              2,
              text,
              startM,
              maxAngle,
              Math.abs(textScale[0]),
              measureAndCacheTextWidth,
              font,
              cachedWidths,
              viewRotationFromTransform ? 0 : this.viewRotation_,
              textKeepUpright
            );
            drawChars:
              if (parts) {
                const replayImageOrLabelArgs = [];
                let c, cc, chars, label, part;
                if (strokeKey) {
                  for (c = 0, cc = parts.length; c < cc; ++c) {
                    part = parts[c];
                    chars = part[4];
                    label = this.createLabel(chars, textKey, "", strokeKey);
                    anchorX = part[2] + (textScale[0] < 0 ? -strokeWidth : strokeWidth);
                    anchorY = baseline * label.height + (0.5 - baseline) * 2 * strokeWidth * textScale[1] / textScale[0] - offsetY;
                    const dimensions = this.calculateImageOrLabelDimensions_(
                      label.width,
                      label.height,
                      part[0],
                      part[1],
                      label.width,
                      label.height,
                      anchorX,
                      anchorY,
                      0,
                      0,
                      part[3],
                      pixelRatioScale,
                      false,
                      defaultPadding,
                      false,
                      feature2
                    );
                    if (declutterTree && declutterMode === "declutter" && declutterTree.collides(dimensions.declutterBox)) {
                      break drawChars;
                    }
                    replayImageOrLabelArgs.push([
                      context,
                      scaledCanvasSize,
                      label,
                      dimensions,
                      1,
                      null,
                      null
                    ]);
                  }
                }
                if (fillKey) {
                  for (c = 0, cc = parts.length; c < cc; ++c) {
                    part = parts[c];
                    chars = part[4];
                    label = this.createLabel(chars, textKey, fillKey, "");
                    anchorX = part[2];
                    anchorY = baseline * label.height - offsetY;
                    const dimensions = this.calculateImageOrLabelDimensions_(
                      label.width,
                      label.height,
                      part[0],
                      part[1],
                      label.width,
                      label.height,
                      anchorX,
                      anchorY,
                      0,
                      0,
                      part[3],
                      pixelRatioScale,
                      false,
                      defaultPadding,
                      false,
                      feature2
                    );
                    if (declutterTree && declutterMode === "declutter" && declutterTree.collides(dimensions.declutterBox)) {
                      break drawChars;
                    }
                    replayImageOrLabelArgs.push([
                      context,
                      scaledCanvasSize,
                      label,
                      dimensions,
                      1,
                      null,
                      null
                    ]);
                  }
                }
                if (declutterTree && declutterMode !== "none") {
                  declutterTree.load(replayImageOrLabelArgs.map(getDeclutterBox));
                }
                for (let i2 = 0, ii2 = replayImageOrLabelArgs.length; i2 < ii2; ++i2) {
                  this.replayImageOrLabel_.apply(this, replayImageOrLabelArgs[i2]);
                }
              }
          }
          ++i;
          break;
        case CanvasInstruction.END_GEOMETRY:
          if (featureCallback !== void 0) {
            feature2 = instruction[1];
            const result = featureCallback(
              feature2,
              currentGeometry,
              declutterMode
            );
            if (result) {
              return result;
            }
          }
          ++i;
          break;
        case CanvasInstruction.FILL:
          if (batchSize) {
            pendingFill++;
          } else {
            this.fill_(context);
          }
          ++i;
          break;
        case CanvasInstruction.MOVE_TO_LINE_TO:
          d = instruction[1];
          dd = instruction[2];
          x = pixelCoordinates[d];
          y = pixelCoordinates[d + 1];
          context.moveTo(x, y);
          prevX = x + 0.5 | 0;
          prevY = y + 0.5 | 0;
          for (d += 2; d < dd; d += 2) {
            x = pixelCoordinates[d];
            y = pixelCoordinates[d + 1];
            roundX = x + 0.5 | 0;
            roundY = y + 0.5 | 0;
            if (d == dd - 2 || roundX !== prevX || roundY !== prevY) {
              context.lineTo(x, y);
              prevX = roundX;
              prevY = roundY;
            }
          }
          ++i;
          break;
        case CanvasInstruction.SET_FILL_STYLE:
          this.alignAndScaleFill_ = instruction[2];
          if (pendingFill) {
            this.fill_(context);
            pendingFill = 0;
            if (pendingStroke) {
              context.stroke();
              pendingStroke = 0;
            }
          }
          context.fillStyle = instruction[1];
          ++i;
          break;
        case CanvasInstruction.SET_STROKE_STYLE:
          if (pendingStroke) {
            context.stroke();
            pendingStroke = 0;
          }
          this.setStrokeStyle_(context, instruction);
          ++i;
          break;
        case CanvasInstruction.STROKE:
          if (batchSize) {
            pendingStroke++;
          } else {
            context.stroke();
          }
          ++i;
          break;
        default:
          ++i;
          break;
      }
    }
    if (pendingFill) {
      this.fill_(context);
    }
    if (pendingStroke) {
      context.stroke();
    }
    return void 0;
  }
  execute(context, scaledCanvasSize, transform, viewRotation, snapToPixel, declutterTree) {
    this.viewRotation_ = viewRotation;
    this.execute_(
      context,
      scaledCanvasSize,
      transform,
      this.instructions,
      snapToPixel,
      void 0,
      void 0,
      declutterTree
    );
  }
  executeHitDetection(context, transform, viewRotation, featureCallback, hitExtent) {
    this.viewRotation_ = viewRotation;
    return this.execute_(
      context,
      [context.canvas.width, context.canvas.height],
      transform,
      this.hitDetectionInstructions,
      true,
      featureCallback,
      hitExtent
    );
  }
}
const Executor$1 = Executor;
const ALL = [
  "Polygon",
  "Circle",
  "LineString",
  "Image",
  "Text",
  "Default"
];
const DECLUTTER = ["Image", "Text"];
const NON_DECLUTTER = ALL.filter(
  (builderType) => !DECLUTTER.includes(builderType)
);
class ExecutorGroup {
  constructor(maxExtent, resolution, pixelRatio, overlaps, allInstructions, renderBuffer, deferredRendering) {
    this.maxExtent_ = maxExtent;
    this.overlaps_ = overlaps;
    this.pixelRatio_ = pixelRatio;
    this.resolution_ = resolution;
    this.renderBuffer_ = renderBuffer;
    this.executorsByZIndex_ = {};
    this.hitDetectionContext_ = null;
    this.hitDetectionTransform_ = create();
    this.renderedContext_ = null;
    this.deferredZIndexContexts_ = {};
    this.createExecutors_(allInstructions, deferredRendering);
  }
  clip(context, transform) {
    const flatClipCoords = this.getClipCoords(transform);
    context.beginPath();
    context.moveTo(flatClipCoords[0], flatClipCoords[1]);
    context.lineTo(flatClipCoords[2], flatClipCoords[3]);
    context.lineTo(flatClipCoords[4], flatClipCoords[5]);
    context.lineTo(flatClipCoords[6], flatClipCoords[7]);
    context.clip();
  }
  createExecutors_(allInstructions, deferredRendering) {
    for (const zIndex in allInstructions) {
      let executors = this.executorsByZIndex_[zIndex];
      if (executors === void 0) {
        executors = {};
        this.executorsByZIndex_[zIndex] = executors;
      }
      const instructionByZindex = allInstructions[zIndex];
      for (const builderType in instructionByZindex) {
        const instructions = instructionByZindex[builderType];
        executors[builderType] = new Executor$1(
          this.resolution_,
          this.pixelRatio_,
          this.overlaps_,
          instructions,
          deferredRendering
        );
      }
    }
  }
  hasExecutors(executors) {
    for (const zIndex in this.executorsByZIndex_) {
      const candidates = this.executorsByZIndex_[zIndex];
      for (let i = 0, ii = executors.length; i < ii; ++i) {
        if (executors[i] in candidates) {
          return true;
        }
      }
    }
    return false;
  }
  forEachFeatureAtCoordinate(coordinate, resolution, rotation, hitTolerance, callback, declutteredFeatures) {
    hitTolerance = Math.round(hitTolerance);
    const contextSize = hitTolerance * 2 + 1;
    const transform = compose(
      this.hitDetectionTransform_,
      hitTolerance + 0.5,
      hitTolerance + 0.5,
      1 / resolution,
      -1 / resolution,
      -rotation,
      -coordinate[0],
      -coordinate[1]
    );
    const newContext = !this.hitDetectionContext_;
    if (newContext) {
      this.hitDetectionContext_ = createCanvasContext2D(
        contextSize,
        contextSize
      );
    }
    const context = this.hitDetectionContext_;
    if (context.canvas.width !== contextSize || context.canvas.height !== contextSize) {
      context.canvas.width = contextSize;
      context.canvas.height = contextSize;
    } else if (!newContext) {
      context.clearRect(0, 0, contextSize, contextSize);
    }
    let hitExtent;
    if (this.renderBuffer_ !== void 0) {
      hitExtent = createEmpty();
      extendCoordinate(hitExtent, coordinate);
      buffer(
        hitExtent,
        resolution * (this.renderBuffer_ + hitTolerance),
        hitExtent
      );
    }
    const indexes = getPixelIndexArray(hitTolerance);
    let builderType;
    function featureCallback(feature2, geometry, declutterMode) {
      const imageData = context.getImageData(
        0,
        0,
        contextSize,
        contextSize
      ).data;
      for (let i2 = 0, ii = indexes.length; i2 < ii; i2++) {
        if (imageData[indexes[i2]] > 0) {
          if (!declutteredFeatures || declutterMode === "none" || builderType !== "Image" && builderType !== "Text" || declutteredFeatures.includes(feature2)) {
            const idx = (indexes[i2] - 3) / 4;
            const x = hitTolerance - idx % contextSize;
            const y = hitTolerance - (idx / contextSize | 0);
            const result2 = callback(feature2, geometry, x * x + y * y);
            if (result2) {
              return result2;
            }
          }
          context.clearRect(0, 0, contextSize, contextSize);
          break;
        }
      }
      return void 0;
    }
    const zs = Object.keys(this.executorsByZIndex_).map(Number);
    zs.sort(ascending);
    let i, j, executors, executor, result;
    for (i = zs.length - 1; i >= 0; --i) {
      const zIndexKey = zs[i].toString();
      executors = this.executorsByZIndex_[zIndexKey];
      for (j = ALL.length - 1; j >= 0; --j) {
        builderType = ALL[j];
        executor = executors[builderType];
        if (executor !== void 0) {
          result = executor.executeHitDetection(
            context,
            transform,
            rotation,
            featureCallback,
            hitExtent
          );
          if (result) {
            return result;
          }
        }
      }
    }
    return void 0;
  }
  getClipCoords(transform) {
    const maxExtent = this.maxExtent_;
    if (!maxExtent) {
      return null;
    }
    const minX = maxExtent[0];
    const minY = maxExtent[1];
    const maxX = maxExtent[2];
    const maxY = maxExtent[3];
    const flatClipCoords = [minX, minY, minX, maxY, maxX, maxY, maxX, minY];
    transform2D(flatClipCoords, 0, 8, 2, transform, flatClipCoords);
    return flatClipCoords;
  }
  isEmpty() {
    return isEmpty$1(this.executorsByZIndex_);
  }
  execute(targetContext, scaledCanvasSize, transform, viewRotation, snapToPixel, builderTypes, declutterTree) {
    const zs = Object.keys(this.executorsByZIndex_).map(Number);
    zs.sort(declutterTree ? descending : ascending);
    builderTypes = builderTypes ? builderTypes : ALL;
    const maxBuilderTypes = ALL.length;
    for (let i = 0, ii = zs.length; i < ii; ++i) {
      const zIndexKey = zs[i].toString();
      const replays = this.executorsByZIndex_[zIndexKey];
      for (let j = 0, jj = builderTypes.length; j < jj; ++j) {
        const builderType = builderTypes[j];
        const replay = replays[builderType];
        if (replay !== void 0) {
          const zIndexContext = declutterTree === null ? void 0 : replay.getZIndexContext();
          const context = zIndexContext ? zIndexContext.getContext() : targetContext;
          const requireClip = this.maxExtent_ && builderType !== "Image" && builderType !== "Text";
          if (requireClip) {
            context.save();
            this.clip(context, transform);
          }
          if (!zIndexContext || builderType === "Text" || builderType === "Image") {
            replay.execute(
              context,
              scaledCanvasSize,
              transform,
              viewRotation,
              snapToPixel,
              declutterTree
            );
          } else {
            zIndexContext.pushFunction(
              (context2) => replay.execute(
                context2,
                scaledCanvasSize,
                transform,
                viewRotation,
                snapToPixel,
                declutterTree
              )
            );
          }
          if (requireClip) {
            context.restore();
          }
          if (zIndexContext) {
            zIndexContext.offset();
            const index2 = zs[i] * maxBuilderTypes + ALL.indexOf(builderType);
            if (!this.deferredZIndexContexts_[index2]) {
              this.deferredZIndexContexts_[index2] = [];
            }
            this.deferredZIndexContexts_[index2].push(zIndexContext);
          }
        }
      }
    }
    this.renderedContext_ = targetContext;
  }
  getDeferredZIndexContexts() {
    return this.deferredZIndexContexts_;
  }
  getRenderedContext() {
    return this.renderedContext_;
  }
  renderDeferred() {
    const deferredZIndexContexts = this.deferredZIndexContexts_;
    const zs = Object.keys(deferredZIndexContexts).map(Number).sort(ascending);
    for (let i = 0, ii = zs.length; i < ii; ++i) {
      deferredZIndexContexts[zs[i]].forEach((zIndexContext) => {
        zIndexContext.draw(this.renderedContext_);
        zIndexContext.clear();
      });
      deferredZIndexContexts[zs[i]].length = 0;
    }
  }
}
const circlePixelIndexArrayCache = {};
function getPixelIndexArray(radius) {
  if (circlePixelIndexArrayCache[radius] !== void 0) {
    return circlePixelIndexArrayCache[radius];
  }
  const size = radius * 2 + 1;
  const maxDistanceSq = radius * radius;
  const distances = new Array(maxDistanceSq + 1);
  for (let i = 0; i <= radius; ++i) {
    for (let j = 0; j <= radius; ++j) {
      const distanceSq = i * i + j * j;
      if (distanceSq > maxDistanceSq) {
        break;
      }
      let distance = distances[distanceSq];
      if (!distance) {
        distance = [];
        distances[distanceSq] = distance;
      }
      distance.push(((radius + i) * size + (radius + j)) * 4 + 3);
      if (i > 0) {
        distance.push(((radius - i) * size + (radius + j)) * 4 + 3);
      }
      if (j > 0) {
        distance.push(((radius + i) * size + (radius - j)) * 4 + 3);
        if (i > 0) {
          distance.push(((radius - i) * size + (radius - j)) * 4 + 3);
        }
      }
    }
  }
  const pixelIndex = [];
  for (let i = 0, ii = distances.length; i < ii; ++i) {
    if (distances[i]) {
      pixelIndex.push(...distances[i]);
    }
  }
  circlePixelIndexArrayCache[radius] = pixelIndex;
  return pixelIndex;
}
const ExecutorGroup$1 = ExecutorGroup;
function toSize(size, dest) {
  if (Array.isArray(size)) {
    return size;
  }
  if (dest === void 0) {
    dest = [size, size];
  } else {
    dest[0] = size;
    dest[1] = size;
  }
  return dest;
}
class ImageStyle {
  constructor(options) {
    this.opacity_ = options.opacity;
    this.rotateWithView_ = options.rotateWithView;
    this.rotation_ = options.rotation;
    this.scale_ = options.scale;
    this.scaleArray_ = toSize(options.scale);
    this.displacement_ = options.displacement;
    this.declutterMode_ = options.declutterMode;
  }
  clone() {
    const scale2 = this.getScale();
    return new ImageStyle({
      opacity: this.getOpacity(),
      scale: Array.isArray(scale2) ? scale2.slice() : scale2,
      rotation: this.getRotation(),
      rotateWithView: this.getRotateWithView(),
      displacement: this.getDisplacement().slice(),
      declutterMode: this.getDeclutterMode()
    });
  }
  getOpacity() {
    return this.opacity_;
  }
  getRotateWithView() {
    return this.rotateWithView_;
  }
  getRotation() {
    return this.rotation_;
  }
  getScale() {
    return this.scale_;
  }
  getScaleArray() {
    return this.scaleArray_;
  }
  getDisplacement() {
    return this.displacement_;
  }
  getDeclutterMode() {
    return this.declutterMode_;
  }
  getAnchor() {
    return abstract();
  }
  getImage(pixelRatio) {
    return abstract();
  }
  getHitDetectionImage() {
    return abstract();
  }
  getPixelRatio(pixelRatio) {
    return 1;
  }
  getImageState() {
    return abstract();
  }
  getImageSize() {
    return abstract();
  }
  getOrigin() {
    return abstract();
  }
  getSize() {
    return abstract();
  }
  setDisplacement(displacement) {
    this.displacement_ = displacement;
  }
  setOpacity(opacity) {
    this.opacity_ = opacity;
  }
  setRotateWithView(rotateWithView) {
    this.rotateWithView_ = rotateWithView;
  }
  setRotation(rotation) {
    this.rotation_ = rotation;
  }
  setScale(scale2) {
    this.scale_ = scale2;
    this.scaleArray_ = toSize(scale2);
  }
  listenImageChange(listener) {
    abstract();
  }
  load() {
    abstract();
  }
  unlistenImageChange(listener) {
    abstract();
  }
  ready() {
    return Promise.resolve();
  }
}
const ImageStyle$1 = ImageStyle;
class RegularShape extends ImageStyle$1 {
  constructor(options) {
    super({
      opacity: 1,
      rotateWithView: options.rotateWithView !== void 0 ? options.rotateWithView : false,
      rotation: options.rotation !== void 0 ? options.rotation : 0,
      scale: options.scale !== void 0 ? options.scale : 1,
      displacement: options.displacement !== void 0 ? options.displacement : [0, 0],
      declutterMode: options.declutterMode
    });
    this.hitDetectionCanvas_ = null;
    this.fill_ = options.fill !== void 0 ? options.fill : null;
    this.origin_ = [0, 0];
    this.points_ = options.points;
    this.radius = options.radius;
    this.radius2_ = options.radius2;
    this.angle_ = options.angle !== void 0 ? options.angle : 0;
    this.stroke_ = options.stroke !== void 0 ? options.stroke : null;
    this.size_;
    this.renderOptions_;
    this.imageState_ = this.fill_ && this.fill_.loading() ? ImageState.LOADING : ImageState.LOADED;
    if (this.imageState_ === ImageState.LOADING) {
      this.ready().then(() => this.imageState_ = ImageState.LOADED);
    }
    this.render();
  }
  clone() {
    const scale2 = this.getScale();
    const style = new RegularShape({
      fill: this.getFill() ? this.getFill().clone() : void 0,
      points: this.getPoints(),
      radius: this.getRadius(),
      radius2: this.getRadius2(),
      angle: this.getAngle(),
      stroke: this.getStroke() ? this.getStroke().clone() : void 0,
      rotation: this.getRotation(),
      rotateWithView: this.getRotateWithView(),
      scale: Array.isArray(scale2) ? scale2.slice() : scale2,
      displacement: this.getDisplacement().slice(),
      declutterMode: this.getDeclutterMode()
    });
    style.setOpacity(this.getOpacity());
    return style;
  }
  getAnchor() {
    const size = this.size_;
    const displacement = this.getDisplacement();
    const scale2 = this.getScaleArray();
    return [
      size[0] / 2 - displacement[0] / scale2[0],
      size[1] / 2 + displacement[1] / scale2[1]
    ];
  }
  getAngle() {
    return this.angle_;
  }
  getFill() {
    return this.fill_;
  }
  setFill(fill) {
    this.fill_ = fill;
    this.render();
  }
  getHitDetectionImage() {
    if (!this.hitDetectionCanvas_) {
      this.hitDetectionCanvas_ = this.createHitDetectionCanvas_(
        this.renderOptions_
      );
    }
    return this.hitDetectionCanvas_;
  }
  getImage(pixelRatio) {
    var _a, _b;
    const fillKey = (_a = this.fill_) == null ? void 0 : _a.getKey();
    const cacheKey = `${pixelRatio},${this.angle_},${this.radius},${this.radius2_},${this.points_},${fillKey}` + Object.values(this.renderOptions_).join(",");
    let image = (_b = shared.get(cacheKey, null, null)) == null ? void 0 : _b.getImage(1);
    if (!image) {
      const renderOptions = this.renderOptions_;
      const size = Math.ceil(renderOptions.size * pixelRatio);
      const context = createCanvasContext2D(size, size);
      this.draw_(renderOptions, context, pixelRatio);
      image = context.canvas;
      shared.set(
        cacheKey,
        null,
        null,
        new IconImage(image, void 0, null, ImageState.LOADED, null)
      );
    }
    return image;
  }
  getPixelRatio(pixelRatio) {
    return pixelRatio;
  }
  getImageSize() {
    return this.size_;
  }
  getImageState() {
    return this.imageState_;
  }
  getOrigin() {
    return this.origin_;
  }
  getPoints() {
    return this.points_;
  }
  getRadius() {
    return this.radius;
  }
  getRadius2() {
    return this.radius2_;
  }
  getSize() {
    return this.size_;
  }
  getStroke() {
    return this.stroke_;
  }
  setStroke(stroke) {
    this.stroke_ = stroke;
    this.render();
  }
  listenImageChange(listener) {
  }
  load() {
  }
  unlistenImageChange(listener) {
  }
  calculateLineJoinSize_(lineJoin, strokeWidth, miterLimit) {
    if (strokeWidth === 0 || this.points_ === Infinity || lineJoin !== "bevel" && lineJoin !== "miter") {
      return strokeWidth;
    }
    let r1 = this.radius;
    let r2 = this.radius2_ === void 0 ? r1 : this.radius2_;
    if (r1 < r2) {
      const tmp = r1;
      r1 = r2;
      r2 = tmp;
    }
    const points = this.radius2_ === void 0 ? this.points_ : this.points_ * 2;
    const alpha = 2 * Math.PI / points;
    const a3 = r2 * Math.sin(alpha);
    const b = Math.sqrt(r2 * r2 - a3 * a3);
    const d = r1 - b;
    const e = Math.sqrt(a3 * a3 + d * d);
    const miterRatio = e / a3;
    if (lineJoin === "miter" && miterRatio <= miterLimit) {
      return miterRatio * strokeWidth;
    }
    const k = strokeWidth / 2 / miterRatio;
    const l = strokeWidth / 2 * (d / e);
    const maxr = Math.sqrt((r1 + k) * (r1 + k) + l * l);
    const bevelAdd = maxr - r1;
    if (this.radius2_ === void 0 || lineJoin === "bevel") {
      return bevelAdd * 2;
    }
    const aa = r1 * Math.sin(alpha);
    const bb = Math.sqrt(r1 * r1 - aa * aa);
    const dd = r2 - bb;
    const ee2 = Math.sqrt(aa * aa + dd * dd);
    const innerMiterRatio = ee2 / aa;
    if (innerMiterRatio <= miterLimit) {
      const innerLength = innerMiterRatio * strokeWidth / 2 - r2 - r1;
      return 2 * Math.max(bevelAdd, innerLength);
    }
    return bevelAdd * 2;
  }
  createRenderOptions() {
    var _a, _b, _c, _d, _e, _f;
    let lineCap = defaultLineCap;
    let lineJoin = defaultLineJoin;
    let miterLimit = 0;
    let lineDash = null;
    let lineDashOffset = 0;
    let strokeStyle;
    let strokeWidth = 0;
    if (this.stroke_) {
      strokeStyle = asColorLike((_a = this.stroke_.getColor()) != null ? _a : defaultStrokeStyle);
      strokeWidth = (_b = this.stroke_.getWidth()) != null ? _b : defaultLineWidth;
      lineDash = this.stroke_.getLineDash();
      lineDashOffset = (_c = this.stroke_.getLineDashOffset()) != null ? _c : 0;
      lineJoin = (_d = this.stroke_.getLineJoin()) != null ? _d : defaultLineJoin;
      lineCap = (_e = this.stroke_.getLineCap()) != null ? _e : defaultLineCap;
      miterLimit = (_f = this.stroke_.getMiterLimit()) != null ? _f : defaultMiterLimit;
    }
    const add2 = this.calculateLineJoinSize_(lineJoin, strokeWidth, miterLimit);
    const maxRadius = Math.max(this.radius, this.radius2_ || 0);
    const size = Math.ceil(2 * maxRadius + add2);
    return {
      strokeStyle,
      strokeWidth,
      size,
      lineCap,
      lineDash,
      lineDashOffset,
      lineJoin,
      miterLimit
    };
  }
  render() {
    this.renderOptions_ = this.createRenderOptions();
    const size = this.renderOptions_.size;
    this.hitDetectionCanvas_ = null;
    this.size_ = [size, size];
  }
  draw_(renderOptions, context, pixelRatio) {
    context.scale(pixelRatio, pixelRatio);
    context.translate(renderOptions.size / 2, renderOptions.size / 2);
    this.createPath_(context);
    if (this.fill_) {
      let color = this.fill_.getColor();
      if (color === null) {
        color = defaultFillStyle;
      }
      context.fillStyle = asColorLike(color);
      context.fill();
    }
    if (renderOptions.strokeStyle) {
      context.strokeStyle = renderOptions.strokeStyle;
      context.lineWidth = renderOptions.strokeWidth;
      if (renderOptions.lineDash) {
        context.setLineDash(renderOptions.lineDash);
        context.lineDashOffset = renderOptions.lineDashOffset;
      }
      context.lineCap = renderOptions.lineCap;
      context.lineJoin = renderOptions.lineJoin;
      context.miterLimit = renderOptions.miterLimit;
      context.stroke();
    }
  }
  createHitDetectionCanvas_(renderOptions) {
    let context;
    if (this.fill_) {
      let color = this.fill_.getColor();
      let opacity = 0;
      if (typeof color === "string") {
        color = asArray(color);
      }
      if (color === null) {
        opacity = 1;
      } else if (Array.isArray(color)) {
        opacity = color.length === 4 ? color[3] : 1;
      }
      if (opacity === 0) {
        context = createCanvasContext2D(renderOptions.size, renderOptions.size);
        this.drawHitDetectionCanvas_(renderOptions, context);
      }
    }
    return context ? context.canvas : this.getImage(1);
  }
  createPath_(context) {
    let points = this.points_;
    const radius = this.radius;
    if (points === Infinity) {
      context.arc(0, 0, radius, 0, 2 * Math.PI);
    } else {
      const radius2 = this.radius2_ === void 0 ? radius : this.radius2_;
      if (this.radius2_ !== void 0) {
        points *= 2;
      }
      const startAngle = this.angle_ - Math.PI / 2;
      const step = 2 * Math.PI / points;
      for (let i = 0; i < points; i++) {
        const angle0 = startAngle + i * step;
        const radiusC = i % 2 === 0 ? radius : radius2;
        context.lineTo(radiusC * Math.cos(angle0), radiusC * Math.sin(angle0));
      }
      context.closePath();
    }
  }
  drawHitDetectionCanvas_(renderOptions, context) {
    context.translate(renderOptions.size / 2, renderOptions.size / 2);
    this.createPath_(context);
    context.fillStyle = defaultFillStyle;
    context.fill();
    if (renderOptions.strokeStyle) {
      context.strokeStyle = renderOptions.strokeStyle;
      context.lineWidth = renderOptions.strokeWidth;
      if (renderOptions.lineDash) {
        context.setLineDash(renderOptions.lineDash);
        context.lineDashOffset = renderOptions.lineDashOffset;
      }
      context.lineJoin = renderOptions.lineJoin;
      context.miterLimit = renderOptions.miterLimit;
      context.stroke();
    }
  }
  ready() {
    return this.fill_ ? this.fill_.ready() : Promise.resolve();
  }
}
const RegularShape$1 = RegularShape;
class CircleStyle extends RegularShape$1 {
  constructor(options) {
    options = options ? options : { radius: 5 };
    super({
      points: Infinity,
      fill: options.fill,
      radius: options.radius,
      stroke: options.stroke,
      scale: options.scale !== void 0 ? options.scale : 1,
      rotation: options.rotation !== void 0 ? options.rotation : 0,
      rotateWithView: options.rotateWithView !== void 0 ? options.rotateWithView : false,
      displacement: options.displacement !== void 0 ? options.displacement : [0, 0],
      declutterMode: options.declutterMode
    });
  }
  clone() {
    const scale2 = this.getScale();
    const style = new CircleStyle({
      fill: this.getFill() ? this.getFill().clone() : void 0,
      stroke: this.getStroke() ? this.getStroke().clone() : void 0,
      radius: this.getRadius(),
      scale: Array.isArray(scale2) ? scale2.slice() : scale2,
      rotation: this.getRotation(),
      rotateWithView: this.getRotateWithView(),
      displacement: this.getDisplacement().slice(),
      declutterMode: this.getDeclutterMode()
    });
    style.setOpacity(this.getOpacity());
    return style;
  }
  setRadius(radius) {
    this.radius = radius;
    this.render();
  }
}
const Circle = CircleStyle;
class Fill {
  constructor(options) {
    options = options || {};
    this.patternImage_ = null;
    this.color_ = null;
    if (options.color !== void 0) {
      this.setColor(options.color);
    }
  }
  clone() {
    const color = this.getColor();
    return new Fill({
      color: Array.isArray(color) ? color.slice() : color || void 0
    });
  }
  getColor() {
    return this.color_;
  }
  setColor(color) {
    if (color !== null && typeof color === "object" && "src" in color) {
      const patternImage = get(
        null,
        color.src,
        "anonymous",
        void 0,
        color.offset ? null : color.color ? color.color : null,
        !(color.offset && color.size)
      );
      patternImage.ready().then(() => {
        this.patternImage_ = null;
      });
      if (patternImage.getImageState() === ImageState.IDLE) {
        patternImage.load();
      }
      if (patternImage.getImageState() === ImageState.LOADING) {
        this.patternImage_ = patternImage;
      }
    }
    this.color_ = color;
  }
  getKey() {
    const fill = this.getColor();
    if (!fill) {
      return "";
    }
    return fill instanceof CanvasPattern || fill instanceof CanvasGradient ? getUid(fill) : typeof fill === "object" && "src" in fill ? fill.src + ":" + fill.offset : asArray(fill).toString();
  }
  loading() {
    return !!this.patternImage_;
  }
  ready() {
    return this.patternImage_ ? this.patternImage_.ready() : Promise.resolve();
  }
}
const Fill$1 = Fill;
function calculateScale(width, height, wantedWidth, wantedHeight) {
  if (wantedWidth !== void 0 && wantedHeight !== void 0) {
    return [wantedWidth / width, wantedHeight / height];
  }
  if (wantedWidth !== void 0) {
    return wantedWidth / width;
  }
  if (wantedHeight !== void 0) {
    return wantedHeight / height;
  }
  return 1;
}
class Icon extends ImageStyle$1 {
  constructor(options) {
    options = options || {};
    const opacity = options.opacity !== void 0 ? options.opacity : 1;
    const rotation = options.rotation !== void 0 ? options.rotation : 0;
    const scale2 = options.scale !== void 0 ? options.scale : 1;
    const rotateWithView = options.rotateWithView !== void 0 ? options.rotateWithView : false;
    super({
      opacity,
      rotation,
      scale: scale2,
      displacement: options.displacement !== void 0 ? options.displacement : [0, 0],
      rotateWithView,
      declutterMode: options.declutterMode
    });
    this.anchor_ = options.anchor !== void 0 ? options.anchor : [0.5, 0.5];
    this.normalizedAnchor_ = null;
    this.anchorOrigin_ = options.anchorOrigin !== void 0 ? options.anchorOrigin : "top-left";
    this.anchorXUnits_ = options.anchorXUnits !== void 0 ? options.anchorXUnits : "fraction";
    this.anchorYUnits_ = options.anchorYUnits !== void 0 ? options.anchorYUnits : "fraction";
    this.crossOrigin_ = options.crossOrigin !== void 0 ? options.crossOrigin : null;
    const image = options.img !== void 0 ? options.img : null;
    let cacheKey = options.src;
    assert(
      !(cacheKey !== void 0 && image),
      "`image` and `src` cannot be provided at the same time"
    );
    if ((cacheKey === void 0 || cacheKey.length === 0) && image) {
      cacheKey = image.src || getUid(image);
    }
    assert(
      cacheKey !== void 0 && cacheKey.length > 0,
      "A defined and non-empty `src` or `image` must be provided"
    );
    assert(
      !((options.width !== void 0 || options.height !== void 0) && options.scale !== void 0),
      "`width` or `height` cannot be provided together with `scale`"
    );
    let imageState;
    if (options.src !== void 0) {
      imageState = ImageState.IDLE;
    } else if (image !== void 0) {
      if ("complete" in image) {
        if (image.complete) {
          imageState = image.src ? ImageState.LOADED : ImageState.IDLE;
        } else {
          imageState = ImageState.LOADING;
        }
      } else {
        imageState = ImageState.LOADED;
      }
    }
    this.color_ = options.color !== void 0 ? asArray(options.color) : null;
    this.iconImage_ = get(
      image,
      cacheKey,
      this.crossOrigin_,
      imageState,
      this.color_
    );
    this.offset_ = options.offset !== void 0 ? options.offset : [0, 0];
    this.offsetOrigin_ = options.offsetOrigin !== void 0 ? options.offsetOrigin : "top-left";
    this.origin_ = null;
    this.size_ = options.size !== void 0 ? options.size : null;
    this.initialOptions_;
    if (options.width !== void 0 || options.height !== void 0) {
      let width, height;
      if (options.size) {
        [width, height] = options.size;
      } else {
        const image2 = this.getImage(1);
        if (image2.width && image2.height) {
          width = image2.width;
          height = image2.height;
        } else if (image2 instanceof HTMLImageElement) {
          this.initialOptions_ = options;
          const onload = () => {
            this.unlistenImageChange(onload);
            if (!this.initialOptions_) {
              return;
            }
            const imageSize = this.iconImage_.getSize();
            this.setScale(
              calculateScale(
                imageSize[0],
                imageSize[1],
                options.width,
                options.height
              )
            );
          };
          this.listenImageChange(onload);
          return;
        }
      }
      if (width !== void 0) {
        this.setScale(
          calculateScale(width, height, options.width, options.height)
        );
      }
    }
  }
  clone() {
    let scale2, width, height;
    if (this.initialOptions_) {
      width = this.initialOptions_.width;
      height = this.initialOptions_.height;
    } else {
      scale2 = this.getScale();
      scale2 = Array.isArray(scale2) ? scale2.slice() : scale2;
    }
    return new Icon({
      anchor: this.anchor_.slice(),
      anchorOrigin: this.anchorOrigin_,
      anchorXUnits: this.anchorXUnits_,
      anchorYUnits: this.anchorYUnits_,
      color: this.color_ && this.color_.slice ? this.color_.slice() : this.color_ || void 0,
      crossOrigin: this.crossOrigin_,
      offset: this.offset_.slice(),
      offsetOrigin: this.offsetOrigin_,
      opacity: this.getOpacity(),
      rotateWithView: this.getRotateWithView(),
      rotation: this.getRotation(),
      scale: scale2,
      width,
      height,
      size: this.size_ !== null ? this.size_.slice() : void 0,
      src: this.getSrc(),
      displacement: this.getDisplacement().slice(),
      declutterMode: this.getDeclutterMode()
    });
  }
  getAnchor() {
    let anchor = this.normalizedAnchor_;
    if (!anchor) {
      anchor = this.anchor_;
      const size = this.getSize();
      if (this.anchorXUnits_ == "fraction" || this.anchorYUnits_ == "fraction") {
        if (!size) {
          return null;
        }
        anchor = this.anchor_.slice();
        if (this.anchorXUnits_ == "fraction") {
          anchor[0] *= size[0];
        }
        if (this.anchorYUnits_ == "fraction") {
          anchor[1] *= size[1];
        }
      }
      if (this.anchorOrigin_ != "top-left") {
        if (!size) {
          return null;
        }
        if (anchor === this.anchor_) {
          anchor = this.anchor_.slice();
        }
        if (this.anchorOrigin_ == "top-right" || this.anchorOrigin_ == "bottom-right") {
          anchor[0] = -anchor[0] + size[0];
        }
        if (this.anchorOrigin_ == "bottom-left" || this.anchorOrigin_ == "bottom-right") {
          anchor[1] = -anchor[1] + size[1];
        }
      }
      this.normalizedAnchor_ = anchor;
    }
    const displacement = this.getDisplacement();
    const scale2 = this.getScaleArray();
    return [
      anchor[0] - displacement[0] / scale2[0],
      anchor[1] + displacement[1] / scale2[1]
    ];
  }
  setAnchor(anchor) {
    this.anchor_ = anchor;
    this.normalizedAnchor_ = null;
  }
  getColor() {
    return this.color_;
  }
  getImage(pixelRatio) {
    return this.iconImage_.getImage(pixelRatio);
  }
  getPixelRatio(pixelRatio) {
    return this.iconImage_.getPixelRatio(pixelRatio);
  }
  getImageSize() {
    return this.iconImage_.getSize();
  }
  getImageState() {
    return this.iconImage_.getImageState();
  }
  getHitDetectionImage() {
    return this.iconImage_.getHitDetectionImage();
  }
  getOrigin() {
    if (this.origin_) {
      return this.origin_;
    }
    let offset = this.offset_;
    if (this.offsetOrigin_ != "top-left") {
      const size = this.getSize();
      const iconImageSize = this.iconImage_.getSize();
      if (!size || !iconImageSize) {
        return null;
      }
      offset = offset.slice();
      if (this.offsetOrigin_ == "top-right" || this.offsetOrigin_ == "bottom-right") {
        offset[0] = iconImageSize[0] - size[0] - offset[0];
      }
      if (this.offsetOrigin_ == "bottom-left" || this.offsetOrigin_ == "bottom-right") {
        offset[1] = iconImageSize[1] - size[1] - offset[1];
      }
    }
    this.origin_ = offset;
    return this.origin_;
  }
  getSrc() {
    return this.iconImage_.getSrc();
  }
  getSize() {
    return !this.size_ ? this.iconImage_.getSize() : this.size_;
  }
  getWidth() {
    const scale2 = this.getScaleArray();
    if (this.size_) {
      return this.size_[0] * scale2[0];
    }
    if (this.iconImage_.getImageState() == ImageState.LOADED) {
      return this.iconImage_.getSize()[0] * scale2[0];
    }
    return void 0;
  }
  getHeight() {
    const scale2 = this.getScaleArray();
    if (this.size_) {
      return this.size_[1] * scale2[1];
    }
    if (this.iconImage_.getImageState() == ImageState.LOADED) {
      return this.iconImage_.getSize()[1] * scale2[1];
    }
    return void 0;
  }
  setScale(scale2) {
    delete this.initialOptions_;
    super.setScale(scale2);
  }
  listenImageChange(listener) {
    this.iconImage_.addEventListener(EventType.CHANGE, listener);
  }
  load() {
    this.iconImage_.load();
  }
  unlistenImageChange(listener) {
    this.iconImage_.removeEventListener(EventType.CHANGE, listener);
  }
  ready() {
    return this.iconImage_.ready();
  }
}
const Icon$1 = Icon;
class Stroke {
  constructor(options) {
    options = options || {};
    this.color_ = options.color !== void 0 ? options.color : null;
    this.lineCap_ = options.lineCap;
    this.lineDash_ = options.lineDash !== void 0 ? options.lineDash : null;
    this.lineDashOffset_ = options.lineDashOffset;
    this.lineJoin_ = options.lineJoin;
    this.miterLimit_ = options.miterLimit;
    this.width_ = options.width;
  }
  clone() {
    const color = this.getColor();
    return new Stroke({
      color: Array.isArray(color) ? color.slice() : color || void 0,
      lineCap: this.getLineCap(),
      lineDash: this.getLineDash() ? this.getLineDash().slice() : void 0,
      lineDashOffset: this.getLineDashOffset(),
      lineJoin: this.getLineJoin(),
      miterLimit: this.getMiterLimit(),
      width: this.getWidth()
    });
  }
  getColor() {
    return this.color_;
  }
  getLineCap() {
    return this.lineCap_;
  }
  getLineDash() {
    return this.lineDash_;
  }
  getLineDashOffset() {
    return this.lineDashOffset_;
  }
  getLineJoin() {
    return this.lineJoin_;
  }
  getMiterLimit() {
    return this.miterLimit_;
  }
  getWidth() {
    return this.width_;
  }
  setColor(color) {
    this.color_ = color;
  }
  setLineCap(lineCap) {
    this.lineCap_ = lineCap;
  }
  setLineDash(lineDash) {
    this.lineDash_ = lineDash;
  }
  setLineDashOffset(lineDashOffset) {
    this.lineDashOffset_ = lineDashOffset;
  }
  setLineJoin(lineJoin) {
    this.lineJoin_ = lineJoin;
  }
  setMiterLimit(miterLimit) {
    this.miterLimit_ = miterLimit;
  }
  setWidth(width) {
    this.width_ = width;
  }
}
const Stroke$1 = Stroke;
class Style {
  constructor(options) {
    options = options || {};
    this.geometry_ = null;
    this.geometryFunction_ = defaultGeometryFunction;
    if (options.geometry !== void 0) {
      this.setGeometry(options.geometry);
    }
    this.fill_ = options.fill !== void 0 ? options.fill : null;
    this.image_ = options.image !== void 0 ? options.image : null;
    this.renderer_ = options.renderer !== void 0 ? options.renderer : null;
    this.hitDetectionRenderer_ = options.hitDetectionRenderer !== void 0 ? options.hitDetectionRenderer : null;
    this.stroke_ = options.stroke !== void 0 ? options.stroke : null;
    this.text_ = options.text !== void 0 ? options.text : null;
    this.zIndex_ = options.zIndex;
  }
  clone() {
    var _a;
    let geometry = this.getGeometry();
    if (geometry && typeof geometry === "object") {
      geometry = geometry.clone();
    }
    return new Style({
      geometry: geometry != null ? geometry : void 0,
      fill: this.getFill() ? this.getFill().clone() : void 0,
      image: this.getImage() ? this.getImage().clone() : void 0,
      renderer: (_a = this.getRenderer()) != null ? _a : void 0,
      stroke: this.getStroke() ? this.getStroke().clone() : void 0,
      text: this.getText() ? this.getText().clone() : void 0,
      zIndex: this.getZIndex()
    });
  }
  getRenderer() {
    return this.renderer_;
  }
  setRenderer(renderer) {
    this.renderer_ = renderer;
  }
  setHitDetectionRenderer(renderer) {
    this.hitDetectionRenderer_ = renderer;
  }
  getHitDetectionRenderer() {
    return this.hitDetectionRenderer_;
  }
  getGeometry() {
    return this.geometry_;
  }
  getGeometryFunction() {
    return this.geometryFunction_;
  }
  getFill() {
    return this.fill_;
  }
  setFill(fill) {
    this.fill_ = fill;
  }
  getImage() {
    return this.image_;
  }
  setImage(image) {
    this.image_ = image;
  }
  getStroke() {
    return this.stroke_;
  }
  setStroke(stroke) {
    this.stroke_ = stroke;
  }
  getText() {
    return this.text_;
  }
  setText(text) {
    this.text_ = text;
  }
  getZIndex() {
    return this.zIndex_;
  }
  setGeometry(geometry) {
    if (typeof geometry === "function") {
      this.geometryFunction_ = geometry;
    } else if (typeof geometry === "string") {
      this.geometryFunction_ = function(feature2) {
        return feature2.get(geometry);
      };
    } else if (!geometry) {
      this.geometryFunction_ = defaultGeometryFunction;
    } else if (geometry !== void 0) {
      this.geometryFunction_ = function() {
        return geometry;
      };
    }
    this.geometry_ = geometry;
  }
  setZIndex(zIndex) {
    this.zIndex_ = zIndex;
  }
}
function toFunction(obj) {
  let styleFunction;
  if (typeof obj === "function") {
    styleFunction = obj;
  } else {
    let styles;
    if (Array.isArray(obj)) {
      styles = obj;
    } else {
      assert(
        typeof obj.getZIndex === "function",
        "Expected an `Style` or an array of `Style`"
      );
      const style = obj;
      styles = [style];
    }
    styleFunction = function() {
      return styles;
    };
  }
  return styleFunction;
}
let defaultStyles = null;
function createDefaultStyle(feature2, resolution) {
  if (!defaultStyles) {
    const fill = new Fill$1({
      color: "rgba(255,255,255,0.4)"
    });
    const stroke = new Stroke$1({
      color: "#3399CC",
      width: 1.25
    });
    defaultStyles = [
      new Style({
        image: new Circle({
          fill,
          stroke,
          radius: 5
        }),
        fill,
        stroke
      })
    ];
  }
  return defaultStyles;
}
function createEditingStyle() {
  const styles = {};
  const white = [255, 255, 255, 1];
  const blue = [0, 153, 255, 1];
  const width = 3;
  styles["Polygon"] = [
    new Style({
      fill: new Fill$1({
        color: [255, 255, 255, 0.5]
      })
    })
  ];
  styles["MultiPolygon"] = styles["Polygon"];
  styles["LineString"] = [
    new Style({
      stroke: new Stroke$1({
        color: white,
        width: width + 2
      })
    }),
    new Style({
      stroke: new Stroke$1({
        color: blue,
        width
      })
    })
  ];
  styles["MultiLineString"] = styles["LineString"];
  styles["Circle"] = styles["Polygon"].concat(styles["LineString"]);
  styles["Point"] = [
    new Style({
      image: new Circle({
        radius: width * 2,
        fill: new Fill$1({
          color: blue
        }),
        stroke: new Stroke$1({
          color: white,
          width: width / 2
        })
      }),
      zIndex: Infinity
    })
  ];
  styles["MultiPoint"] = styles["Point"];
  styles["GeometryCollection"] = styles["Polygon"].concat(
    styles["LineString"],
    styles["Point"]
  );
  return styles;
}
function defaultGeometryFunction(feature2) {
  return feature2.getGeometry();
}
const DEFAULT_FILL_COLOR = "#333";
class Text {
  constructor(options) {
    options = options || {};
    this.font_ = options.font;
    this.rotation_ = options.rotation;
    this.rotateWithView_ = options.rotateWithView;
    this.keepUpright_ = options.keepUpright;
    this.scale_ = options.scale;
    this.scaleArray_ = toSize(options.scale !== void 0 ? options.scale : 1);
    this.text_ = options.text;
    this.textAlign_ = options.textAlign;
    this.justify_ = options.justify;
    this.repeat_ = options.repeat;
    this.textBaseline_ = options.textBaseline;
    this.fill_ = options.fill !== void 0 ? options.fill : new Fill$1({ color: DEFAULT_FILL_COLOR });
    this.maxAngle_ = options.maxAngle !== void 0 ? options.maxAngle : Math.PI / 4;
    this.placement_ = options.placement !== void 0 ? options.placement : "point";
    this.overflow_ = !!options.overflow;
    this.stroke_ = options.stroke !== void 0 ? options.stroke : null;
    this.offsetX_ = options.offsetX !== void 0 ? options.offsetX : 0;
    this.offsetY_ = options.offsetY !== void 0 ? options.offsetY : 0;
    this.backgroundFill_ = options.backgroundFill ? options.backgroundFill : null;
    this.backgroundStroke_ = options.backgroundStroke ? options.backgroundStroke : null;
    this.padding_ = options.padding === void 0 ? null : options.padding;
    this.declutterMode_ = options.declutterMode;
  }
  clone() {
    const scale2 = this.getScale();
    return new Text({
      font: this.getFont(),
      placement: this.getPlacement(),
      repeat: this.getRepeat(),
      maxAngle: this.getMaxAngle(),
      overflow: this.getOverflow(),
      rotation: this.getRotation(),
      rotateWithView: this.getRotateWithView(),
      keepUpright: this.getKeepUpright(),
      scale: Array.isArray(scale2) ? scale2.slice() : scale2,
      text: this.getText(),
      textAlign: this.getTextAlign(),
      justify: this.getJustify(),
      textBaseline: this.getTextBaseline(),
      fill: this.getFill() ? this.getFill().clone() : void 0,
      stroke: this.getStroke() ? this.getStroke().clone() : void 0,
      offsetX: this.getOffsetX(),
      offsetY: this.getOffsetY(),
      backgroundFill: this.getBackgroundFill() ? this.getBackgroundFill().clone() : void 0,
      backgroundStroke: this.getBackgroundStroke() ? this.getBackgroundStroke().clone() : void 0,
      padding: this.getPadding() || void 0,
      declutterMode: this.getDeclutterMode()
    });
  }
  getOverflow() {
    return this.overflow_;
  }
  getFont() {
    return this.font_;
  }
  getMaxAngle() {
    return this.maxAngle_;
  }
  getPlacement() {
    return this.placement_;
  }
  getRepeat() {
    return this.repeat_;
  }
  getOffsetX() {
    return this.offsetX_;
  }
  getOffsetY() {
    return this.offsetY_;
  }
  getFill() {
    return this.fill_;
  }
  getRotateWithView() {
    return this.rotateWithView_;
  }
  getKeepUpright() {
    return this.keepUpright_;
  }
  getRotation() {
    return this.rotation_;
  }
  getScale() {
    return this.scale_;
  }
  getScaleArray() {
    return this.scaleArray_;
  }
  getStroke() {
    return this.stroke_;
  }
  getText() {
    return this.text_;
  }
  getTextAlign() {
    return this.textAlign_;
  }
  getJustify() {
    return this.justify_;
  }
  getTextBaseline() {
    return this.textBaseline_;
  }
  getBackgroundFill() {
    return this.backgroundFill_;
  }
  getBackgroundStroke() {
    return this.backgroundStroke_;
  }
  getPadding() {
    return this.padding_;
  }
  getDeclutterMode() {
    return this.declutterMode_;
  }
  setOverflow(overflow) {
    this.overflow_ = overflow;
  }
  setFont(font) {
    this.font_ = font;
  }
  setMaxAngle(maxAngle) {
    this.maxAngle_ = maxAngle;
  }
  setOffsetX(offsetX) {
    this.offsetX_ = offsetX;
  }
  setOffsetY(offsetY) {
    this.offsetY_ = offsetY;
  }
  setPlacement(placement) {
    this.placement_ = placement;
  }
  setRepeat(repeat) {
    this.repeat_ = repeat;
  }
  setRotateWithView(rotateWithView) {
    this.rotateWithView_ = rotateWithView;
  }
  setKeepUpright(keepUpright) {
    this.keepUpright_ = keepUpright;
  }
  setFill(fill) {
    this.fill_ = fill;
  }
  setRotation(rotation) {
    this.rotation_ = rotation;
  }
  setScale(scale2) {
    this.scale_ = scale2;
    this.scaleArray_ = toSize(scale2 !== void 0 ? scale2 : 1);
  }
  setStroke(stroke) {
    this.stroke_ = stroke;
  }
  setText(text) {
    this.text_ = text;
  }
  setTextAlign(textAlign) {
    this.textAlign_ = textAlign;
  }
  setJustify(justify) {
    this.justify_ = justify;
  }
  setTextBaseline(textBaseline) {
    this.textBaseline_ = textBaseline;
  }
  setBackgroundFill(fill) {
    this.backgroundFill_ = fill;
  }
  setBackgroundStroke(stroke) {
    this.backgroundStroke_ = stroke;
  }
  setPadding(padding) {
    this.padding_ = padding;
  }
}
const Text$1 = Text;
class CanvasImmediateRenderer extends VectorContext$1 {
  constructor(context, pixelRatio, extent, transform, viewRotation, squaredTolerance, userTransform) {
    super();
    this.context_ = context;
    this.pixelRatio_ = pixelRatio;
    this.extent_ = extent;
    this.transform_ = transform;
    this.transformRotation_ = transform ? toFixed(Math.atan2(transform[1], transform[0]), 10) : 0;
    this.viewRotation_ = viewRotation;
    this.squaredTolerance_ = squaredTolerance;
    this.userTransform_ = userTransform;
    this.contextFillState_ = null;
    this.contextStrokeState_ = null;
    this.contextTextState_ = null;
    this.fillState_ = null;
    this.strokeState_ = null;
    this.image_ = null;
    this.imageAnchorX_ = 0;
    this.imageAnchorY_ = 0;
    this.imageHeight_ = 0;
    this.imageOpacity_ = 0;
    this.imageOriginX_ = 0;
    this.imageOriginY_ = 0;
    this.imageRotateWithView_ = false;
    this.imageRotation_ = 0;
    this.imageScale_ = [0, 0];
    this.imageWidth_ = 0;
    this.text_ = "";
    this.textOffsetX_ = 0;
    this.textOffsetY_ = 0;
    this.textRotateWithView_ = false;
    this.textRotation_ = 0;
    this.textScale_ = [0, 0];
    this.textFillState_ = null;
    this.textStrokeState_ = null;
    this.textState_ = null;
    this.pixelCoordinates_ = [];
    this.tmpLocalTransform_ = create();
  }
  drawImages_(flatCoordinates, offset, end, stride) {
    if (!this.image_) {
      return;
    }
    const pixelCoordinates = transform2D(
      flatCoordinates,
      offset,
      end,
      stride,
      this.transform_,
      this.pixelCoordinates_
    );
    const context = this.context_;
    const localTransform = this.tmpLocalTransform_;
    const alpha = context.globalAlpha;
    if (this.imageOpacity_ != 1) {
      context.globalAlpha = alpha * this.imageOpacity_;
    }
    let rotation = this.imageRotation_;
    if (this.transformRotation_ === 0) {
      rotation -= this.viewRotation_;
    }
    if (this.imageRotateWithView_) {
      rotation += this.viewRotation_;
    }
    for (let i = 0, ii = pixelCoordinates.length; i < ii; i += 2) {
      const x = pixelCoordinates[i] - this.imageAnchorX_;
      const y = pixelCoordinates[i + 1] - this.imageAnchorY_;
      if (rotation !== 0 || this.imageScale_[0] != 1 || this.imageScale_[1] != 1) {
        const centerX = x + this.imageAnchorX_;
        const centerY = y + this.imageAnchorY_;
        compose(
          localTransform,
          centerX,
          centerY,
          1,
          1,
          rotation,
          -centerX,
          -centerY
        );
        context.save();
        context.transform.apply(context, localTransform);
        context.translate(centerX, centerY);
        context.scale(this.imageScale_[0], this.imageScale_[1]);
        context.drawImage(
          this.image_,
          this.imageOriginX_,
          this.imageOriginY_,
          this.imageWidth_,
          this.imageHeight_,
          -this.imageAnchorX_,
          -this.imageAnchorY_,
          this.imageWidth_,
          this.imageHeight_
        );
        context.restore();
      } else {
        context.drawImage(
          this.image_,
          this.imageOriginX_,
          this.imageOriginY_,
          this.imageWidth_,
          this.imageHeight_,
          x,
          y,
          this.imageWidth_,
          this.imageHeight_
        );
      }
    }
    if (this.imageOpacity_ != 1) {
      context.globalAlpha = alpha;
    }
  }
  drawText_(flatCoordinates, offset, end, stride) {
    if (!this.textState_ || this.text_ === "") {
      return;
    }
    if (this.textFillState_) {
      this.setContextFillState_(this.textFillState_);
    }
    if (this.textStrokeState_) {
      this.setContextStrokeState_(this.textStrokeState_);
    }
    this.setContextTextState_(this.textState_);
    const pixelCoordinates = transform2D(
      flatCoordinates,
      offset,
      end,
      stride,
      this.transform_,
      this.pixelCoordinates_
    );
    const context = this.context_;
    let rotation = this.textRotation_;
    if (this.transformRotation_ === 0) {
      rotation -= this.viewRotation_;
    }
    if (this.textRotateWithView_) {
      rotation += this.viewRotation_;
    }
    for (; offset < end; offset += stride) {
      const x = pixelCoordinates[offset] + this.textOffsetX_;
      const y = pixelCoordinates[offset + 1] + this.textOffsetY_;
      if (rotation !== 0 || this.textScale_[0] != 1 || this.textScale_[1] != 1) {
        context.save();
        context.translate(x - this.textOffsetX_, y - this.textOffsetY_);
        context.rotate(rotation);
        context.translate(this.textOffsetX_, this.textOffsetY_);
        context.scale(this.textScale_[0], this.textScale_[1]);
        if (this.textStrokeState_) {
          context.strokeText(this.text_, 0, 0);
        }
        if (this.textFillState_) {
          context.fillText(this.text_, 0, 0);
        }
        context.restore();
      } else {
        if (this.textStrokeState_) {
          context.strokeText(this.text_, x, y);
        }
        if (this.textFillState_) {
          context.fillText(this.text_, x, y);
        }
      }
    }
  }
  moveToLineTo_(flatCoordinates, offset, end, stride, close) {
    const context = this.context_;
    const pixelCoordinates = transform2D(
      flatCoordinates,
      offset,
      end,
      stride,
      this.transform_,
      this.pixelCoordinates_
    );
    context.moveTo(pixelCoordinates[0], pixelCoordinates[1]);
    let length = pixelCoordinates.length;
    if (close) {
      length -= 2;
    }
    for (let i = 2; i < length; i += 2) {
      context.lineTo(pixelCoordinates[i], pixelCoordinates[i + 1]);
    }
    if (close) {
      context.closePath();
    }
    return end;
  }
  drawRings_(flatCoordinates, offset, ends, stride) {
    for (let i = 0, ii = ends.length; i < ii; ++i) {
      offset = this.moveToLineTo_(
        flatCoordinates,
        offset,
        ends[i],
        stride,
        true
      );
    }
    return offset;
  }
  drawCircle(geometry) {
    if (this.squaredTolerance_) {
      geometry = geometry.simplifyTransformed(
        this.squaredTolerance_,
        this.userTransform_
      );
    }
    if (!intersects$1(this.extent_, geometry.getExtent())) {
      return;
    }
    if (this.fillState_ || this.strokeState_) {
      if (this.fillState_) {
        this.setContextFillState_(this.fillState_);
      }
      if (this.strokeState_) {
        this.setContextStrokeState_(this.strokeState_);
      }
      const pixelCoordinates = transformGeom2D(
        geometry,
        this.transform_,
        this.pixelCoordinates_
      );
      const dx = pixelCoordinates[2] - pixelCoordinates[0];
      const dy = pixelCoordinates[3] - pixelCoordinates[1];
      const radius = Math.sqrt(dx * dx + dy * dy);
      const context = this.context_;
      context.beginPath();
      context.arc(
        pixelCoordinates[0],
        pixelCoordinates[1],
        radius,
        0,
        2 * Math.PI
      );
      if (this.fillState_) {
        context.fill();
      }
      if (this.strokeState_) {
        context.stroke();
      }
    }
    if (this.text_ !== "") {
      this.drawText_(geometry.getCenter(), 0, 2, 2);
    }
  }
  setStyle(style) {
    this.setFillStrokeStyle(style.getFill(), style.getStroke());
    this.setImageStyle(style.getImage());
    this.setTextStyle(style.getText());
  }
  setTransform(transform) {
    this.transform_ = transform;
  }
  drawGeometry(geometry) {
    const type = geometry.getType();
    switch (type) {
      case "Point":
        this.drawPoint(
          geometry
        );
        break;
      case "LineString":
        this.drawLineString(
          geometry
        );
        break;
      case "Polygon":
        this.drawPolygon(
          geometry
        );
        break;
      case "MultiPoint":
        this.drawMultiPoint(
          geometry
        );
        break;
      case "MultiLineString":
        this.drawMultiLineString(
          geometry
        );
        break;
      case "MultiPolygon":
        this.drawMultiPolygon(
          geometry
        );
        break;
      case "GeometryCollection":
        this.drawGeometryCollection(
          geometry
        );
        break;
      case "Circle":
        this.drawCircle(
          geometry
        );
        break;
    }
  }
  drawFeature(feature2, style) {
    const geometry = style.getGeometryFunction()(feature2);
    if (!geometry) {
      return;
    }
    this.setStyle(style);
    this.drawGeometry(geometry);
  }
  drawGeometryCollection(geometry) {
    const geometries = geometry.getGeometriesArray();
    for (let i = 0, ii = geometries.length; i < ii; ++i) {
      this.drawGeometry(geometries[i]);
    }
  }
  drawPoint(geometry) {
    if (this.squaredTolerance_) {
      geometry = geometry.simplifyTransformed(
        this.squaredTolerance_,
        this.userTransform_
      );
    }
    const flatCoordinates = geometry.getFlatCoordinates();
    const stride = geometry.getStride();
    if (this.image_) {
      this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);
    }
    if (this.text_ !== "") {
      this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);
    }
  }
  drawMultiPoint(geometry) {
    if (this.squaredTolerance_) {
      geometry = geometry.simplifyTransformed(
        this.squaredTolerance_,
        this.userTransform_
      );
    }
    const flatCoordinates = geometry.getFlatCoordinates();
    const stride = geometry.getStride();
    if (this.image_) {
      this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);
    }
    if (this.text_ !== "") {
      this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);
    }
  }
  drawLineString(geometry) {
    if (this.squaredTolerance_) {
      geometry = geometry.simplifyTransformed(
        this.squaredTolerance_,
        this.userTransform_
      );
    }
    if (!intersects$1(this.extent_, geometry.getExtent())) {
      return;
    }
    if (this.strokeState_) {
      this.setContextStrokeState_(this.strokeState_);
      const context = this.context_;
      const flatCoordinates = geometry.getFlatCoordinates();
      context.beginPath();
      this.moveToLineTo_(
        flatCoordinates,
        0,
        flatCoordinates.length,
        geometry.getStride(),
        false
      );
      context.stroke();
    }
    if (this.text_ !== "") {
      const flatMidpoint = geometry.getFlatMidpoint();
      this.drawText_(flatMidpoint, 0, 2, 2);
    }
  }
  drawMultiLineString(geometry) {
    if (this.squaredTolerance_) {
      geometry = geometry.simplifyTransformed(
        this.squaredTolerance_,
        this.userTransform_
      );
    }
    const geometryExtent = geometry.getExtent();
    if (!intersects$1(this.extent_, geometryExtent)) {
      return;
    }
    if (this.strokeState_) {
      this.setContextStrokeState_(this.strokeState_);
      const context = this.context_;
      const flatCoordinates = geometry.getFlatCoordinates();
      let offset = 0;
      const ends = geometry.getEnds();
      const stride = geometry.getStride();
      context.beginPath();
      for (let i = 0, ii = ends.length; i < ii; ++i) {
        offset = this.moveToLineTo_(
          flatCoordinates,
          offset,
          ends[i],
          stride,
          false
        );
      }
      context.stroke();
    }
    if (this.text_ !== "") {
      const flatMidpoints = geometry.getFlatMidpoints();
      this.drawText_(flatMidpoints, 0, flatMidpoints.length, 2);
    }
  }
  drawPolygon(geometry) {
    if (this.squaredTolerance_) {
      geometry = geometry.simplifyTransformed(
        this.squaredTolerance_,
        this.userTransform_
      );
    }
    if (!intersects$1(this.extent_, geometry.getExtent())) {
      return;
    }
    if (this.strokeState_ || this.fillState_) {
      if (this.fillState_) {
        this.setContextFillState_(this.fillState_);
      }
      if (this.strokeState_) {
        this.setContextStrokeState_(this.strokeState_);
      }
      const context = this.context_;
      context.beginPath();
      this.drawRings_(
        geometry.getOrientedFlatCoordinates(),
        0,
        geometry.getEnds(),
        geometry.getStride()
      );
      if (this.fillState_) {
        context.fill();
      }
      if (this.strokeState_) {
        context.stroke();
      }
    }
    if (this.text_ !== "") {
      const flatInteriorPoint = geometry.getFlatInteriorPoint();
      this.drawText_(flatInteriorPoint, 0, 2, 2);
    }
  }
  drawMultiPolygon(geometry) {
    if (this.squaredTolerance_) {
      geometry = geometry.simplifyTransformed(
        this.squaredTolerance_,
        this.userTransform_
      );
    }
    if (!intersects$1(this.extent_, geometry.getExtent())) {
      return;
    }
    if (this.strokeState_ || this.fillState_) {
      if (this.fillState_) {
        this.setContextFillState_(this.fillState_);
      }
      if (this.strokeState_) {
        this.setContextStrokeState_(this.strokeState_);
      }
      const context = this.context_;
      const flatCoordinates = geometry.getOrientedFlatCoordinates();
      let offset = 0;
      const endss = geometry.getEndss();
      const stride = geometry.getStride();
      context.beginPath();
      for (let i = 0, ii = endss.length; i < ii; ++i) {
        const ends = endss[i];
        offset = this.drawRings_(flatCoordinates, offset, ends, stride);
      }
      if (this.fillState_) {
        context.fill();
      }
      if (this.strokeState_) {
        context.stroke();
      }
    }
    if (this.text_ !== "") {
      const flatInteriorPoints = geometry.getFlatInteriorPoints();
      this.drawText_(flatInteriorPoints, 0, flatInteriorPoints.length, 2);
    }
  }
  setContextFillState_(fillState) {
    const context = this.context_;
    const contextFillState = this.contextFillState_;
    if (!contextFillState) {
      context.fillStyle = fillState.fillStyle;
      this.contextFillState_ = {
        fillStyle: fillState.fillStyle
      };
    } else {
      if (contextFillState.fillStyle != fillState.fillStyle) {
        contextFillState.fillStyle = fillState.fillStyle;
        context.fillStyle = fillState.fillStyle;
      }
    }
  }
  setContextStrokeState_(strokeState) {
    const context = this.context_;
    const contextStrokeState = this.contextStrokeState_;
    if (!contextStrokeState) {
      context.lineCap = strokeState.lineCap;
      context.setLineDash(strokeState.lineDash);
      context.lineDashOffset = strokeState.lineDashOffset;
      context.lineJoin = strokeState.lineJoin;
      context.lineWidth = strokeState.lineWidth;
      context.miterLimit = strokeState.miterLimit;
      context.strokeStyle = strokeState.strokeStyle;
      this.contextStrokeState_ = {
        lineCap: strokeState.lineCap,
        lineDash: strokeState.lineDash,
        lineDashOffset: strokeState.lineDashOffset,
        lineJoin: strokeState.lineJoin,
        lineWidth: strokeState.lineWidth,
        miterLimit: strokeState.miterLimit,
        strokeStyle: strokeState.strokeStyle
      };
    } else {
      if (contextStrokeState.lineCap != strokeState.lineCap) {
        contextStrokeState.lineCap = strokeState.lineCap;
        context.lineCap = strokeState.lineCap;
      }
      if (!equals$2(contextStrokeState.lineDash, strokeState.lineDash)) {
        context.setLineDash(
          contextStrokeState.lineDash = strokeState.lineDash
        );
      }
      if (contextStrokeState.lineDashOffset != strokeState.lineDashOffset) {
        contextStrokeState.lineDashOffset = strokeState.lineDashOffset;
        context.lineDashOffset = strokeState.lineDashOffset;
      }
      if (contextStrokeState.lineJoin != strokeState.lineJoin) {
        contextStrokeState.lineJoin = strokeState.lineJoin;
        context.lineJoin = strokeState.lineJoin;
      }
      if (contextStrokeState.lineWidth != strokeState.lineWidth) {
        contextStrokeState.lineWidth = strokeState.lineWidth;
        context.lineWidth = strokeState.lineWidth;
      }
      if (contextStrokeState.miterLimit != strokeState.miterLimit) {
        contextStrokeState.miterLimit = strokeState.miterLimit;
        context.miterLimit = strokeState.miterLimit;
      }
      if (contextStrokeState.strokeStyle != strokeState.strokeStyle) {
        contextStrokeState.strokeStyle = strokeState.strokeStyle;
        context.strokeStyle = strokeState.strokeStyle;
      }
    }
  }
  setContextTextState_(textState) {
    const context = this.context_;
    const contextTextState = this.contextTextState_;
    const textAlign = textState.textAlign ? textState.textAlign : defaultTextAlign;
    if (!contextTextState) {
      context.font = textState.font;
      context.textAlign = textAlign;
      context.textBaseline = textState.textBaseline;
      this.contextTextState_ = {
        font: textState.font,
        textAlign,
        textBaseline: textState.textBaseline
      };
    } else {
      if (contextTextState.font != textState.font) {
        contextTextState.font = textState.font;
        context.font = textState.font;
      }
      if (contextTextState.textAlign != textAlign) {
        contextTextState.textAlign = textAlign;
        context.textAlign = textAlign;
      }
      if (contextTextState.textBaseline != textState.textBaseline) {
        contextTextState.textBaseline = textState.textBaseline;
        context.textBaseline = textState.textBaseline;
      }
    }
  }
  setFillStrokeStyle(fillStyle, strokeStyle) {
    if (!fillStyle) {
      this.fillState_ = null;
    } else {
      const fillStyleColor = fillStyle.getColor();
      this.fillState_ = {
        fillStyle: asColorLike(
          fillStyleColor ? fillStyleColor : defaultFillStyle
        )
      };
    }
    if (!strokeStyle) {
      this.strokeState_ = null;
    } else {
      const strokeStyleColor = strokeStyle.getColor();
      const strokeStyleLineCap = strokeStyle.getLineCap();
      const strokeStyleLineDash = strokeStyle.getLineDash();
      const strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
      const strokeStyleLineJoin = strokeStyle.getLineJoin();
      const strokeStyleWidth = strokeStyle.getWidth();
      const strokeStyleMiterLimit = strokeStyle.getMiterLimit();
      const lineDash = strokeStyleLineDash ? strokeStyleLineDash : defaultLineDash;
      this.strokeState_ = {
        lineCap: strokeStyleLineCap !== void 0 ? strokeStyleLineCap : defaultLineCap,
        lineDash: this.pixelRatio_ === 1 ? lineDash : lineDash.map((n) => n * this.pixelRatio_),
        lineDashOffset: (strokeStyleLineDashOffset ? strokeStyleLineDashOffset : defaultLineDashOffset) * this.pixelRatio_,
        lineJoin: strokeStyleLineJoin !== void 0 ? strokeStyleLineJoin : defaultLineJoin,
        lineWidth: (strokeStyleWidth !== void 0 ? strokeStyleWidth : defaultLineWidth) * this.pixelRatio_,
        miterLimit: strokeStyleMiterLimit !== void 0 ? strokeStyleMiterLimit : defaultMiterLimit,
        strokeStyle: asColorLike(
          strokeStyleColor ? strokeStyleColor : defaultStrokeStyle
        )
      };
    }
  }
  setImageStyle(imageStyle) {
    let imageSize;
    if (!imageStyle || !(imageSize = imageStyle.getSize())) {
      this.image_ = null;
      return;
    }
    const imagePixelRatio = imageStyle.getPixelRatio(this.pixelRatio_);
    const imageAnchor = imageStyle.getAnchor();
    const imageOrigin = imageStyle.getOrigin();
    this.image_ = imageStyle.getImage(this.pixelRatio_);
    this.imageAnchorX_ = imageAnchor[0] * imagePixelRatio;
    this.imageAnchorY_ = imageAnchor[1] * imagePixelRatio;
    this.imageHeight_ = imageSize[1] * imagePixelRatio;
    this.imageOpacity_ = imageStyle.getOpacity();
    this.imageOriginX_ = imageOrigin[0];
    this.imageOriginY_ = imageOrigin[1];
    this.imageRotateWithView_ = imageStyle.getRotateWithView();
    this.imageRotation_ = imageStyle.getRotation();
    const imageScale = imageStyle.getScaleArray();
    this.imageScale_ = [
      imageScale[0] * this.pixelRatio_ / imagePixelRatio,
      imageScale[1] * this.pixelRatio_ / imagePixelRatio
    ];
    this.imageWidth_ = imageSize[0] * imagePixelRatio;
  }
  setTextStyle(textStyle) {
    if (!textStyle) {
      this.text_ = "";
    } else {
      const textFillStyle = textStyle.getFill();
      if (!textFillStyle) {
        this.textFillState_ = null;
      } else {
        const textFillStyleColor = textFillStyle.getColor();
        this.textFillState_ = {
          fillStyle: asColorLike(
            textFillStyleColor ? textFillStyleColor : defaultFillStyle
          )
        };
      }
      const textStrokeStyle = textStyle.getStroke();
      if (!textStrokeStyle) {
        this.textStrokeState_ = null;
      } else {
        const textStrokeStyleColor = textStrokeStyle.getColor();
        const textStrokeStyleLineCap = textStrokeStyle.getLineCap();
        const textStrokeStyleLineDash = textStrokeStyle.getLineDash();
        const textStrokeStyleLineDashOffset = textStrokeStyle.getLineDashOffset();
        const textStrokeStyleLineJoin = textStrokeStyle.getLineJoin();
        const textStrokeStyleWidth = textStrokeStyle.getWidth();
        const textStrokeStyleMiterLimit = textStrokeStyle.getMiterLimit();
        this.textStrokeState_ = {
          lineCap: textStrokeStyleLineCap !== void 0 ? textStrokeStyleLineCap : defaultLineCap,
          lineDash: textStrokeStyleLineDash ? textStrokeStyleLineDash : defaultLineDash,
          lineDashOffset: textStrokeStyleLineDashOffset ? textStrokeStyleLineDashOffset : defaultLineDashOffset,
          lineJoin: textStrokeStyleLineJoin !== void 0 ? textStrokeStyleLineJoin : defaultLineJoin,
          lineWidth: textStrokeStyleWidth !== void 0 ? textStrokeStyleWidth : defaultLineWidth,
          miterLimit: textStrokeStyleMiterLimit !== void 0 ? textStrokeStyleMiterLimit : defaultMiterLimit,
          strokeStyle: asColorLike(
            textStrokeStyleColor ? textStrokeStyleColor : defaultStrokeStyle
          )
        };
      }
      const textFont = textStyle.getFont();
      const textOffsetX = textStyle.getOffsetX();
      const textOffsetY = textStyle.getOffsetY();
      const textRotateWithView = textStyle.getRotateWithView();
      const textRotation = textStyle.getRotation();
      const textScale = textStyle.getScaleArray();
      const textText = textStyle.getText();
      const textTextAlign = textStyle.getTextAlign();
      const textTextBaseline = textStyle.getTextBaseline();
      this.textState_ = {
        font: textFont !== void 0 ? textFont : defaultFont,
        textAlign: textTextAlign !== void 0 ? textTextAlign : defaultTextAlign,
        textBaseline: textTextBaseline !== void 0 ? textTextBaseline : defaultTextBaseline
      };
      this.text_ = textText !== void 0 ? Array.isArray(textText) ? textText.reduce((acc, t, i) => acc += i % 2 ? " " : t, "") : textText : "";
      this.textOffsetX_ = textOffsetX !== void 0 ? this.pixelRatio_ * textOffsetX : 0;
      this.textOffsetY_ = textOffsetY !== void 0 ? this.pixelRatio_ * textOffsetY : 0;
      this.textRotateWithView_ = textRotateWithView !== void 0 ? textRotateWithView : false;
      this.textRotation_ = textRotation !== void 0 ? textRotation : 0;
      this.textScale_ = [
        this.pixelRatio_ * textScale[0],
        this.pixelRatio_ * textScale[1]
      ];
    }
  }
}
const CanvasImmediateRenderer$1 = CanvasImmediateRenderer;
const HIT_DETECT_RESOLUTION = 0.5;
function createHitDetectionImageData(size, transforms2, features, styleFunction, extent, resolution, rotation, squaredTolerance, projection) {
  const userExtent = projection ? toUserExtent(extent) : extent;
  const width = size[0] * HIT_DETECT_RESOLUTION;
  const height = size[1] * HIT_DETECT_RESOLUTION;
  const context = createCanvasContext2D(width, height);
  context.imageSmoothingEnabled = false;
  const canvas = context.canvas;
  const renderer = new CanvasImmediateRenderer$1(
    context,
    HIT_DETECT_RESOLUTION,
    extent,
    null,
    rotation,
    squaredTolerance,
    projection ? getTransformFromProjections(getUserProjection(), projection) : null
  );
  const featureCount = features.length;
  const indexFactor = Math.floor((256 * 256 * 256 - 1) / featureCount);
  const featuresByZIndex = {};
  for (let i = 1; i <= featureCount; ++i) {
    const feature2 = features[i - 1];
    const featureStyleFunction = feature2.getStyleFunction() || styleFunction;
    if (!featureStyleFunction) {
      continue;
    }
    let styles = featureStyleFunction(feature2, resolution);
    if (!styles) {
      continue;
    }
    if (!Array.isArray(styles)) {
      styles = [styles];
    }
    const index2 = i * indexFactor;
    const color = index2.toString(16).padStart(7, "#00000");
    for (let j = 0, jj = styles.length; j < jj; ++j) {
      const originalStyle = styles[j];
      const geometry = originalStyle.getGeometryFunction()(feature2);
      if (!geometry || !intersects$1(userExtent, geometry.getExtent())) {
        continue;
      }
      const style = originalStyle.clone();
      const fill = style.getFill();
      if (fill) {
        fill.setColor(color);
      }
      const stroke = style.getStroke();
      if (stroke) {
        stroke.setColor(color);
        stroke.setLineDash(null);
      }
      style.setText(void 0);
      const image = originalStyle.getImage();
      if (image) {
        const imgSize = image.getImageSize();
        if (!imgSize) {
          continue;
        }
        const imgContext = createCanvasContext2D(
          imgSize[0],
          imgSize[1],
          void 0,
          { alpha: false }
        );
        const img = imgContext.canvas;
        imgContext.fillStyle = color;
        imgContext.fillRect(0, 0, img.width, img.height);
        style.setImage(
          new Icon$1({
            img,
            anchor: image.getAnchor(),
            anchorXUnits: "pixels",
            anchorYUnits: "pixels",
            offset: image.getOrigin(),
            opacity: 1,
            size: image.getSize(),
            scale: image.getScale(),
            rotation: image.getRotation(),
            rotateWithView: image.getRotateWithView()
          })
        );
      }
      const zIndex = style.getZIndex() || 0;
      let byGeometryType = featuresByZIndex[zIndex];
      if (!byGeometryType) {
        byGeometryType = {};
        featuresByZIndex[zIndex] = byGeometryType;
        byGeometryType["Polygon"] = [];
        byGeometryType["Circle"] = [];
        byGeometryType["LineString"] = [];
        byGeometryType["Point"] = [];
      }
      const type = geometry.getType();
      if (type === "GeometryCollection") {
        const geometries = geometry.getGeometriesArrayRecursive();
        for (let i2 = 0, ii = geometries.length; i2 < ii; ++i2) {
          const geometry2 = geometries[i2];
          byGeometryType[geometry2.getType().replace("Multi", "")].push(
            geometry2,
            style
          );
        }
      } else {
        byGeometryType[type.replace("Multi", "")].push(geometry, style);
      }
    }
  }
  const zIndexKeys = Object.keys(featuresByZIndex).map(Number).sort(ascending);
  for (let i = 0, ii = zIndexKeys.length; i < ii; ++i) {
    const byGeometryType = featuresByZIndex[zIndexKeys[i]];
    for (const type in byGeometryType) {
      const geomAndStyle = byGeometryType[type];
      for (let j = 0, jj = geomAndStyle.length; j < jj; j += 2) {
        renderer.setStyle(geomAndStyle[j + 1]);
        for (let k = 0, kk = transforms2.length; k < kk; ++k) {
          renderer.setTransform(transforms2[k]);
          renderer.drawGeometry(geomAndStyle[j]);
        }
      }
    }
  }
  return context.getImageData(0, 0, canvas.width, canvas.height);
}
function hitDetect(pixel, features, imageData) {
  const resultFeatures = [];
  if (imageData) {
    const x = Math.floor(Math.round(pixel[0]) * HIT_DETECT_RESOLUTION);
    const y = Math.floor(Math.round(pixel[1]) * HIT_DETECT_RESOLUTION);
    const index2 = (clamp(x, 0, imageData.width - 1) + clamp(y, 0, imageData.height - 1) * imageData.width) * 4;
    const r = imageData.data[index2];
    const g = imageData.data[index2 + 1];
    const b = imageData.data[index2 + 2];
    const i = b + 256 * (g + 256 * r);
    const indexFactor = Math.floor((256 * 256 * 256 - 1) / features.length);
    if (i && i % indexFactor === 0) {
      resultFeatures.push(features[i / indexFactor - 1]);
    }
  }
  return resultFeatures;
}
const SIMPLIFY_TOLERANCE = 0.5;
const GEOMETRY_RENDERERS = {
  "Point": renderPointGeometry,
  "LineString": renderLineStringGeometry,
  "Polygon": renderPolygonGeometry,
  "MultiPoint": renderMultiPointGeometry,
  "MultiLineString": renderMultiLineStringGeometry,
  "MultiPolygon": renderMultiPolygonGeometry,
  "GeometryCollection": renderGeometryCollectionGeometry,
  "Circle": renderCircleGeometry
};
function defaultOrder(feature1, feature2) {
  return parseInt(getUid(feature1), 10) - parseInt(getUid(feature2), 10);
}
function getSquaredTolerance(resolution, pixelRatio) {
  const tolerance = getTolerance(resolution, pixelRatio);
  return tolerance * tolerance;
}
function getTolerance(resolution, pixelRatio) {
  return SIMPLIFY_TOLERANCE * resolution / pixelRatio;
}
function renderCircleGeometry(builderGroup, geometry, style, feature2, index2) {
  const fillStyle = style.getFill();
  const strokeStyle = style.getStroke();
  if (fillStyle || strokeStyle) {
    const circleReplay = builderGroup.getBuilder(style.getZIndex(), "Circle");
    circleReplay.setFillStrokeStyle(fillStyle, strokeStyle);
    circleReplay.drawCircle(geometry, feature2, index2);
  }
  const textStyle = style.getText();
  if (textStyle && textStyle.getText()) {
    const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
    textReplay.setTextStyle(textStyle);
    textReplay.drawText(geometry, feature2);
  }
}
function renderFeature(replayGroup, feature2, style, squaredTolerance, listener, transform, declutter, index2) {
  const loadingPromises = [];
  const imageStyle = style.getImage();
  if (imageStyle) {
    let loading2 = true;
    const imageState = imageStyle.getImageState();
    if (imageState == ImageState.LOADED || imageState == ImageState.ERROR) {
      loading2 = false;
    } else {
      if (imageState == ImageState.IDLE) {
        imageStyle.load();
      }
    }
    if (loading2) {
      loadingPromises.push(imageStyle.ready());
    }
  }
  const fillStyle = style.getFill();
  if (fillStyle && fillStyle.loading()) {
    loadingPromises.push(fillStyle.ready());
  }
  const loading = loadingPromises.length > 0;
  if (loading) {
    Promise.all(loadingPromises).then(() => listener(null));
  }
  renderFeatureInternal(
    replayGroup,
    feature2,
    style,
    squaredTolerance,
    transform,
    declutter,
    index2
  );
  return loading;
}
function renderFeatureInternal(replayGroup, feature2, style, squaredTolerance, transform, declutter, index2) {
  const geometry = style.getGeometryFunction()(feature2);
  if (!geometry) {
    return;
  }
  const simplifiedGeometry = geometry.simplifyTransformed(
    squaredTolerance,
    transform
  );
  const renderer = style.getRenderer();
  if (renderer) {
    renderGeometry(replayGroup, simplifiedGeometry, style, feature2, index2);
  } else {
    const geometryRenderer = GEOMETRY_RENDERERS[simplifiedGeometry.getType()];
    geometryRenderer(
      replayGroup,
      simplifiedGeometry,
      style,
      feature2,
      index2,
      declutter
    );
  }
}
function renderGeometry(replayGroup, geometry, style, feature2, index2) {
  if (geometry.getType() == "GeometryCollection") {
    const geometries = geometry.getGeometries();
    for (let i = 0, ii = geometries.length; i < ii; ++i) {
      renderGeometry(replayGroup, geometries[i], style, feature2, index2);
    }
    return;
  }
  const replay = replayGroup.getBuilder(style.getZIndex(), "Default");
  replay.drawCustom(
    geometry,
    feature2,
    style.getRenderer(),
    style.getHitDetectionRenderer(),
    index2
  );
}
function renderGeometryCollectionGeometry(replayGroup, geometry, style, feature2, declutterBuilderGroup, index2) {
  const geometries = geometry.getGeometriesArray();
  let i, ii;
  for (i = 0, ii = geometries.length; i < ii; ++i) {
    const geometryRenderer = GEOMETRY_RENDERERS[geometries[i].getType()];
    geometryRenderer(
      replayGroup,
      geometries[i],
      style,
      feature2,
      declutterBuilderGroup,
      index2
    );
  }
}
function renderLineStringGeometry(builderGroup, geometry, style, feature2, index2) {
  const strokeStyle = style.getStroke();
  if (strokeStyle) {
    const lineStringReplay = builderGroup.getBuilder(
      style.getZIndex(),
      "LineString"
    );
    lineStringReplay.setFillStrokeStyle(null, strokeStyle);
    lineStringReplay.drawLineString(geometry, feature2, index2);
  }
  const textStyle = style.getText();
  if (textStyle && textStyle.getText()) {
    const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
    textReplay.setTextStyle(textStyle);
    textReplay.drawText(geometry, feature2, index2);
  }
}
function renderMultiLineStringGeometry(builderGroup, geometry, style, feature2, index2) {
  const strokeStyle = style.getStroke();
  if (strokeStyle) {
    const lineStringReplay = builderGroup.getBuilder(
      style.getZIndex(),
      "LineString"
    );
    lineStringReplay.setFillStrokeStyle(null, strokeStyle);
    lineStringReplay.drawMultiLineString(geometry, feature2, index2);
  }
  const textStyle = style.getText();
  if (textStyle && textStyle.getText()) {
    const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
    textReplay.setTextStyle(textStyle);
    textReplay.drawText(geometry, feature2, index2);
  }
}
function renderMultiPolygonGeometry(builderGroup, geometry, style, feature2, index2) {
  const fillStyle = style.getFill();
  const strokeStyle = style.getStroke();
  if (strokeStyle || fillStyle) {
    const polygonReplay = builderGroup.getBuilder(style.getZIndex(), "Polygon");
    polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);
    polygonReplay.drawMultiPolygon(geometry, feature2, index2);
  }
  const textStyle = style.getText();
  if (textStyle && textStyle.getText()) {
    const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
    textReplay.setTextStyle(textStyle);
    textReplay.drawText(geometry, feature2, index2);
  }
}
function renderPointGeometry(builderGroup, geometry, style, feature2, index2, declutter) {
  const imageStyle = style.getImage();
  const textStyle = style.getText();
  const hasText = textStyle && textStyle.getText();
  const declutterImageWithText = declutter && imageStyle && hasText ? {} : void 0;
  if (imageStyle) {
    if (imageStyle.getImageState() != ImageState.LOADED) {
      return;
    }
    const imageReplay = builderGroup.getBuilder(style.getZIndex(), "Image");
    imageReplay.setImageStyle(imageStyle, declutterImageWithText);
    imageReplay.drawPoint(geometry, feature2, index2);
  }
  if (hasText) {
    const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
    textReplay.setTextStyle(textStyle, declutterImageWithText);
    textReplay.drawText(geometry, feature2, index2);
  }
}
function renderMultiPointGeometry(builderGroup, geometry, style, feature2, index2, declutter) {
  const imageStyle = style.getImage();
  const hasImage = imageStyle && imageStyle.getOpacity() !== 0;
  const textStyle = style.getText();
  const hasText = textStyle && textStyle.getText();
  const declutterImageWithText = declutter && hasImage && hasText ? {} : void 0;
  if (hasImage) {
    if (imageStyle.getImageState() != ImageState.LOADED) {
      return;
    }
    const imageReplay = builderGroup.getBuilder(style.getZIndex(), "Image");
    imageReplay.setImageStyle(imageStyle, declutterImageWithText);
    imageReplay.drawMultiPoint(geometry, feature2, index2);
  }
  if (hasText) {
    const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
    textReplay.setTextStyle(textStyle, declutterImageWithText);
    textReplay.drawText(geometry, feature2, index2);
  }
}
function renderPolygonGeometry(builderGroup, geometry, style, feature2, index2) {
  const fillStyle = style.getFill();
  const strokeStyle = style.getStroke();
  if (fillStyle || strokeStyle) {
    const polygonReplay = builderGroup.getBuilder(style.getZIndex(), "Polygon");
    polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);
    polygonReplay.drawPolygon(geometry, feature2, index2);
  }
  const textStyle = style.getText();
  if (textStyle && textStyle.getText()) {
    const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
    textReplay.setTextStyle(textStyle);
    textReplay.drawText(geometry, feature2, index2);
  }
}
class RenderEvent extends Event {
  constructor(type, inversePixelTransform, frameState, context) {
    super(type);
    this.inversePixelTransform = inversePixelTransform;
    this.frameState = frameState;
    this.context = context;
  }
}
const RenderEvent$1 = RenderEvent;
const maxStaleKeys = 5;
class LayerRenderer extends Observable$1 {
  constructor(layer) {
    super();
    this.ready = true;
    this.boundHandleImageChange_ = this.handleImageChange_.bind(this);
    this.layer_ = layer;
    this.staleKeys_ = new Array();
    this.maxStaleKeys = maxStaleKeys;
  }
  getStaleKeys() {
    return this.staleKeys_;
  }
  prependStaleKey(key) {
    this.staleKeys_.unshift(key);
    if (this.staleKeys_.length > this.maxStaleKeys) {
      this.staleKeys_.length = this.maxStaleKeys;
    }
  }
  getFeatures(pixel) {
    return abstract();
  }
  getData(pixel) {
    return null;
  }
  prepareFrame(frameState) {
    return abstract();
  }
  renderFrame(frameState, target) {
    return abstract();
  }
  forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, matches) {
    return void 0;
  }
  getLayer() {
    return this.layer_;
  }
  handleFontsChanged() {
  }
  handleImageChange_(event) {
    const image = event.target;
    if (image.getState() === ImageState.LOADED || image.getState() === ImageState.ERROR) {
      this.renderIfReadyAndVisible();
    }
  }
  loadImage(image) {
    let imageState = image.getState();
    if (imageState != ImageState.LOADED && imageState != ImageState.ERROR) {
      image.addEventListener(EventType.CHANGE, this.boundHandleImageChange_);
    }
    if (imageState == ImageState.IDLE) {
      image.load();
      imageState = image.getState();
    }
    return imageState == ImageState.LOADED;
  }
  renderIfReadyAndVisible() {
    const layer = this.getLayer();
    if (layer && layer.getVisible() && layer.getSourceState() === "ready") {
      layer.changed();
    }
  }
  renderDeferred(frameState) {
  }
  disposeInternal() {
    delete this.layer_;
    super.disposeInternal();
  }
}
const LayerRenderer$1 = LayerRenderer;
const canvasPool = [];
let pixelContext = null;
function createPixelContext() {
  pixelContext = createCanvasContext2D(1, 1, void 0, {
    willReadFrequently: true
  });
}
class CanvasLayerRenderer extends LayerRenderer$1 {
  constructor(layer) {
    super(layer);
    this.container = null;
    this.renderedResolution;
    this.tempTransform = create();
    this.pixelTransform = create();
    this.inversePixelTransform = create();
    this.context = null;
    this.deferredContext_ = null;
    this.containerReused = false;
    this.frameState = null;
  }
  getImageData(image, col, row) {
    if (!pixelContext) {
      createPixelContext();
    }
    pixelContext.clearRect(0, 0, 1, 1);
    let data;
    try {
      pixelContext.drawImage(image, col, row, 1, 1, 0, 0, 1, 1);
      data = pixelContext.getImageData(0, 0, 1, 1).data;
    } catch {
      pixelContext = null;
      return null;
    }
    return data;
  }
  getBackground(frameState) {
    const layer = this.getLayer();
    let background = layer.getBackground();
    if (typeof background === "function") {
      background = background(frameState.viewState.resolution);
    }
    return background || void 0;
  }
  useContainer(target, transform, backgroundColor) {
    const layerClassName = this.getLayer().getClassName();
    let container, context;
    if (target && target.className === layerClassName && (!backgroundColor || target && target.style.backgroundColor && equals$2(
      asArray(target.style.backgroundColor),
      asArray(backgroundColor)
    ))) {
      const canvas = target.firstElementChild;
      if (canvas instanceof HTMLCanvasElement) {
        context = canvas.getContext("2d");
      }
    }
    if (context && equivalent(context.canvas.style.transform, transform)) {
      this.container = target;
      this.context = context;
      this.containerReused = true;
    } else if (this.containerReused) {
      this.container = null;
      this.context = null;
      this.containerReused = false;
    } else if (this.container) {
      this.container.style.backgroundColor = null;
    }
    if (!this.container) {
      container = document.createElement("div");
      container.className = layerClassName;
      let style = container.style;
      style.position = "absolute";
      style.width = "100%";
      style.height = "100%";
      context = createCanvasContext2D();
      const canvas = context.canvas;
      container.appendChild(canvas);
      style = canvas.style;
      style.position = "absolute";
      style.left = "0";
      style.transformOrigin = "top left";
      this.container = container;
      this.context = context;
    }
    if (!this.containerReused && backgroundColor && !this.container.style.backgroundColor) {
      this.container.style.backgroundColor = backgroundColor;
    }
  }
  clipUnrotated(context, frameState, extent) {
    const topLeft = getTopLeft(extent);
    const topRight = getTopRight(extent);
    const bottomRight = getBottomRight(extent);
    const bottomLeft = getBottomLeft(extent);
    apply(frameState.coordinateToPixelTransform, topLeft);
    apply(frameState.coordinateToPixelTransform, topRight);
    apply(frameState.coordinateToPixelTransform, bottomRight);
    apply(frameState.coordinateToPixelTransform, bottomLeft);
    const inverted = this.inversePixelTransform;
    apply(inverted, topLeft);
    apply(inverted, topRight);
    apply(inverted, bottomRight);
    apply(inverted, bottomLeft);
    context.save();
    context.beginPath();
    context.moveTo(Math.round(topLeft[0]), Math.round(topLeft[1]));
    context.lineTo(Math.round(topRight[0]), Math.round(topRight[1]));
    context.lineTo(Math.round(bottomRight[0]), Math.round(bottomRight[1]));
    context.lineTo(Math.round(bottomLeft[0]), Math.round(bottomLeft[1]));
    context.clip();
  }
  prepareContainer(frameState, target) {
    const extent = frameState.extent;
    const resolution = frameState.viewState.resolution;
    const rotation = frameState.viewState.rotation;
    const pixelRatio = frameState.pixelRatio;
    const width = Math.round(getWidth(extent) / resolution * pixelRatio);
    const height = Math.round(getHeight(extent) / resolution * pixelRatio);
    compose(
      this.pixelTransform,
      frameState.size[0] / 2,
      frameState.size[1] / 2,
      1 / pixelRatio,
      1 / pixelRatio,
      rotation,
      -width / 2,
      -height / 2
    );
    makeInverse(this.inversePixelTransform, this.pixelTransform);
    const canvasTransform = toString$1(this.pixelTransform);
    this.useContainer(target, canvasTransform, this.getBackground(frameState));
    if (!this.containerReused) {
      const canvas = this.context.canvas;
      if (canvas.width != width || canvas.height != height) {
        canvas.width = width;
        canvas.height = height;
      } else {
        this.context.clearRect(0, 0, width, height);
      }
      if (canvasTransform !== canvas.style.transform) {
        canvas.style.transform = canvasTransform;
      }
    }
  }
  dispatchRenderEvent_(type, context, frameState) {
    const layer = this.getLayer();
    if (layer.hasListener(type)) {
      const event = new RenderEvent$1(
        type,
        this.inversePixelTransform,
        frameState,
        context
      );
      layer.dispatchEvent(event);
    }
  }
  preRender(context, frameState) {
    this.frameState = frameState;
    if (frameState.declutter) {
      return;
    }
    this.dispatchRenderEvent_(RenderEventType.PRERENDER, context, frameState);
  }
  postRender(context, frameState) {
    if (frameState.declutter) {
      return;
    }
    this.dispatchRenderEvent_(RenderEventType.POSTRENDER, context, frameState);
  }
  renderDeferredInternal(frameState) {
  }
  getRenderContext(frameState) {
    if (frameState.declutter && !this.deferredContext_) {
      this.deferredContext_ = new ZIndexContext$1();
    }
    return frameState.declutter ? this.deferredContext_.getContext() : this.context;
  }
  renderDeferred(frameState) {
    if (!frameState.declutter) {
      return;
    }
    this.dispatchRenderEvent_(
      RenderEventType.PRERENDER,
      this.context,
      frameState
    );
    if (frameState.declutter && this.deferredContext_) {
      this.deferredContext_.draw(this.context);
      this.deferredContext_.clear();
    }
    this.renderDeferredInternal(frameState);
    this.dispatchRenderEvent_(
      RenderEventType.POSTRENDER,
      this.context,
      frameState
    );
  }
  getRenderTransform(center, resolution, rotation, pixelRatio, width, height, offsetX) {
    const dx1 = width / 2;
    const dy1 = height / 2;
    const sx = pixelRatio / resolution;
    const sy = -sx;
    const dx2 = -center[0] + offsetX;
    const dy2 = -center[1];
    return compose(
      this.tempTransform,
      dx1,
      dy1,
      sx,
      sy,
      -rotation,
      dx2,
      dy2
    );
  }
  disposeInternal() {
    delete this.frameState;
    super.disposeInternal();
  }
}
const CanvasLayerRenderer$1 = CanvasLayerRenderer;
class CanvasVectorLayerRenderer extends CanvasLayerRenderer$1 {
  constructor(vectorLayer) {
    super(vectorLayer);
    this.boundHandleStyleImageChange_ = this.handleStyleImageChange_.bind(this);
    this.animatingOrInteracting_;
    this.hitDetectionImageData_ = null;
    this.clipped_ = false;
    this.renderedFeatures_ = null;
    this.renderedRevision_ = -1;
    this.renderedResolution_ = NaN;
    this.renderedExtent_ = createEmpty();
    this.wrappedRenderedExtent_ = createEmpty();
    this.renderedRotation_;
    this.renderedCenter_ = null;
    this.renderedProjection_ = null;
    this.renderedPixelRatio_ = 1;
    this.renderedRenderOrder_ = null;
    this.renderedFrameDeclutter_;
    this.replayGroup_ = null;
    this.replayGroupChanged = true;
    this.clipping = true;
    this.targetContext_ = null;
    this.opacity_ = 1;
  }
  renderWorlds(executorGroup, frameState, declutterable) {
    const extent = frameState.extent;
    const viewState = frameState.viewState;
    const center = viewState.center;
    const resolution = viewState.resolution;
    const projection = viewState.projection;
    const rotation = viewState.rotation;
    const projectionExtent = projection.getExtent();
    const vectorSource = this.getLayer().getSource();
    const declutter = this.getLayer().getDeclutter();
    const pixelRatio = frameState.pixelRatio;
    const viewHints = frameState.viewHints;
    const snapToPixel = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);
    const context = this.context;
    const width = Math.round(getWidth(extent) / resolution * pixelRatio);
    const height = Math.round(getHeight(extent) / resolution * pixelRatio);
    const multiWorld = vectorSource.getWrapX() && projection.canWrapX();
    const worldWidth = multiWorld ? getWidth(projectionExtent) : null;
    const endWorld = multiWorld ? Math.ceil((extent[2] - projectionExtent[2]) / worldWidth) + 1 : 1;
    let world = multiWorld ? Math.floor((extent[0] - projectionExtent[0]) / worldWidth) : 0;
    do {
      let transform = this.getRenderTransform(
        center,
        resolution,
        0,
        pixelRatio,
        width,
        height,
        world * worldWidth
      );
      if (frameState.declutter) {
        transform = transform.slice(0);
      }
      executorGroup.execute(
        context,
        [context.canvas.width, context.canvas.height],
        transform,
        rotation,
        snapToPixel,
        declutterable === void 0 ? ALL : declutterable ? DECLUTTER : NON_DECLUTTER,
        declutterable ? declutter && frameState.declutter[declutter] : void 0
      );
    } while (++world < endWorld);
  }
  setDrawContext_() {
    if (this.opacity_ !== 1) {
      this.targetContext_ = this.context;
      this.context = createCanvasContext2D(
        this.context.canvas.width,
        this.context.canvas.height,
        canvasPool
      );
    }
  }
  resetDrawContext_() {
    if (this.opacity_ !== 1 && this.targetContext_) {
      const alpha = this.targetContext_.globalAlpha;
      this.targetContext_.globalAlpha = this.opacity_;
      this.targetContext_.drawImage(this.context.canvas, 0, 0);
      this.targetContext_.globalAlpha = alpha;
      releaseCanvas(this.context);
      canvasPool.push(this.context.canvas);
      this.context = this.targetContext_;
      this.targetContext_ = null;
    }
  }
  renderDeclutter(frameState) {
    if (!this.replayGroup_ || !this.getLayer().getDeclutter()) {
      return;
    }
    this.renderWorlds(this.replayGroup_, frameState, true);
  }
  renderDeferredInternal(frameState) {
    if (!this.replayGroup_) {
      return;
    }
    this.replayGroup_.renderDeferred();
    if (this.clipped_) {
      this.context.restore();
    }
    this.resetDrawContext_();
  }
  renderFrame(frameState, target) {
    const layerState = frameState.layerStatesArray[frameState.layerIndex];
    this.opacity_ = layerState.opacity;
    const viewState = frameState.viewState;
    this.prepareContainer(frameState, target);
    const context = this.context;
    const replayGroup = this.replayGroup_;
    let render2 = replayGroup && !replayGroup.isEmpty();
    if (!render2) {
      const hasRenderListeners = this.getLayer().hasListener(RenderEventType.PRERENDER) || this.getLayer().hasListener(RenderEventType.POSTRENDER);
      if (!hasRenderListeners) {
        return this.container;
      }
    }
    this.setDrawContext_();
    this.preRender(context, frameState);
    viewState.projection;
    this.clipped_ = false;
    if (render2 && layerState.extent && this.clipping) {
      const layerExtent = fromUserExtent(layerState.extent);
      render2 = intersects$1(layerExtent, frameState.extent);
      this.clipped_ = render2 && !containsExtent(layerExtent, frameState.extent);
      if (this.clipped_) {
        this.clipUnrotated(context, frameState, layerExtent);
      }
    }
    if (render2) {
      this.renderWorlds(
        replayGroup,
        frameState,
        this.getLayer().getDeclutter() ? false : void 0
      );
    }
    if (!frameState.declutter && this.clipped_) {
      context.restore();
    }
    this.postRender(context, frameState);
    if (this.renderedRotation_ !== viewState.rotation) {
      this.renderedRotation_ = viewState.rotation;
      this.hitDetectionImageData_ = null;
    }
    if (!frameState.declutter) {
      this.resetDrawContext_();
    }
    return this.container;
  }
  getFeatures(pixel) {
    return new Promise((resolve) => {
      if (this.frameState && !this.hitDetectionImageData_ && !this.animatingOrInteracting_) {
        const size = this.frameState.size.slice();
        const center = this.renderedCenter_;
        const resolution = this.renderedResolution_;
        const rotation = this.renderedRotation_;
        const projection = this.renderedProjection_;
        const extent = this.wrappedRenderedExtent_;
        const layer = this.getLayer();
        const transforms2 = [];
        const width = size[0] * HIT_DETECT_RESOLUTION;
        const height = size[1] * HIT_DETECT_RESOLUTION;
        transforms2.push(
          this.getRenderTransform(
            center,
            resolution,
            rotation,
            HIT_DETECT_RESOLUTION,
            width,
            height,
            0
          ).slice()
        );
        const source = layer.getSource();
        const projectionExtent = projection.getExtent();
        if (source.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, extent)) {
          let startX = extent[0];
          const worldWidth = getWidth(projectionExtent);
          let world = 0;
          let offsetX;
          while (startX < projectionExtent[0]) {
            --world;
            offsetX = worldWidth * world;
            transforms2.push(
              this.getRenderTransform(
                center,
                resolution,
                rotation,
                HIT_DETECT_RESOLUTION,
                width,
                height,
                offsetX
              ).slice()
            );
            startX += worldWidth;
          }
          world = 0;
          startX = extent[2];
          while (startX > projectionExtent[2]) {
            ++world;
            offsetX = worldWidth * world;
            transforms2.push(
              this.getRenderTransform(
                center,
                resolution,
                rotation,
                HIT_DETECT_RESOLUTION,
                width,
                height,
                offsetX
              ).slice()
            );
            startX -= worldWidth;
          }
        }
        this.hitDetectionImageData_ = createHitDetectionImageData(
          size,
          transforms2,
          this.renderedFeatures_,
          layer.getStyleFunction(),
          extent,
          resolution,
          rotation,
          getSquaredTolerance(resolution, this.renderedPixelRatio_),
          null
        );
      }
      resolve(
        hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_)
      );
    });
  }
  forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, matches) {
    var _a, _b;
    if (!this.replayGroup_) {
      return void 0;
    }
    const resolution = frameState.viewState.resolution;
    const rotation = frameState.viewState.rotation;
    const layer = this.getLayer();
    const features = {};
    const featureCallback = function(feature2, geometry, distanceSq) {
      const key = getUid(feature2);
      const match = features[key];
      if (!match) {
        if (distanceSq === 0) {
          features[key] = true;
          return callback(feature2, layer, geometry);
        }
        matches.push(
          features[key] = {
            feature: feature2,
            layer,
            geometry,
            distanceSq,
            callback
          }
        );
      } else if (match !== true && distanceSq < match.distanceSq) {
        if (distanceSq === 0) {
          features[key] = true;
          matches.splice(matches.lastIndexOf(match), 1);
          return callback(feature2, layer, geometry);
        }
        match.geometry = geometry;
        match.distanceSq = distanceSq;
      }
      return void 0;
    };
    const declutter = this.getLayer().getDeclutter();
    return this.replayGroup_.forEachFeatureAtCoordinate(
      coordinate,
      resolution,
      rotation,
      hitTolerance,
      featureCallback,
      declutter ? (_b = (_a = frameState.declutter) == null ? void 0 : _a[declutter]) == null ? void 0 : _b.all().map((item) => item.value) : null
    );
  }
  handleFontsChanged() {
    const layer = this.getLayer();
    if (layer.getVisible() && this.replayGroup_) {
      layer.changed();
    }
  }
  handleStyleImageChange_(event) {
    this.renderIfReadyAndVisible();
  }
  prepareFrame(frameState) {
    const vectorLayer = this.getLayer();
    const vectorSource = vectorLayer.getSource();
    if (!vectorSource) {
      return false;
    }
    const animating = frameState.viewHints[ViewHint.ANIMATING];
    const interacting = frameState.viewHints[ViewHint.INTERACTING];
    const updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();
    const updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();
    if (this.ready && !updateWhileAnimating && animating || !updateWhileInteracting && interacting) {
      this.animatingOrInteracting_ = true;
      return true;
    }
    this.animatingOrInteracting_ = false;
    const frameStateExtent = frameState.extent;
    const viewState = frameState.viewState;
    const projection = viewState.projection;
    const resolution = viewState.resolution;
    const pixelRatio = frameState.pixelRatio;
    const vectorLayerRevision = vectorLayer.getRevision();
    const vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();
    let vectorLayerRenderOrder = vectorLayer.getRenderOrder();
    if (vectorLayerRenderOrder === void 0) {
      vectorLayerRenderOrder = defaultOrder;
    }
    const center = viewState.center.slice();
    const extent = buffer(
      frameStateExtent,
      vectorLayerRenderBuffer * resolution
    );
    const renderedExtent = extent.slice();
    const loadExtents = [extent.slice()];
    const projectionExtent = projection.getExtent();
    if (vectorSource.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, frameState.extent)) {
      const worldWidth = getWidth(projectionExtent);
      const gutter = Math.max(getWidth(extent) / 2, worldWidth);
      extent[0] = projectionExtent[0] - gutter;
      extent[2] = projectionExtent[2] + gutter;
      wrapX(center, projection);
      const loadExtent = wrapX$1(loadExtents[0], projection);
      if (loadExtent[0] < projectionExtent[0] && loadExtent[2] < projectionExtent[2]) {
        loadExtents.push([
          loadExtent[0] + worldWidth,
          loadExtent[1],
          loadExtent[2] + worldWidth,
          loadExtent[3]
        ]);
      } else if (loadExtent[0] > projectionExtent[0] && loadExtent[2] > projectionExtent[2]) {
        loadExtents.push([
          loadExtent[0] - worldWidth,
          loadExtent[1],
          loadExtent[2] - worldWidth,
          loadExtent[3]
        ]);
      }
    }
    if (this.ready && this.renderedResolution_ == resolution && this.renderedRevision_ == vectorLayerRevision && this.renderedRenderOrder_ == vectorLayerRenderOrder && this.renderedFrameDeclutter_ === !!frameState.declutter && containsExtent(this.wrappedRenderedExtent_, extent)) {
      if (!equals$2(this.renderedExtent_, renderedExtent)) {
        this.hitDetectionImageData_ = null;
        this.renderedExtent_ = renderedExtent;
      }
      this.renderedCenter_ = center;
      this.replayGroupChanged = false;
      return true;
    }
    this.replayGroup_ = null;
    const replayGroup = new CanvasBuilderGroup(
      getTolerance(resolution, pixelRatio),
      extent,
      resolution,
      pixelRatio
    );
    let userTransform;
    {
      for (let i = 0, ii = loadExtents.length; i < ii; ++i) {
        vectorSource.loadFeatures(loadExtents[i], resolution, projection);
      }
    }
    const squaredTolerance = getSquaredTolerance(resolution, pixelRatio);
    let ready = true;
    const render2 = (feature2, index2) => {
      let styles;
      const styleFunction = feature2.getStyleFunction() || vectorLayer.getStyleFunction();
      if (styleFunction) {
        styles = styleFunction(feature2, resolution);
      }
      if (styles) {
        const dirty = this.renderFeature(
          feature2,
          squaredTolerance,
          styles,
          replayGroup,
          userTransform,
          this.getLayer().getDeclutter(),
          index2
        );
        ready = ready && !dirty;
      }
    };
    const userExtent = toUserExtent(extent);
    const features = vectorSource.getFeaturesInExtent(userExtent);
    if (vectorLayerRenderOrder) {
      features.sort(vectorLayerRenderOrder);
    }
    for (let i = 0, ii = features.length; i < ii; ++i) {
      render2(features[i], i);
    }
    this.renderedFeatures_ = features;
    this.ready = ready;
    const replayGroupInstructions = replayGroup.finish();
    const executorGroup = new ExecutorGroup$1(
      extent,
      resolution,
      pixelRatio,
      vectorSource.getOverlaps(),
      replayGroupInstructions,
      vectorLayer.getRenderBuffer(),
      !!frameState.declutter
    );
    this.renderedResolution_ = resolution;
    this.renderedRevision_ = vectorLayerRevision;
    this.renderedRenderOrder_ = vectorLayerRenderOrder;
    this.renderedFrameDeclutter_ = !!frameState.declutter;
    this.renderedExtent_ = renderedExtent;
    this.wrappedRenderedExtent_ = extent;
    this.renderedCenter_ = center;
    this.renderedProjection_ = projection;
    this.renderedPixelRatio_ = pixelRatio;
    this.replayGroup_ = executorGroup;
    this.hitDetectionImageData_ = null;
    this.replayGroupChanged = true;
    return true;
  }
  renderFeature(feature2, squaredTolerance, styles, builderGroup, transform, declutter, index2) {
    if (!styles) {
      return false;
    }
    let loading = false;
    if (Array.isArray(styles)) {
      for (let i = 0, ii = styles.length; i < ii; ++i) {
        loading = renderFeature(
          builderGroup,
          feature2,
          styles[i],
          squaredTolerance,
          this.boundHandleStyleImageChange_,
          transform,
          declutter,
          index2
        ) || loading;
      }
    } else {
      loading = renderFeature(
        builderGroup,
        feature2,
        styles,
        squaredTolerance,
        this.boundHandleStyleImageChange_,
        transform,
        declutter,
        index2
      );
    }
    return loading;
  }
}
const CanvasVectorLayerRenderer$1 = CanvasVectorLayerRenderer;
let numTypes = 0;
const BooleanType = 1 << numTypes++;
const NumberType = 1 << numTypes++;
const StringType = 1 << numTypes++;
const ColorType = 1 << numTypes++;
const NumberArrayType = 1 << numTypes++;
const SizeType = 1 << numTypes++;
const AnyType = Math.pow(2, numTypes) - 1;
const typeNames = {
  [BooleanType]: "boolean",
  [NumberType]: "number",
  [StringType]: "string",
  [ColorType]: "color",
  [NumberArrayType]: "number[]",
  [SizeType]: "size"
};
const namedTypes = Object.keys(typeNames).map(Number).sort(ascending);
function isSpecific(type) {
  return type in typeNames;
}
function typeName(type) {
  const names = [];
  for (const namedType of namedTypes) {
    if (includesType(type, namedType)) {
      names.push(typeNames[namedType]);
    }
  }
  if (names.length === 0) {
    return "untyped";
  }
  if (names.length < 3) {
    return names.join(" or ");
  }
  return names.slice(0, -1).join(", ") + ", or " + names[names.length - 1];
}
function includesType(broad, specific) {
  return (broad & specific) === specific;
}
function isType(type, expected) {
  return type === expected;
}
class LiteralExpression {
  constructor(type, value) {
    if (!isSpecific(type)) {
      throw new Error(
        `literal expressions must have a specific type, got ${typeName(type)}`
      );
    }
    this.type = type;
    this.value = value;
  }
}
class CallExpression {
  constructor(type, operator, ...args) {
    this.type = type;
    this.operator = operator;
    this.args = args;
  }
}
function newParsingContext() {
  return {
    variables: /* @__PURE__ */ new Set(),
    properties: /* @__PURE__ */ new Set(),
    featureId: false,
    geometryType: false,
    mapState: false
  };
}
function parse(encoded, expectedType, context) {
  switch (typeof encoded) {
    case "boolean": {
      if (isType(expectedType, StringType)) {
        return new LiteralExpression(StringType, encoded ? "true" : "false");
      }
      if (!includesType(expectedType, BooleanType)) {
        throw new Error(
          `got a boolean, but expected ${typeName(expectedType)}`
        );
      }
      return new LiteralExpression(BooleanType, encoded);
    }
    case "number": {
      if (isType(expectedType, SizeType)) {
        return new LiteralExpression(SizeType, toSize(encoded));
      }
      if (isType(expectedType, BooleanType)) {
        return new LiteralExpression(BooleanType, !!encoded);
      }
      if (isType(expectedType, StringType)) {
        return new LiteralExpression(StringType, encoded.toString());
      }
      if (!includesType(expectedType, NumberType)) {
        throw new Error(`got a number, but expected ${typeName(expectedType)}`);
      }
      return new LiteralExpression(NumberType, encoded);
    }
    case "string": {
      if (isType(expectedType, ColorType)) {
        return new LiteralExpression(ColorType, fromString(encoded));
      }
      if (isType(expectedType, BooleanType)) {
        return new LiteralExpression(BooleanType, !!encoded);
      }
      if (!includesType(expectedType, StringType)) {
        throw new Error(`got a string, but expected ${typeName(expectedType)}`);
      }
      return new LiteralExpression(StringType, encoded);
    }
  }
  if (!Array.isArray(encoded)) {
    throw new Error("expression must be an array or a primitive value");
  }
  if (encoded.length === 0) {
    throw new Error("empty expression");
  }
  if (typeof encoded[0] === "string") {
    return parseCallExpression(encoded, expectedType, context);
  }
  for (const item of encoded) {
    if (typeof item !== "number") {
      throw new Error("expected an array of numbers");
    }
  }
  if (isType(expectedType, SizeType)) {
    if (encoded.length !== 2) {
      throw new Error(
        `expected an array of two values for a size, got ${encoded.length}`
      );
    }
    return new LiteralExpression(SizeType, encoded);
  }
  if (isType(expectedType, ColorType)) {
    if (encoded.length === 3) {
      return new LiteralExpression(ColorType, [...encoded, 1]);
    }
    if (encoded.length === 4) {
      return new LiteralExpression(ColorType, encoded);
    }
    throw new Error(
      `expected an array of 3 or 4 values for a color, got ${encoded.length}`
    );
  }
  if (!includesType(expectedType, NumberArrayType)) {
    throw new Error(
      `got an array of numbers, but expected ${typeName(expectedType)}`
    );
  }
  return new LiteralExpression(NumberArrayType, encoded);
}
const Ops = {
  Get: "get",
  Var: "var",
  Concat: "concat",
  GeometryType: "geometry-type",
  LineMetric: "line-metric",
  Any: "any",
  All: "all",
  Not: "!",
  Resolution: "resolution",
  Zoom: "zoom",
  Time: "time",
  Equal: "==",
  NotEqual: "!=",
  GreaterThan: ">",
  GreaterThanOrEqualTo: ">=",
  LessThan: "<",
  LessThanOrEqualTo: "<=",
  Multiply: "*",
  Divide: "/",
  Add: "+",
  Subtract: "-",
  Clamp: "clamp",
  Mod: "%",
  Pow: "^",
  Abs: "abs",
  Floor: "floor",
  Ceil: "ceil",
  Round: "round",
  Sin: "sin",
  Cos: "cos",
  Atan: "atan",
  Sqrt: "sqrt",
  Match: "match",
  Between: "between",
  Interpolate: "interpolate",
  Coalesce: "coalesce",
  Case: "case",
  In: "in",
  Number: "number",
  String: "string",
  Array: "array",
  Color: "color",
  Id: "id",
  Band: "band",
  Palette: "palette",
  ToString: "to-string",
  Has: "has"
};
const parsers = {
  [Ops.Get]: createCallExpressionParser(hasArgsCount(1, Infinity), withGetArgs),
  [Ops.Var]: createCallExpressionParser(hasArgsCount(1, 1), withVarArgs),
  [Ops.Has]: createCallExpressionParser(hasArgsCount(1, Infinity), withGetArgs),
  [Ops.Id]: createCallExpressionParser(usesFeatureId, withNoArgs),
  [Ops.Concat]: createCallExpressionParser(
    hasArgsCount(2, Infinity),
    withArgsOfType(StringType)
  ),
  [Ops.GeometryType]: createCallExpressionParser(usesGeometryType, withNoArgs),
  [Ops.LineMetric]: createCallExpressionParser(withNoArgs),
  [Ops.Resolution]: createCallExpressionParser(usesMapState, withNoArgs),
  [Ops.Zoom]: createCallExpressionParser(usesMapState, withNoArgs),
  [Ops.Time]: createCallExpressionParser(usesMapState, withNoArgs),
  [Ops.Any]: createCallExpressionParser(
    hasArgsCount(2, Infinity),
    withArgsOfType(BooleanType)
  ),
  [Ops.All]: createCallExpressionParser(
    hasArgsCount(2, Infinity),
    withArgsOfType(BooleanType)
  ),
  [Ops.Not]: createCallExpressionParser(
    hasArgsCount(1, 1),
    withArgsOfType(BooleanType)
  ),
  [Ops.Equal]: createCallExpressionParser(
    hasArgsCount(2, 2),
    withArgsOfType(AnyType)
  ),
  [Ops.NotEqual]: createCallExpressionParser(
    hasArgsCount(2, 2),
    withArgsOfType(AnyType)
  ),
  [Ops.GreaterThan]: createCallExpressionParser(
    hasArgsCount(2, 2),
    withArgsOfType(NumberType)
  ),
  [Ops.GreaterThanOrEqualTo]: createCallExpressionParser(
    hasArgsCount(2, 2),
    withArgsOfType(NumberType)
  ),
  [Ops.LessThan]: createCallExpressionParser(
    hasArgsCount(2, 2),
    withArgsOfType(NumberType)
  ),
  [Ops.LessThanOrEqualTo]: createCallExpressionParser(
    hasArgsCount(2, 2),
    withArgsOfType(NumberType)
  ),
  [Ops.Multiply]: createCallExpressionParser(
    hasArgsCount(2, Infinity),
    withArgsOfReturnType
  ),
  [Ops.Coalesce]: createCallExpressionParser(
    hasArgsCount(2, Infinity),
    withArgsOfReturnType
  ),
  [Ops.Divide]: createCallExpressionParser(
    hasArgsCount(2, 2),
    withArgsOfType(NumberType)
  ),
  [Ops.Add]: createCallExpressionParser(
    hasArgsCount(2, Infinity),
    withArgsOfType(NumberType)
  ),
  [Ops.Subtract]: createCallExpressionParser(
    hasArgsCount(2, 2),
    withArgsOfType(NumberType)
  ),
  [Ops.Clamp]: createCallExpressionParser(
    hasArgsCount(3, 3),
    withArgsOfType(NumberType)
  ),
  [Ops.Mod]: createCallExpressionParser(
    hasArgsCount(2, 2),
    withArgsOfType(NumberType)
  ),
  [Ops.Pow]: createCallExpressionParser(
    hasArgsCount(2, 2),
    withArgsOfType(NumberType)
  ),
  [Ops.Abs]: createCallExpressionParser(
    hasArgsCount(1, 1),
    withArgsOfType(NumberType)
  ),
  [Ops.Floor]: createCallExpressionParser(
    hasArgsCount(1, 1),
    withArgsOfType(NumberType)
  ),
  [Ops.Ceil]: createCallExpressionParser(
    hasArgsCount(1, 1),
    withArgsOfType(NumberType)
  ),
  [Ops.Round]: createCallExpressionParser(
    hasArgsCount(1, 1),
    withArgsOfType(NumberType)
  ),
  [Ops.Sin]: createCallExpressionParser(
    hasArgsCount(1, 1),
    withArgsOfType(NumberType)
  ),
  [Ops.Cos]: createCallExpressionParser(
    hasArgsCount(1, 1),
    withArgsOfType(NumberType)
  ),
  [Ops.Atan]: createCallExpressionParser(
    hasArgsCount(1, 2),
    withArgsOfType(NumberType)
  ),
  [Ops.Sqrt]: createCallExpressionParser(
    hasArgsCount(1, 1),
    withArgsOfType(NumberType)
  ),
  [Ops.Match]: createCallExpressionParser(
    hasArgsCount(4, Infinity),
    hasEvenArgs,
    withMatchArgs
  ),
  [Ops.Between]: createCallExpressionParser(
    hasArgsCount(3, 3),
    withArgsOfType(NumberType)
  ),
  [Ops.Interpolate]: createCallExpressionParser(
    hasArgsCount(6, Infinity),
    hasEvenArgs,
    withInterpolateArgs
  ),
  [Ops.Case]: createCallExpressionParser(
    hasArgsCount(3, Infinity),
    hasOddArgs,
    withCaseArgs
  ),
  [Ops.In]: createCallExpressionParser(hasArgsCount(2, 2), withInArgs),
  [Ops.Number]: createCallExpressionParser(
    hasArgsCount(1, Infinity),
    withArgsOfType(AnyType)
  ),
  [Ops.String]: createCallExpressionParser(
    hasArgsCount(1, Infinity),
    withArgsOfType(AnyType)
  ),
  [Ops.Array]: createCallExpressionParser(
    hasArgsCount(1, Infinity),
    withArgsOfType(NumberType)
  ),
  [Ops.Color]: createCallExpressionParser(
    hasArgsCount(1, 4),
    withArgsOfType(NumberType)
  ),
  [Ops.Band]: createCallExpressionParser(
    hasArgsCount(1, 3),
    withArgsOfType(NumberType)
  ),
  [Ops.Palette]: createCallExpressionParser(
    hasArgsCount(2, 2),
    withPaletteArgs
  ),
  [Ops.ToString]: createCallExpressionParser(
    hasArgsCount(1, 1),
    withArgsOfType(BooleanType | NumberType | StringType | ColorType)
  )
};
function withGetArgs(encoded, returnType, context) {
  const argsCount = encoded.length - 1;
  const args = new Array(argsCount);
  for (let i = 0; i < argsCount; ++i) {
    const key = encoded[i + 1];
    switch (typeof key) {
      case "number": {
        args[i] = new LiteralExpression(NumberType, key);
        break;
      }
      case "string": {
        args[i] = new LiteralExpression(StringType, key);
        break;
      }
      default: {
        throw new Error(
          `expected a string key or numeric array index for a get operation, got ${key}`
        );
      }
    }
    if (i === 0) {
      context.properties.add(String(key));
    }
  }
  return args;
}
function withVarArgs(encoded, returnType, context) {
  const name = encoded[1];
  if (typeof name !== "string") {
    throw new Error("expected a string argument for var operation");
  }
  context.variables.add(name);
  return [new LiteralExpression(StringType, name)];
}
function usesFeatureId(encoded, returnType, context) {
  context.featureId = true;
}
function usesGeometryType(encoded, returnType, context) {
  context.geometryType = true;
}
function usesMapState(encoded, returnType, context) {
  context.mapState = true;
}
function withNoArgs(encoded, returnType, context) {
  const operation = encoded[0];
  if (encoded.length !== 1) {
    throw new Error(`expected no arguments for ${operation} operation`);
  }
  return [];
}
function hasArgsCount(minArgs, maxArgs) {
  return function(encoded, returnType, context) {
    const operation = encoded[0];
    const argCount = encoded.length - 1;
    if (minArgs === maxArgs) {
      if (argCount !== minArgs) {
        const plural = minArgs === 1 ? "" : "s";
        throw new Error(
          `expected ${minArgs} argument${plural} for ${operation}, got ${argCount}`
        );
      }
    } else if (argCount < minArgs || argCount > maxArgs) {
      const range = maxArgs === Infinity ? `${minArgs} or more` : `${minArgs} to ${maxArgs}`;
      throw new Error(
        `expected ${range} arguments for ${operation}, got ${argCount}`
      );
    }
  };
}
function withArgsOfReturnType(encoded, returnType, context) {
  const argCount = encoded.length - 1;
  const args = new Array(argCount);
  for (let i = 0; i < argCount; ++i) {
    const expression = parse(encoded[i + 1], returnType, context);
    args[i] = expression;
  }
  return args;
}
function withArgsOfType(argType) {
  return function(encoded, returnType, context) {
    const argCount = encoded.length - 1;
    const args = new Array(argCount);
    for (let i = 0; i < argCount; ++i) {
      const expression = parse(encoded[i + 1], argType, context);
      args[i] = expression;
    }
    return args;
  };
}
function hasOddArgs(encoded, returnType, context) {
  const operation = encoded[0];
  const argCount = encoded.length - 1;
  if (argCount % 2 === 0) {
    throw new Error(
      `expected an odd number of arguments for ${operation}, got ${argCount} instead`
    );
  }
}
function hasEvenArgs(encoded, returnType, context) {
  const operation = encoded[0];
  const argCount = encoded.length - 1;
  if (argCount % 2 === 1) {
    throw new Error(
      `expected an even number of arguments for operation ${operation}, got ${argCount} instead`
    );
  }
}
function withMatchArgs(encoded, returnType, context) {
  const argsCount = encoded.length - 1;
  const inputType = StringType | NumberType | BooleanType;
  const input = parse(encoded[1], inputType, context);
  const fallback = parse(encoded[encoded.length - 1], returnType, context);
  const args = new Array(argsCount - 2);
  for (let i = 0; i < argsCount - 2; i += 2) {
    try {
      const match = parse(encoded[i + 2], input.type, context);
      args[i] = match;
    } catch (err) {
      throw new Error(
        `failed to parse argument ${i + 1} of match expression: ${err.message}`
      );
    }
    try {
      const output = parse(encoded[i + 3], fallback.type, context);
      args[i + 1] = output;
    } catch (err) {
      throw new Error(
        `failed to parse argument ${i + 2} of match expression: ${err.message}`
      );
    }
  }
  return [input, ...args, fallback];
}
function withInterpolateArgs(encoded, returnType, context) {
  const interpolationType = encoded[1];
  let base;
  switch (interpolationType[0]) {
    case "linear":
      base = 1;
      break;
    case "exponential":
      const b = interpolationType[1];
      if (typeof b !== "number" || b <= 0) {
        throw new Error(
          `expected a number base for exponential interpolation, got ${JSON.stringify(b)} instead`
        );
      }
      base = b;
      break;
    default:
      throw new Error(
        `invalid interpolation type: ${JSON.stringify(interpolationType)}`
      );
  }
  const interpolation = new LiteralExpression(NumberType, base);
  let input;
  try {
    input = parse(encoded[2], NumberType, context);
  } catch (err) {
    throw new Error(
      `failed to parse argument 1 in interpolate expression: ${err.message}`
    );
  }
  const args = new Array(encoded.length - 3);
  for (let i = 0; i < args.length; i += 2) {
    try {
      const stop = parse(encoded[i + 3], NumberType, context);
      args[i] = stop;
    } catch (err) {
      throw new Error(
        `failed to parse argument ${i + 2} for interpolate expression: ${err.message}`
      );
    }
    try {
      const output = parse(encoded[i + 4], returnType, context);
      args[i + 1] = output;
    } catch (err) {
      throw new Error(
        `failed to parse argument ${i + 3} for interpolate expression: ${err.message}`
      );
    }
  }
  return [interpolation, input, ...args];
}
function withCaseArgs(encoded, returnType, context) {
  const fallback = parse(encoded[encoded.length - 1], returnType, context);
  const args = new Array(encoded.length - 1);
  for (let i = 0; i < args.length - 1; i += 2) {
    try {
      const condition = parse(encoded[i + 1], BooleanType, context);
      args[i] = condition;
    } catch (err) {
      throw new Error(
        `failed to parse argument ${i} of case expression: ${err.message}`
      );
    }
    try {
      const output = parse(encoded[i + 2], fallback.type, context);
      args[i + 1] = output;
    } catch (err) {
      throw new Error(
        `failed to parse argument ${i + 1} of case expression: ${err.message}`
      );
    }
  }
  args[args.length - 1] = fallback;
  return args;
}
function withInArgs(encoded, returnType, context) {
  let haystack = encoded[2];
  if (!Array.isArray(haystack)) {
    throw new Error(
      `the second argument for the "in" operator must be an array`
    );
  }
  let needleType;
  if (typeof haystack[0] === "string") {
    if (haystack[0] !== "literal") {
      throw new Error(
        `for the "in" operator, a string array should be wrapped in a "literal" operator to disambiguate from expressions`
      );
    }
    if (!Array.isArray(haystack[1])) {
      throw new Error(
        `failed to parse "in" expression: the literal operator must be followed by an array`
      );
    }
    haystack = haystack[1];
    needleType = StringType;
  } else {
    needleType = NumberType;
  }
  const args = new Array(haystack.length);
  for (let i = 0; i < args.length; i++) {
    try {
      const arg = parse(haystack[i], needleType, context);
      args[i] = arg;
    } catch (err) {
      throw new Error(
        `failed to parse haystack item ${i} for "in" expression: ${err.message}`
      );
    }
  }
  const needle = parse(encoded[1], needleType, context);
  return [needle, ...args];
}
function withPaletteArgs(encoded, returnType, context) {
  let index2;
  try {
    index2 = parse(encoded[1], NumberType, context);
  } catch (err) {
    throw new Error(
      `failed to parse first argument in palette expression: ${err.message}`
    );
  }
  const colors = encoded[2];
  if (!Array.isArray(colors)) {
    throw new Error("the second argument of palette must be an array");
  }
  const parsedColors = new Array(colors.length);
  for (let i = 0; i < parsedColors.length; i++) {
    let color;
    try {
      color = parse(colors[i], ColorType, context);
    } catch (err) {
      throw new Error(
        `failed to parse color at index ${i} in palette expression: ${err.message}`
      );
    }
    if (!(color instanceof LiteralExpression)) {
      throw new Error(
        `the palette color at index ${i} must be a literal value`
      );
    }
    parsedColors[i] = color;
  }
  return [index2, ...parsedColors];
}
function createCallExpressionParser(...validators) {
  return function(encoded, returnType, context) {
    const operator = encoded[0];
    let args;
    for (let i = 0; i < validators.length; i++) {
      const parsed = validators[i](encoded, returnType, context);
      if (i == validators.length - 1) {
        if (!parsed) {
          throw new Error(
            "expected last argument validator to return the parsed args"
          );
        }
        args = parsed;
      }
    }
    return new CallExpression(returnType, operator, ...args);
  };
}
function parseCallExpression(encoded, returnType, context) {
  const operator = encoded[0];
  const parser = parsers[operator];
  if (!parser) {
    throw new Error(`unknown operator: ${operator}`);
  }
  return parser(encoded, returnType, context);
}
function computeGeometryType(geometry) {
  if (!geometry) {
    return "";
  }
  const type = geometry.getType();
  switch (type) {
    case "Point":
    case "LineString":
    case "Polygon":
      return type;
    case "MultiPoint":
    case "MultiLineString":
    case "MultiPolygon":
      return type.substring(5);
    case "Circle":
      return "Polygon";
    case "GeometryCollection":
      return computeGeometryType(
        geometry.getGeometries()[0]
      );
    default:
      return "";
  }
}
function newEvaluationContext() {
  return {
    variables: {},
    properties: {},
    resolution: NaN,
    featureId: null,
    geometryType: ""
  };
}
function buildExpression(encoded, type, context) {
  const expression = parse(encoded, type, context);
  return compileExpression(expression);
}
function compileExpression(expression, context) {
  if (expression instanceof LiteralExpression) {
    if (expression.type === ColorType && typeof expression.value === "string") {
      const colorValue = fromString(expression.value);
      return function() {
        return colorValue;
      };
    }
    return function() {
      return expression.value;
    };
  }
  const operator = expression.operator;
  switch (operator) {
    case Ops.Number:
    case Ops.String:
    case Ops.Coalesce: {
      return compileAssertionExpression(expression);
    }
    case Ops.Get:
    case Ops.Var:
    case Ops.Has: {
      return compileAccessorExpression(expression);
    }
    case Ops.Id: {
      return (context2) => context2.featureId;
    }
    case Ops.GeometryType: {
      return (context2) => context2.geometryType;
    }
    case Ops.Concat: {
      const args = expression.args.map((e) => compileExpression(e));
      return (context2) => "".concat(...args.map((arg) => arg(context2).toString()));
    }
    case Ops.Resolution: {
      return (context2) => context2.resolution;
    }
    case Ops.Any:
    case Ops.All:
    case Ops.Between:
    case Ops.In:
    case Ops.Not: {
      return compileLogicalExpression(expression);
    }
    case Ops.Equal:
    case Ops.NotEqual:
    case Ops.LessThan:
    case Ops.LessThanOrEqualTo:
    case Ops.GreaterThan:
    case Ops.GreaterThanOrEqualTo: {
      return compileComparisonExpression(expression);
    }
    case Ops.Multiply:
    case Ops.Divide:
    case Ops.Add:
    case Ops.Subtract:
    case Ops.Clamp:
    case Ops.Mod:
    case Ops.Pow:
    case Ops.Abs:
    case Ops.Floor:
    case Ops.Ceil:
    case Ops.Round:
    case Ops.Sin:
    case Ops.Cos:
    case Ops.Atan:
    case Ops.Sqrt: {
      return compileNumericExpression(expression);
    }
    case Ops.Case: {
      return compileCaseExpression(expression);
    }
    case Ops.Match: {
      return compileMatchExpression(expression);
    }
    case Ops.Interpolate: {
      return compileInterpolateExpression(expression);
    }
    case Ops.ToString: {
      return compileConvertExpression(expression);
    }
    default: {
      throw new Error(`Unsupported operator ${operator}`);
    }
  }
}
function compileAssertionExpression(expression, context) {
  const type = expression.operator;
  const length = expression.args.length;
  const args = new Array(length);
  for (let i = 0; i < length; ++i) {
    args[i] = compileExpression(expression.args[i]);
  }
  switch (type) {
    case Ops.Coalesce: {
      return (context2) => {
        for (let i = 0; i < length; ++i) {
          const value = args[i](context2);
          if (typeof value !== "undefined" && value !== null) {
            return value;
          }
        }
        throw new Error("Expected one of the values to be non-null");
      };
    }
    case Ops.Number:
    case Ops.String: {
      return (context2) => {
        for (let i = 0; i < length; ++i) {
          const value = args[i](context2);
          if (typeof value === type) {
            return value;
          }
        }
        throw new Error(`Expected one of the values to be a ${type}`);
      };
    }
    default: {
      throw new Error(`Unsupported assertion operator ${type}`);
    }
  }
}
function compileAccessorExpression(expression, context) {
  const nameExpression = expression.args[0];
  const name = nameExpression.value;
  switch (expression.operator) {
    case Ops.Get: {
      return (context2) => {
        const args = expression.args;
        let value = context2.properties[name];
        for (let i = 1, ii = args.length; i < ii; ++i) {
          const keyExpression = args[i];
          const key = keyExpression.value;
          value = value[key];
        }
        return value;
      };
    }
    case Ops.Var: {
      return (context2) => context2.variables[name];
    }
    case Ops.Has: {
      return (context2) => {
        const args = expression.args;
        if (!(name in context2.properties)) {
          return false;
        }
        let value = context2.properties[name];
        for (let i = 1, ii = args.length; i < ii; ++i) {
          const keyExpression = args[i];
          const key = keyExpression.value;
          if (!value || !Object.hasOwn(value, key)) {
            return false;
          }
          value = value[key];
        }
        return true;
      };
    }
    default: {
      throw new Error(`Unsupported accessor operator ${expression.operator}`);
    }
  }
}
function compileComparisonExpression(expression, context) {
  const op = expression.operator;
  const left = compileExpression(expression.args[0]);
  const right = compileExpression(expression.args[1]);
  switch (op) {
    case Ops.Equal: {
      return (context2) => left(context2) === right(context2);
    }
    case Ops.NotEqual: {
      return (context2) => left(context2) !== right(context2);
    }
    case Ops.LessThan: {
      return (context2) => left(context2) < right(context2);
    }
    case Ops.LessThanOrEqualTo: {
      return (context2) => left(context2) <= right(context2);
    }
    case Ops.GreaterThan: {
      return (context2) => left(context2) > right(context2);
    }
    case Ops.GreaterThanOrEqualTo: {
      return (context2) => left(context2) >= right(context2);
    }
    default: {
      throw new Error(`Unsupported comparison operator ${op}`);
    }
  }
}
function compileLogicalExpression(expression, context) {
  const op = expression.operator;
  const length = expression.args.length;
  const args = new Array(length);
  for (let i = 0; i < length; ++i) {
    args[i] = compileExpression(expression.args[i]);
  }
  switch (op) {
    case Ops.Any: {
      return (context2) => {
        for (let i = 0; i < length; ++i) {
          if (args[i](context2)) {
            return true;
          }
        }
        return false;
      };
    }
    case Ops.All: {
      return (context2) => {
        for (let i = 0; i < length; ++i) {
          if (!args[i](context2)) {
            return false;
          }
        }
        return true;
      };
    }
    case Ops.Between: {
      return (context2) => {
        const value = args[0](context2);
        const min = args[1](context2);
        const max = args[2](context2);
        return value >= min && value <= max;
      };
    }
    case Ops.In: {
      return (context2) => {
        const value = args[0](context2);
        for (let i = 1; i < length; ++i) {
          if (value === args[i](context2)) {
            return true;
          }
        }
        return false;
      };
    }
    case Ops.Not: {
      return (context2) => !args[0](context2);
    }
    default: {
      throw new Error(`Unsupported logical operator ${op}`);
    }
  }
}
function compileNumericExpression(expression, context) {
  const op = expression.operator;
  const length = expression.args.length;
  const args = new Array(length);
  for (let i = 0; i < length; ++i) {
    args[i] = compileExpression(expression.args[i]);
  }
  switch (op) {
    case Ops.Multiply: {
      return (context2) => {
        let value = 1;
        for (let i = 0; i < length; ++i) {
          value *= args[i](context2);
        }
        return value;
      };
    }
    case Ops.Divide: {
      return (context2) => args[0](context2) / args[1](context2);
    }
    case Ops.Add: {
      return (context2) => {
        let value = 0;
        for (let i = 0; i < length; ++i) {
          value += args[i](context2);
        }
        return value;
      };
    }
    case Ops.Subtract: {
      return (context2) => args[0](context2) - args[1](context2);
    }
    case Ops.Clamp: {
      return (context2) => {
        const value = args[0](context2);
        const min = args[1](context2);
        if (value < min) {
          return min;
        }
        const max = args[2](context2);
        if (value > max) {
          return max;
        }
        return value;
      };
    }
    case Ops.Mod: {
      return (context2) => args[0](context2) % args[1](context2);
    }
    case Ops.Pow: {
      return (context2) => Math.pow(args[0](context2), args[1](context2));
    }
    case Ops.Abs: {
      return (context2) => Math.abs(args[0](context2));
    }
    case Ops.Floor: {
      return (context2) => Math.floor(args[0](context2));
    }
    case Ops.Ceil: {
      return (context2) => Math.ceil(args[0](context2));
    }
    case Ops.Round: {
      return (context2) => Math.round(args[0](context2));
    }
    case Ops.Sin: {
      return (context2) => Math.sin(args[0](context2));
    }
    case Ops.Cos: {
      return (context2) => Math.cos(args[0](context2));
    }
    case Ops.Atan: {
      if (length === 2) {
        return (context2) => Math.atan2(args[0](context2), args[1](context2));
      }
      return (context2) => Math.atan(args[0](context2));
    }
    case Ops.Sqrt: {
      return (context2) => Math.sqrt(args[0](context2));
    }
    default: {
      throw new Error(`Unsupported numeric operator ${op}`);
    }
  }
}
function compileCaseExpression(expression, context) {
  const length = expression.args.length;
  const args = new Array(length);
  for (let i = 0; i < length; ++i) {
    args[i] = compileExpression(expression.args[i]);
  }
  return (context2) => {
    for (let i = 0; i < length - 1; i += 2) {
      const condition = args[i](context2);
      if (condition) {
        return args[i + 1](context2);
      }
    }
    return args[length - 1](context2);
  };
}
function compileMatchExpression(expression, context) {
  const length = expression.args.length;
  const args = new Array(length);
  for (let i = 0; i < length; ++i) {
    args[i] = compileExpression(expression.args[i]);
  }
  return (context2) => {
    const value = args[0](context2);
    for (let i = 1; i < length - 1; i += 2) {
      if (value === args[i](context2)) {
        return args[i + 1](context2);
      }
    }
    return args[length - 1](context2);
  };
}
function compileInterpolateExpression(expression, context) {
  const length = expression.args.length;
  const args = new Array(length);
  for (let i = 0; i < length; ++i) {
    args[i] = compileExpression(expression.args[i]);
  }
  return (context2) => {
    const base = args[0](context2);
    const value = args[1](context2);
    let previousInput;
    let previousOutput;
    for (let i = 2; i < length; i += 2) {
      const input = args[i](context2);
      let output = args[i + 1](context2);
      const isColor = Array.isArray(output);
      if (isColor) {
        output = withAlpha(output);
      }
      if (input >= value) {
        if (i === 2) {
          return output;
        }
        if (isColor) {
          return interpolateColor(
            base,
            value,
            previousInput,
            previousOutput,
            input,
            output
          );
        }
        return interpolateNumber(
          base,
          value,
          previousInput,
          previousOutput,
          input,
          output
        );
      }
      previousInput = input;
      previousOutput = output;
    }
    return previousOutput;
  };
}
function compileConvertExpression(expression, context) {
  const op = expression.operator;
  const length = expression.args.length;
  const args = new Array(length);
  for (let i = 0; i < length; ++i) {
    args[i] = compileExpression(expression.args[i]);
  }
  switch (op) {
    case Ops.ToString: {
      return (context2) => {
        const value = args[0](context2);
        if (expression.args[0].type === ColorType) {
          return toString(value);
        }
        return value.toString();
      };
    }
    default: {
      throw new Error(`Unsupported convert operator ${op}`);
    }
  }
}
function interpolateNumber(base, value, input1, output1, input2, output2) {
  const delta = input2 - input1;
  if (delta === 0) {
    return output1;
  }
  const along = value - input1;
  const factor = base === 1 ? along / delta : (Math.pow(base, along) - 1) / (Math.pow(base, delta) - 1);
  return output1 + factor * (output2 - output1);
}
function interpolateColor(base, value, input1, rgba1, input2, rgba2) {
  const delta = input2 - input1;
  if (delta === 0) {
    return rgba1;
  }
  const lcha1 = rgbaToLcha(rgba1);
  const lcha2 = rgbaToLcha(rgba2);
  let deltaHue = lcha2[2] - lcha1[2];
  if (deltaHue > 180) {
    deltaHue -= 360;
  } else if (deltaHue < -180) {
    deltaHue += 360;
  }
  const lcha = [
    interpolateNumber(base, value, input1, lcha1[0], input2, lcha2[0]),
    interpolateNumber(base, value, input1, lcha1[1], input2, lcha2[1]),
    lcha1[2] + interpolateNumber(base, value, input1, 0, input2, deltaHue),
    interpolateNumber(base, value, input1, rgba1[3], input2, rgba2[3])
  ];
  return lchaToRgba(lcha);
}
function always(context) {
  return true;
}
function rulesToStyleFunction(rules) {
  const parsingContext = newParsingContext();
  const evaluator = buildRuleSet(rules, parsingContext);
  const evaluationContext = newEvaluationContext();
  return function(feature2, resolution) {
    evaluationContext.properties = feature2.getPropertiesInternal();
    evaluationContext.resolution = resolution;
    if (parsingContext.featureId) {
      const id = feature2.getId();
      if (id !== void 0) {
        evaluationContext.featureId = id;
      } else {
        evaluationContext.featureId = null;
      }
    }
    if (parsingContext.geometryType) {
      evaluationContext.geometryType = computeGeometryType(
        feature2.getGeometry()
      );
    }
    return evaluator(evaluationContext);
  };
}
function flatStylesToStyleFunction(flatStyles) {
  const parsingContext = newParsingContext();
  const length = flatStyles.length;
  const evaluators = new Array(length);
  for (let i = 0; i < length; ++i) {
    evaluators[i] = buildStyle(flatStyles[i], parsingContext);
  }
  const evaluationContext = newEvaluationContext();
  const styles = new Array(length);
  return function(feature2, resolution) {
    evaluationContext.properties = feature2.getPropertiesInternal();
    evaluationContext.resolution = resolution;
    if (parsingContext.featureId) {
      const id = feature2.getId();
      if (id !== void 0) {
        evaluationContext.featureId = id;
      } else {
        evaluationContext.featureId = null;
      }
    }
    let nonNullCount = 0;
    for (let i = 0; i < length; ++i) {
      const style = evaluators[i](evaluationContext);
      if (style) {
        styles[nonNullCount] = style;
        nonNullCount += 1;
      }
    }
    styles.length = nonNullCount;
    return styles;
  };
}
function buildRuleSet(rules, context) {
  const length = rules.length;
  const compiledRules = new Array(length);
  for (let i = 0; i < length; ++i) {
    const rule = rules[i];
    const filter = "filter" in rule ? buildExpression(rule.filter, BooleanType, context) : always;
    let styles;
    if (Array.isArray(rule.style)) {
      const styleLength = rule.style.length;
      styles = new Array(styleLength);
      for (let j = 0; j < styleLength; ++j) {
        styles[j] = buildStyle(rule.style[j], context);
      }
    } else {
      styles = [buildStyle(rule.style, context)];
    }
    compiledRules[i] = { filter, styles };
  }
  return function(context2) {
    const styles = [];
    let someMatched = false;
    for (let i = 0; i < length; ++i) {
      const filterEvaluator = compiledRules[i].filter;
      if (!filterEvaluator(context2)) {
        continue;
      }
      if (rules[i].else && someMatched) {
        continue;
      }
      someMatched = true;
      for (const styleEvaluator of compiledRules[i].styles) {
        const style = styleEvaluator(context2);
        if (!style) {
          continue;
        }
        styles.push(style);
      }
    }
    return styles;
  };
}
function buildStyle(flatStyle, context) {
  const evaluateFill = buildFill(flatStyle, "", context);
  const evaluateStroke = buildStroke(flatStyle, "", context);
  const evaluateText = buildText(flatStyle, context);
  const evaluateImage = buildImage(flatStyle, context);
  const evaluateZIndex = numberEvaluator(flatStyle, "z-index", context);
  if (!evaluateFill && !evaluateStroke && !evaluateText && !evaluateImage && !isEmpty$1(flatStyle)) {
    throw new Error(
      "No fill, stroke, point, or text symbolizer properties in style: " + JSON.stringify(flatStyle)
    );
  }
  const style = new Style();
  return function(context2) {
    let empty = true;
    if (evaluateFill) {
      const fill = evaluateFill(context2);
      if (fill) {
        empty = false;
      }
      style.setFill(fill);
    }
    if (evaluateStroke) {
      const stroke = evaluateStroke(context2);
      if (stroke) {
        empty = false;
      }
      style.setStroke(stroke);
    }
    if (evaluateText) {
      const text = evaluateText(context2);
      if (text) {
        empty = false;
      }
      style.setText(text);
    }
    if (evaluateImage) {
      const image = evaluateImage(context2);
      if (image) {
        empty = false;
      }
      style.setImage(image);
    }
    if (evaluateZIndex) {
      style.setZIndex(evaluateZIndex(context2));
    }
    if (empty) {
      return null;
    }
    return style;
  };
}
function buildFill(flatStyle, prefix, context) {
  let evaluateColor;
  if (prefix + "fill-pattern-src" in flatStyle) {
    evaluateColor = patternEvaluator(flatStyle, prefix + "fill-", context);
  } else {
    if (flatStyle[prefix + "fill-color"] === "none") {
      return (context2) => null;
    }
    evaluateColor = colorLikeEvaluator(
      flatStyle,
      prefix + "fill-color",
      context
    );
  }
  if (!evaluateColor) {
    return null;
  }
  const fill = new Fill$1();
  return function(context2) {
    const color = evaluateColor(context2);
    if (color === NO_COLOR) {
      return null;
    }
    fill.setColor(color);
    return fill;
  };
}
function buildStroke(flatStyle, prefix, context) {
  const evaluateWidth = numberEvaluator(
    flatStyle,
    prefix + "stroke-width",
    context
  );
  const evaluateColor = colorLikeEvaluator(
    flatStyle,
    prefix + "stroke-color",
    context
  );
  if (!evaluateWidth && !evaluateColor) {
    return null;
  }
  const evaluateLineCap = stringEvaluator(
    flatStyle,
    prefix + "stroke-line-cap",
    context
  );
  const evaluateLineJoin = stringEvaluator(
    flatStyle,
    prefix + "stroke-line-join",
    context
  );
  const evaluateLineDash = numberArrayEvaluator(
    flatStyle,
    prefix + "stroke-line-dash",
    context
  );
  const evaluateLineDashOffset = numberEvaluator(
    flatStyle,
    prefix + "stroke-line-dash-offset",
    context
  );
  const evaluateMiterLimit = numberEvaluator(
    flatStyle,
    prefix + "stroke-miter-limit",
    context
  );
  const stroke = new Stroke$1();
  return function(context2) {
    if (evaluateColor) {
      const color = evaluateColor(context2);
      if (color === NO_COLOR) {
        return null;
      }
      stroke.setColor(color);
    }
    if (evaluateWidth) {
      stroke.setWidth(evaluateWidth(context2));
    }
    if (evaluateLineCap) {
      const lineCap = evaluateLineCap(context2);
      if (lineCap !== "butt" && lineCap !== "round" && lineCap !== "square") {
        throw new Error("Expected butt, round, or square line cap");
      }
      stroke.setLineCap(lineCap);
    }
    if (evaluateLineJoin) {
      const lineJoin = evaluateLineJoin(context2);
      if (lineJoin !== "bevel" && lineJoin !== "round" && lineJoin !== "miter") {
        throw new Error("Expected bevel, round, or miter line join");
      }
      stroke.setLineJoin(lineJoin);
    }
    if (evaluateLineDash) {
      stroke.setLineDash(evaluateLineDash(context2));
    }
    if (evaluateLineDashOffset) {
      stroke.setLineDashOffset(evaluateLineDashOffset(context2));
    }
    if (evaluateMiterLimit) {
      stroke.setMiterLimit(evaluateMiterLimit(context2));
    }
    return stroke;
  };
}
function buildText(flatStyle, context) {
  const prefix = "text-";
  const evaluateValue = stringEvaluator(flatStyle, prefix + "value", context);
  if (!evaluateValue) {
    return null;
  }
  const evaluateFill = buildFill(flatStyle, prefix, context);
  const evaluateBackgroundFill = buildFill(
    flatStyle,
    prefix + "background-",
    context
  );
  const evaluateStroke = buildStroke(flatStyle, prefix, context);
  const evaluateBackgroundStroke = buildStroke(
    flatStyle,
    prefix + "background-",
    context
  );
  const evaluateFont = stringEvaluator(flatStyle, prefix + "font", context);
  const evaluateMaxAngle = numberEvaluator(
    flatStyle,
    prefix + "max-angle",
    context
  );
  const evaluateOffsetX = numberEvaluator(
    flatStyle,
    prefix + "offset-x",
    context
  );
  const evaluateOffsetY = numberEvaluator(
    flatStyle,
    prefix + "offset-y",
    context
  );
  const evaluateOverflow = booleanEvaluator(
    flatStyle,
    prefix + "overflow",
    context
  );
  const evaluatePlacement = stringEvaluator(
    flatStyle,
    prefix + "placement",
    context
  );
  const evaluateRepeat = numberEvaluator(flatStyle, prefix + "repeat", context);
  const evaluateScale = sizeLikeEvaluator(flatStyle, prefix + "scale", context);
  const evaluateRotateWithView = booleanEvaluator(
    flatStyle,
    prefix + "rotate-with-view",
    context
  );
  const evaluateRotation = numberEvaluator(
    flatStyle,
    prefix + "rotation",
    context
  );
  const evaluateAlign = stringEvaluator(flatStyle, prefix + "align", context);
  const evaluateJustify = stringEvaluator(
    flatStyle,
    prefix + "justify",
    context
  );
  const evaluateBaseline = stringEvaluator(
    flatStyle,
    prefix + "baseline",
    context
  );
  const evaluateKeepUpright = booleanEvaluator(
    flatStyle,
    prefix + "keep-upright",
    context
  );
  const evaluatePadding = numberArrayEvaluator(
    flatStyle,
    prefix + "padding",
    context
  );
  const declutterMode = optionalDeclutterMode(
    flatStyle,
    prefix + "declutter-mode"
  );
  const text = new Text$1({ declutterMode });
  return function(context2) {
    text.setText(evaluateValue(context2));
    if (evaluateFill) {
      text.setFill(evaluateFill(context2));
    }
    if (evaluateBackgroundFill) {
      text.setBackgroundFill(evaluateBackgroundFill(context2));
    }
    if (evaluateStroke) {
      text.setStroke(evaluateStroke(context2));
    }
    if (evaluateBackgroundStroke) {
      text.setBackgroundStroke(evaluateBackgroundStroke(context2));
    }
    if (evaluateFont) {
      text.setFont(evaluateFont(context2));
    }
    if (evaluateMaxAngle) {
      text.setMaxAngle(evaluateMaxAngle(context2));
    }
    if (evaluateOffsetX) {
      text.setOffsetX(evaluateOffsetX(context2));
    }
    if (evaluateOffsetY) {
      text.setOffsetY(evaluateOffsetY(context2));
    }
    if (evaluateOverflow) {
      text.setOverflow(evaluateOverflow(context2));
    }
    if (evaluatePlacement) {
      const placement = evaluatePlacement(context2);
      if (placement !== "point" && placement !== "line") {
        throw new Error("Expected point or line for text-placement");
      }
      text.setPlacement(placement);
    }
    if (evaluateRepeat) {
      text.setRepeat(evaluateRepeat(context2));
    }
    if (evaluateScale) {
      text.setScale(evaluateScale(context2));
    }
    if (evaluateRotateWithView) {
      text.setRotateWithView(evaluateRotateWithView(context2));
    }
    if (evaluateRotation) {
      text.setRotation(evaluateRotation(context2));
    }
    if (evaluateAlign) {
      const textAlign = evaluateAlign(context2);
      if (textAlign !== "left" && textAlign !== "center" && textAlign !== "right" && textAlign !== "end" && textAlign !== "start") {
        throw new Error(
          "Expected left, right, center, start, or end for text-align"
        );
      }
      text.setTextAlign(textAlign);
    }
    if (evaluateJustify) {
      const justify = evaluateJustify(context2);
      if (justify !== "left" && justify !== "right" && justify !== "center") {
        throw new Error("Expected left, right, or center for text-justify");
      }
      text.setJustify(justify);
    }
    if (evaluateBaseline) {
      const textBaseline = evaluateBaseline(context2);
      if (textBaseline !== "bottom" && textBaseline !== "top" && textBaseline !== "middle" && textBaseline !== "alphabetic" && textBaseline !== "hanging") {
        throw new Error(
          "Expected bottom, top, middle, alphabetic, or hanging for text-baseline"
        );
      }
      text.setTextBaseline(textBaseline);
    }
    if (evaluatePadding) {
      text.setPadding(evaluatePadding(context2));
    }
    if (evaluateKeepUpright) {
      text.setKeepUpright(evaluateKeepUpright(context2));
    }
    return text;
  };
}
function buildImage(flatStyle, context) {
  if ("icon-src" in flatStyle) {
    return buildIcon(flatStyle, context);
  }
  if ("shape-points" in flatStyle) {
    return buildShape(flatStyle, context);
  }
  if ("circle-radius" in flatStyle) {
    return buildCircle(flatStyle, context);
  }
  return null;
}
function buildIcon(flatStyle, context) {
  const prefix = "icon-";
  const srcName = prefix + "src";
  const src = requireString(flatStyle[srcName], srcName);
  const evaluateAnchor = coordinateEvaluator(
    flatStyle,
    prefix + "anchor",
    context
  );
  const evaluateScale = sizeLikeEvaluator(flatStyle, prefix + "scale", context);
  const evaluateOpacity = numberEvaluator(
    flatStyle,
    prefix + "opacity",
    context
  );
  const evaluateDisplacement = coordinateEvaluator(
    flatStyle,
    prefix + "displacement",
    context
  );
  const evaluateRotation = numberEvaluator(
    flatStyle,
    prefix + "rotation",
    context
  );
  const evaluateRotateWithView = booleanEvaluator(
    flatStyle,
    prefix + "rotate-with-view",
    context
  );
  const anchorOrigin = optionalIconOrigin(flatStyle, prefix + "anchor-origin");
  const anchorXUnits = optionalIconAnchorUnits(
    flatStyle,
    prefix + "anchor-x-units"
  );
  const anchorYUnits = optionalIconAnchorUnits(
    flatStyle,
    prefix + "anchor-y-units"
  );
  const color = optionalColorLike(flatStyle, prefix + "color");
  const crossOrigin = optionalString(flatStyle, prefix + "cross-origin");
  const offset = optionalNumberArray(flatStyle, prefix + "offset");
  const offsetOrigin = optionalIconOrigin(flatStyle, prefix + "offset-origin");
  const width = optionalNumber(flatStyle, prefix + "width");
  const height = optionalNumber(flatStyle, prefix + "height");
  const size = optionalSize(flatStyle, prefix + "size");
  const declutterMode = optionalDeclutterMode(
    flatStyle,
    prefix + "declutter-mode"
  );
  const icon = new Icon$1({
    src,
    anchorOrigin,
    anchorXUnits,
    anchorYUnits,
    color,
    crossOrigin,
    offset,
    offsetOrigin,
    height,
    width,
    size,
    declutterMode
  });
  return function(context2) {
    if (evaluateOpacity) {
      icon.setOpacity(evaluateOpacity(context2));
    }
    if (evaluateDisplacement) {
      icon.setDisplacement(evaluateDisplacement(context2));
    }
    if (evaluateRotation) {
      icon.setRotation(evaluateRotation(context2));
    }
    if (evaluateRotateWithView) {
      icon.setRotateWithView(evaluateRotateWithView(context2));
    }
    if (evaluateScale) {
      icon.setScale(evaluateScale(context2));
    }
    if (evaluateAnchor) {
      icon.setAnchor(evaluateAnchor(context2));
    }
    return icon;
  };
}
function buildShape(flatStyle, context) {
  const prefix = "shape-";
  const pointsName = prefix + "points";
  const radiusName = prefix + "radius";
  const points = requireNumber(flatStyle[pointsName], pointsName);
  const radius = requireNumber(flatStyle[radiusName], radiusName);
  const evaluateFill = buildFill(flatStyle, prefix, context);
  const evaluateStroke = buildStroke(flatStyle, prefix, context);
  const evaluateScale = sizeLikeEvaluator(flatStyle, prefix + "scale", context);
  const evaluateDisplacement = coordinateEvaluator(
    flatStyle,
    prefix + "displacement",
    context
  );
  const evaluateRotation = numberEvaluator(
    flatStyle,
    prefix + "rotation",
    context
  );
  const evaluateRotateWithView = booleanEvaluator(
    flatStyle,
    prefix + "rotate-with-view",
    context
  );
  const radius2 = optionalNumber(flatStyle, prefix + "radius2");
  const angle = optionalNumber(flatStyle, prefix + "angle");
  const declutterMode = optionalDeclutterMode(
    flatStyle,
    prefix + "declutter-mode"
  );
  const shape = new RegularShape$1({
    points,
    radius,
    radius2,
    angle,
    declutterMode
  });
  return function(context2) {
    if (evaluateFill) {
      shape.setFill(evaluateFill(context2));
    }
    if (evaluateStroke) {
      shape.setStroke(evaluateStroke(context2));
    }
    if (evaluateDisplacement) {
      shape.setDisplacement(evaluateDisplacement(context2));
    }
    if (evaluateRotation) {
      shape.setRotation(evaluateRotation(context2));
    }
    if (evaluateRotateWithView) {
      shape.setRotateWithView(evaluateRotateWithView(context2));
    }
    if (evaluateScale) {
      shape.setScale(evaluateScale(context2));
    }
    return shape;
  };
}
function buildCircle(flatStyle, context) {
  const prefix = "circle-";
  const evaluateFill = buildFill(flatStyle, prefix, context);
  const evaluateStroke = buildStroke(flatStyle, prefix, context);
  const evaluateRadius = numberEvaluator(flatStyle, prefix + "radius", context);
  const evaluateScale = sizeLikeEvaluator(flatStyle, prefix + "scale", context);
  const evaluateDisplacement = coordinateEvaluator(
    flatStyle,
    prefix + "displacement",
    context
  );
  const evaluateRotation = numberEvaluator(
    flatStyle,
    prefix + "rotation",
    context
  );
  const evaluateRotateWithView = booleanEvaluator(
    flatStyle,
    prefix + "rotate-with-view",
    context
  );
  const declutterMode = optionalDeclutterMode(
    flatStyle,
    prefix + "declutter-mode"
  );
  const circle = new Circle({
    radius: 5,
    declutterMode
  });
  return function(context2) {
    if (evaluateRadius) {
      circle.setRadius(evaluateRadius(context2));
    }
    if (evaluateFill) {
      circle.setFill(evaluateFill(context2));
    }
    if (evaluateStroke) {
      circle.setStroke(evaluateStroke(context2));
    }
    if (evaluateDisplacement) {
      circle.setDisplacement(evaluateDisplacement(context2));
    }
    if (evaluateRotation) {
      circle.setRotation(evaluateRotation(context2));
    }
    if (evaluateRotateWithView) {
      circle.setRotateWithView(evaluateRotateWithView(context2));
    }
    if (evaluateScale) {
      circle.setScale(evaluateScale(context2));
    }
    return circle;
  };
}
function numberEvaluator(flatStyle, name, context) {
  if (!(name in flatStyle)) {
    return void 0;
  }
  const evaluator = buildExpression(flatStyle[name], NumberType, context);
  return function(context2) {
    return requireNumber(evaluator(context2), name);
  };
}
function stringEvaluator(flatStyle, name, context) {
  if (!(name in flatStyle)) {
    return null;
  }
  const evaluator = buildExpression(flatStyle[name], StringType, context);
  return function(context2) {
    return requireString(evaluator(context2), name);
  };
}
function patternEvaluator(flatStyle, prefix, context) {
  const srcEvaluator = stringEvaluator(
    flatStyle,
    prefix + "pattern-src",
    context
  );
  const offsetEvaluator = sizeEvaluator(
    flatStyle,
    prefix + "pattern-offset",
    context
  );
  const patternSizeEvaluator = sizeEvaluator(
    flatStyle,
    prefix + "pattern-size",
    context
  );
  const colorEvaluator = colorLikeEvaluator(
    flatStyle,
    prefix + "color",
    context
  );
  return function(context2) {
    return {
      src: srcEvaluator(context2),
      offset: offsetEvaluator && offsetEvaluator(context2),
      size: patternSizeEvaluator && patternSizeEvaluator(context2),
      color: colorEvaluator && colorEvaluator(context2)
    };
  };
}
function booleanEvaluator(flatStyle, name, context) {
  if (!(name in flatStyle)) {
    return null;
  }
  const evaluator = buildExpression(flatStyle[name], BooleanType, context);
  return function(context2) {
    const value = evaluator(context2);
    if (typeof value !== "boolean") {
      throw new Error(`Expected a boolean for ${name}`);
    }
    return value;
  };
}
function colorLikeEvaluator(flatStyle, name, context) {
  if (!(name in flatStyle)) {
    return null;
  }
  const evaluator = buildExpression(flatStyle[name], ColorType, context);
  return function(context2) {
    return requireColorLike(evaluator(context2), name);
  };
}
function numberArrayEvaluator(flatStyle, name, context) {
  if (!(name in flatStyle)) {
    return null;
  }
  const evaluator = buildExpression(flatStyle[name], NumberArrayType, context);
  return function(context2) {
    return requireNumberArray(evaluator(context2), name);
  };
}
function coordinateEvaluator(flatStyle, name, context) {
  if (!(name in flatStyle)) {
    return null;
  }
  const evaluator = buildExpression(flatStyle[name], NumberArrayType, context);
  return function(context2) {
    const array = requireNumberArray(evaluator(context2), name);
    if (array.length !== 2) {
      throw new Error(`Expected two numbers for ${name}`);
    }
    return array;
  };
}
function sizeEvaluator(flatStyle, name, context) {
  if (!(name in flatStyle)) {
    return null;
  }
  const evaluator = buildExpression(flatStyle[name], NumberArrayType, context);
  return function(context2) {
    return requireSize(evaluator(context2), name);
  };
}
function sizeLikeEvaluator(flatStyle, name, context) {
  if (!(name in flatStyle)) {
    return null;
  }
  const evaluator = buildExpression(
    flatStyle[name],
    NumberArrayType | NumberType,
    context
  );
  return function(context2) {
    return requireSizeLike(evaluator(context2), name);
  };
}
function optionalNumber(flatStyle, property) {
  const value = flatStyle[property];
  if (value === void 0) {
    return void 0;
  }
  if (typeof value !== "number") {
    throw new Error(`Expected a number for ${property}`);
  }
  return value;
}
function optionalSize(flatStyle, property) {
  const encoded = flatStyle[property];
  if (encoded === void 0) {
    return void 0;
  }
  if (typeof encoded === "number") {
    return toSize(encoded);
  }
  if (!Array.isArray(encoded)) {
    throw new Error(`Expected a number or size array for ${property}`);
  }
  if (encoded.length !== 2 || typeof encoded[0] !== "number" || typeof encoded[1] !== "number") {
    throw new Error(`Expected a number or size array for ${property}`);
  }
  return encoded;
}
function optionalString(flatStyle, property) {
  const encoded = flatStyle[property];
  if (encoded === void 0) {
    return void 0;
  }
  if (typeof encoded !== "string") {
    throw new Error(`Expected a string for ${property}`);
  }
  return encoded;
}
function optionalIconOrigin(flatStyle, property) {
  const encoded = flatStyle[property];
  if (encoded === void 0) {
    return void 0;
  }
  if (encoded !== "bottom-left" && encoded !== "bottom-right" && encoded !== "top-left" && encoded !== "top-right") {
    throw new Error(
      `Expected bottom-left, bottom-right, top-left, or top-right for ${property}`
    );
  }
  return encoded;
}
function optionalIconAnchorUnits(flatStyle, property) {
  const encoded = flatStyle[property];
  if (encoded === void 0) {
    return void 0;
  }
  if (encoded !== "pixels" && encoded !== "fraction") {
    throw new Error(`Expected pixels or fraction for ${property}`);
  }
  return encoded;
}
function optionalNumberArray(flatStyle, property) {
  const encoded = flatStyle[property];
  if (encoded === void 0) {
    return void 0;
  }
  return requireNumberArray(encoded, property);
}
function optionalDeclutterMode(flatStyle, property) {
  const encoded = flatStyle[property];
  if (encoded === void 0) {
    return void 0;
  }
  if (typeof encoded !== "string") {
    throw new Error(`Expected a string for ${property}`);
  }
  if (encoded !== "declutter" && encoded !== "obstacle" && encoded !== "none") {
    throw new Error(`Expected declutter, obstacle, or none for ${property}`);
  }
  return encoded;
}
function optionalColorLike(flatStyle, property) {
  const encoded = flatStyle[property];
  if (encoded === void 0) {
    return void 0;
  }
  return requireColorLike(encoded, property);
}
function requireNumberArray(value, property) {
  if (!Array.isArray(value)) {
    throw new Error(`Expected an array for ${property}`);
  }
  const length = value.length;
  for (let i = 0; i < length; ++i) {
    if (typeof value[i] !== "number") {
      throw new Error(`Expected an array of numbers for ${property}`);
    }
  }
  return value;
}
function requireString(value, property) {
  if (typeof value !== "string") {
    throw new Error(`Expected a string for ${property}`);
  }
  return value;
}
function requireNumber(value, property) {
  if (typeof value !== "number") {
    throw new Error(`Expected a number for ${property}`);
  }
  return value;
}
function requireColorLike(value, property) {
  if (typeof value === "string") {
    return value;
  }
  const array = requireNumberArray(value, property);
  const length = array.length;
  if (length < 3 || length > 4) {
    throw new Error(`Expected a color with 3 or 4 values for ${property}`);
  }
  return array;
}
function requireSize(value, property) {
  const size = requireNumberArray(value, property);
  if (size.length !== 2) {
    throw new Error(`Expected an array of two numbers for ${property}`);
  }
  return size;
}
function requireSizeLike(value, property) {
  if (typeof value === "number") {
    return value;
  }
  return requireSize(value, property);
}
const ViewProperty = {
  CENTER: "center",
  RESOLUTION: "resolution",
  ROTATION: "rotation"
};
function createExtent(extent, onlyCenter, smooth) {
  return function(center, resolution, size, isMoving, centerShift) {
    if (!center) {
      return void 0;
    }
    if (!resolution && !onlyCenter) {
      return center;
    }
    const viewWidth = onlyCenter ? 0 : size[0] * resolution;
    const viewHeight = onlyCenter ? 0 : size[1] * resolution;
    const shiftX = centerShift ? centerShift[0] : 0;
    const shiftY = centerShift ? centerShift[1] : 0;
    let minX = extent[0] + viewWidth / 2 + shiftX;
    let maxX = extent[2] - viewWidth / 2 + shiftX;
    let minY = extent[1] + viewHeight / 2 + shiftY;
    let maxY = extent[3] - viewHeight / 2 + shiftY;
    if (minX > maxX) {
      minX = (maxX + minX) / 2;
      maxX = minX;
    }
    if (minY > maxY) {
      minY = (maxY + minY) / 2;
      maxY = minY;
    }
    let x = clamp(center[0], minX, maxX);
    let y = clamp(center[1], minY, maxY);
    if (isMoving && smooth && resolution) {
      const ratio = 30 * resolution;
      x += -ratio * Math.log(1 + Math.max(0, minX - center[0]) / ratio) + ratio * Math.log(1 + Math.max(0, center[0] - maxX) / ratio);
      y += -ratio * Math.log(1 + Math.max(0, minY - center[1]) / ratio) + ratio * Math.log(1 + Math.max(0, center[1] - maxY) / ratio);
    }
    return [x, y];
  };
}
function none$1(center) {
  return center;
}
function easeIn(t) {
  return Math.pow(t, 3);
}
function easeOut(t) {
  return 1 - easeIn(1 - t);
}
function inAndOut(t) {
  return 3 * t * t - 2 * t * t * t;
}
function getViewportClampedResolution(resolution, maxExtent, viewportSize, showFullExtent) {
  const xResolution = getWidth(maxExtent) / viewportSize[0];
  const yResolution = getHeight(maxExtent) / viewportSize[1];
  if (showFullExtent) {
    return Math.min(resolution, Math.max(xResolution, yResolution));
  }
  return Math.min(resolution, Math.min(xResolution, yResolution));
}
function getSmoothClampedResolution(resolution, maxResolution, minResolution) {
  let result = Math.min(resolution, maxResolution);
  const ratio = 50;
  result *= Math.log(1 + ratio * Math.max(0, resolution / maxResolution - 1)) / ratio + 1;
  if (minResolution) {
    result = Math.max(result, minResolution);
    result /= Math.log(1 + ratio * Math.max(0, minResolution / resolution - 1)) / ratio + 1;
  }
  return clamp(result, minResolution / 2, maxResolution * 2);
}
function createSnapToResolutions(resolutions, smooth, maxExtent, showFullExtent) {
  smooth = smooth !== void 0 ? smooth : true;
  return function(resolution, direction, size, isMoving) {
    if (resolution !== void 0) {
      const maxResolution = resolutions[0];
      const minResolution = resolutions[resolutions.length - 1];
      const cappedMaxRes = maxExtent ? getViewportClampedResolution(
        maxResolution,
        maxExtent,
        size,
        showFullExtent
      ) : maxResolution;
      if (isMoving) {
        if (!smooth) {
          return clamp(resolution, minResolution, cappedMaxRes);
        }
        return getSmoothClampedResolution(
          resolution,
          cappedMaxRes,
          minResolution
        );
      }
      const capped = Math.min(cappedMaxRes, resolution);
      const z = Math.floor(linearFindNearest(resolutions, capped, direction));
      if (resolutions[z] > cappedMaxRes && z < resolutions.length - 1) {
        return resolutions[z + 1];
      }
      return resolutions[z];
    }
    return void 0;
  };
}
function createSnapToPower(power, maxResolution, minResolution, smooth, maxExtent, showFullExtent) {
  smooth = smooth !== void 0 ? smooth : true;
  minResolution = minResolution !== void 0 ? minResolution : 0;
  return function(resolution, direction, size, isMoving) {
    if (resolution !== void 0) {
      const cappedMaxRes = maxExtent ? getViewportClampedResolution(
        maxResolution,
        maxExtent,
        size,
        showFullExtent
      ) : maxResolution;
      if (isMoving) {
        if (!smooth) {
          return clamp(resolution, minResolution, cappedMaxRes);
        }
        return getSmoothClampedResolution(
          resolution,
          cappedMaxRes,
          minResolution
        );
      }
      const tolerance = 1e-9;
      const minZoomLevel = Math.ceil(
        Math.log(maxResolution / cappedMaxRes) / Math.log(power) - tolerance
      );
      const offset = -direction * (0.5 - tolerance) + 0.5;
      const capped = Math.min(cappedMaxRes, resolution);
      const cappedZoomLevel = Math.floor(
        Math.log(maxResolution / capped) / Math.log(power) + offset
      );
      const zoomLevel = Math.max(minZoomLevel, cappedZoomLevel);
      const newResolution = maxResolution / Math.pow(power, zoomLevel);
      return clamp(newResolution, minResolution, cappedMaxRes);
    }
    return void 0;
  };
}
function createMinMaxResolution(maxResolution, minResolution, smooth, maxExtent, showFullExtent) {
  smooth = smooth !== void 0 ? smooth : true;
  return function(resolution, direction, size, isMoving) {
    if (resolution !== void 0) {
      const cappedMaxRes = maxExtent ? getViewportClampedResolution(
        maxResolution,
        maxExtent,
        size,
        showFullExtent
      ) : maxResolution;
      if (!smooth || !isMoving) {
        return clamp(resolution, minResolution, cappedMaxRes);
      }
      return getSmoothClampedResolution(
        resolution,
        cappedMaxRes,
        minResolution
      );
    }
    return void 0;
  };
}
function disable(rotation) {
  if (rotation !== void 0) {
    return 0;
  }
  return void 0;
}
function none(rotation) {
  if (rotation !== void 0) {
    return rotation;
  }
  return void 0;
}
function createSnapToN(n) {
  const theta = 2 * Math.PI / n;
  return function(rotation, isMoving) {
    if (isMoving) {
      return rotation;
    }
    if (rotation !== void 0) {
      rotation = Math.floor(rotation / theta + 0.5) * theta;
      return rotation;
    }
    return void 0;
  };
}
function createSnapToZero(tolerance) {
  const t = tolerance === void 0 ? toRadians(5) : tolerance;
  return function(rotation, isMoving) {
    if (isMoving || rotation === void 0) {
      return rotation;
    }
    if (Math.abs(rotation) <= t) {
      return 0;
    }
    return rotation;
  };
}
const DEFAULT_TILE_SIZE = 256;
const DEFAULT_MIN_ZOOM = 0;
class View extends BaseObject$1 {
  constructor(options) {
    super();
    this.on;
    this.once;
    this.un;
    options = Object.assign({}, options);
    this.hints_ = [0, 0];
    this.animations_ = [];
    this.updateAnimationKey_;
    this.projection_ = createProjection(options.projection, "EPSG:3857");
    this.viewportSize_ = [100, 100];
    this.targetCenter_ = null;
    this.targetResolution_;
    this.targetRotation_;
    this.nextCenter_ = null;
    this.nextResolution_;
    this.nextRotation_;
    this.cancelAnchor_ = void 0;
    if (options.projection) {
      disableCoordinateWarning();
    }
    if (options.center) {
      options.center = fromUserCoordinate(options.center, this.projection_);
    }
    if (options.extent) {
      options.extent = fromUserExtent(options.extent, this.projection_);
    }
    this.applyOptions_(options);
  }
  applyOptions_(options) {
    const properties = Object.assign({}, options);
    for (const key in ViewProperty) {
      delete properties[key];
    }
    this.setProperties(properties, true);
    const resolutionConstraintInfo = createResolutionConstraint(options);
    this.maxResolution_ = resolutionConstraintInfo.maxResolution;
    this.minResolution_ = resolutionConstraintInfo.minResolution;
    this.zoomFactor_ = resolutionConstraintInfo.zoomFactor;
    this.resolutions_ = options.resolutions;
    this.padding_ = options.padding;
    this.minZoom_ = resolutionConstraintInfo.minZoom;
    const centerConstraint = createCenterConstraint(options);
    const resolutionConstraint = resolutionConstraintInfo.constraint;
    const rotationConstraint = createRotationConstraint(options);
    this.constraints_ = {
      center: centerConstraint,
      resolution: resolutionConstraint,
      rotation: rotationConstraint
    };
    this.setRotation(options.rotation !== void 0 ? options.rotation : 0);
    this.setCenterInternal(
      options.center !== void 0 ? options.center : null
    );
    if (options.resolution !== void 0) {
      this.setResolution(options.resolution);
    } else if (options.zoom !== void 0) {
      this.setZoom(options.zoom);
    }
  }
  get padding() {
    return this.padding_;
  }
  set padding(padding) {
    let oldPadding = this.padding_;
    this.padding_ = padding;
    const center = this.getCenterInternal();
    if (center) {
      const newPadding = padding || [0, 0, 0, 0];
      oldPadding = oldPadding || [0, 0, 0, 0];
      const resolution = this.getResolution();
      const offsetX = resolution / 2 * (newPadding[3] - oldPadding[3] + oldPadding[1] - newPadding[1]);
      const offsetY = resolution / 2 * (newPadding[0] - oldPadding[0] + oldPadding[2] - newPadding[2]);
      this.setCenterInternal([center[0] + offsetX, center[1] - offsetY]);
    }
  }
  getUpdatedOptions_(newOptions) {
    const options = this.getProperties();
    if (options.resolution !== void 0) {
      options.resolution = this.getResolution();
    } else {
      options.zoom = this.getZoom();
    }
    options.center = this.getCenterInternal();
    options.rotation = this.getRotation();
    return Object.assign({}, options, newOptions);
  }
  animate(var_args) {
    if (this.isDef() && !this.getAnimating()) {
      this.resolveConstraints(0);
    }
    const args = new Array(arguments.length);
    for (let i = 0; i < args.length; ++i) {
      let options = arguments[i];
      if (options.center) {
        options = Object.assign({}, options);
        options.center = fromUserCoordinate(
          options.center,
          this.getProjection()
        );
      }
      if (options.anchor) {
        options = Object.assign({}, options);
        options.anchor = fromUserCoordinate(
          options.anchor,
          this.getProjection()
        );
      }
      args[i] = options;
    }
    this.animateInternal.apply(this, args);
  }
  animateInternal(var_args) {
    let animationCount = arguments.length;
    let callback;
    if (animationCount > 1 && typeof arguments[animationCount - 1] === "function") {
      callback = arguments[animationCount - 1];
      --animationCount;
    }
    let i = 0;
    for (; i < animationCount && !this.isDef(); ++i) {
      const state = arguments[i];
      if (state.center) {
        this.setCenterInternal(state.center);
      }
      if (state.zoom !== void 0) {
        this.setZoom(state.zoom);
      } else if (state.resolution) {
        this.setResolution(state.resolution);
      }
      if (state.rotation !== void 0) {
        this.setRotation(state.rotation);
      }
    }
    if (i === animationCount) {
      if (callback) {
        animationCallback(callback, true);
      }
      return;
    }
    let start = Date.now();
    let center = this.targetCenter_.slice();
    let resolution = this.targetResolution_;
    let rotation = this.targetRotation_;
    const series = [];
    for (; i < animationCount; ++i) {
      const options = arguments[i];
      const animation = {
        start,
        complete: false,
        anchor: options.anchor,
        duration: options.duration !== void 0 ? options.duration : 1e3,
        easing: options.easing || inAndOut,
        callback
      };
      if (options.center) {
        animation.sourceCenter = center;
        animation.targetCenter = options.center.slice();
        center = animation.targetCenter;
      }
      if (options.zoom !== void 0) {
        animation.sourceResolution = resolution;
        animation.targetResolution = this.getResolutionForZoom(options.zoom);
        resolution = animation.targetResolution;
      } else if (options.resolution) {
        animation.sourceResolution = resolution;
        animation.targetResolution = options.resolution;
        resolution = animation.targetResolution;
      }
      if (options.rotation !== void 0) {
        animation.sourceRotation = rotation;
        const delta = modulo(options.rotation - rotation + Math.PI, 2 * Math.PI) - Math.PI;
        animation.targetRotation = rotation + delta;
        rotation = animation.targetRotation;
      }
      if (isNoopAnimation(animation)) {
        animation.complete = true;
      } else {
        start += animation.duration;
      }
      series.push(animation);
    }
    this.animations_.push(series);
    this.setHint(ViewHint.ANIMATING, 1);
    this.updateAnimations_();
  }
  getAnimating() {
    return this.hints_[ViewHint.ANIMATING] > 0;
  }
  getInteracting() {
    return this.hints_[ViewHint.INTERACTING] > 0;
  }
  cancelAnimations() {
    this.setHint(ViewHint.ANIMATING, -this.hints_[ViewHint.ANIMATING]);
    let anchor;
    for (let i = 0, ii = this.animations_.length; i < ii; ++i) {
      const series = this.animations_[i];
      if (series[0].callback) {
        animationCallback(series[0].callback, false);
      }
      if (!anchor) {
        for (let j = 0, jj = series.length; j < jj; ++j) {
          const animation = series[j];
          if (!animation.complete) {
            anchor = animation.anchor;
            break;
          }
        }
      }
    }
    this.animations_.length = 0;
    this.cancelAnchor_ = anchor;
    this.nextCenter_ = null;
    this.nextResolution_ = NaN;
    this.nextRotation_ = NaN;
  }
  updateAnimations_() {
    if (this.updateAnimationKey_ !== void 0) {
      cancelAnimationFrame(this.updateAnimationKey_);
      this.updateAnimationKey_ = void 0;
    }
    if (!this.getAnimating()) {
      return;
    }
    const now = Date.now();
    let more = false;
    for (let i = this.animations_.length - 1; i >= 0; --i) {
      const series = this.animations_[i];
      let seriesComplete = true;
      for (let j = 0, jj = series.length; j < jj; ++j) {
        const animation = series[j];
        if (animation.complete) {
          continue;
        }
        const elapsed = now - animation.start;
        let fraction = animation.duration > 0 ? elapsed / animation.duration : 1;
        if (fraction >= 1) {
          animation.complete = true;
          fraction = 1;
        } else {
          seriesComplete = false;
        }
        const progress = animation.easing(fraction);
        if (animation.sourceCenter) {
          const x0 = animation.sourceCenter[0];
          const y0 = animation.sourceCenter[1];
          const x1 = animation.targetCenter[0];
          const y1 = animation.targetCenter[1];
          this.nextCenter_ = animation.targetCenter;
          const x = x0 + progress * (x1 - x0);
          const y = y0 + progress * (y1 - y0);
          this.targetCenter_ = [x, y];
        }
        if (animation.sourceResolution && animation.targetResolution) {
          const resolution = progress === 1 ? animation.targetResolution : animation.sourceResolution + progress * (animation.targetResolution - animation.sourceResolution);
          if (animation.anchor) {
            const size = this.getViewportSize_(this.getRotation());
            const constrainedResolution = this.constraints_.resolution(
              resolution,
              0,
              size,
              true
            );
            this.targetCenter_ = this.calculateCenterZoom(
              constrainedResolution,
              animation.anchor
            );
          }
          this.nextResolution_ = animation.targetResolution;
          this.targetResolution_ = resolution;
          this.applyTargetState_(true);
        }
        if (animation.sourceRotation !== void 0 && animation.targetRotation !== void 0) {
          const rotation = progress === 1 ? modulo(animation.targetRotation + Math.PI, 2 * Math.PI) - Math.PI : animation.sourceRotation + progress * (animation.targetRotation - animation.sourceRotation);
          if (animation.anchor) {
            const constrainedRotation = this.constraints_.rotation(
              rotation,
              true
            );
            this.targetCenter_ = this.calculateCenterRotate(
              constrainedRotation,
              animation.anchor
            );
          }
          this.nextRotation_ = animation.targetRotation;
          this.targetRotation_ = rotation;
        }
        this.applyTargetState_(true);
        more = true;
        if (!animation.complete) {
          break;
        }
      }
      if (seriesComplete) {
        this.animations_[i] = null;
        this.setHint(ViewHint.ANIMATING, -1);
        this.nextCenter_ = null;
        this.nextResolution_ = NaN;
        this.nextRotation_ = NaN;
        const callback = series[0].callback;
        if (callback) {
          animationCallback(callback, true);
        }
      }
    }
    this.animations_ = this.animations_.filter(Boolean);
    if (more && this.updateAnimationKey_ === void 0) {
      this.updateAnimationKey_ = requestAnimationFrame(
        this.updateAnimations_.bind(this)
      );
    }
  }
  calculateCenterRotate(rotation, anchor) {
    let center;
    const currentCenter = this.getCenterInternal();
    if (currentCenter !== void 0) {
      center = [currentCenter[0] - anchor[0], currentCenter[1] - anchor[1]];
      rotate$1(center, rotation - this.getRotation());
      add$2(center, anchor);
    }
    return center;
  }
  calculateCenterZoom(resolution, anchor) {
    let center;
    const currentCenter = this.getCenterInternal();
    const currentResolution = this.getResolution();
    if (currentCenter !== void 0 && currentResolution !== void 0) {
      const x = anchor[0] - resolution * (anchor[0] - currentCenter[0]) / currentResolution;
      const y = anchor[1] - resolution * (anchor[1] - currentCenter[1]) / currentResolution;
      center = [x, y];
    }
    return center;
  }
  getViewportSize_(rotation) {
    const size = this.viewportSize_;
    if (rotation) {
      const w = size[0];
      const h = size[1];
      return [
        Math.abs(w * Math.cos(rotation)) + Math.abs(h * Math.sin(rotation)),
        Math.abs(w * Math.sin(rotation)) + Math.abs(h * Math.cos(rotation))
      ];
    }
    return size;
  }
  setViewportSize(size) {
    this.viewportSize_ = Array.isArray(size) ? size.slice() : [100, 100];
    if (!this.getAnimating()) {
      this.resolveConstraints(0);
    }
  }
  getCenter() {
    const center = this.getCenterInternal();
    if (!center) {
      return center;
    }
    return toUserCoordinate(center, this.getProjection());
  }
  getCenterInternal() {
    return this.get(ViewProperty.CENTER);
  }
  getConstraints() {
    return this.constraints_;
  }
  getConstrainResolution() {
    return this.get("constrainResolution");
  }
  getHints(hints) {
    if (hints !== void 0) {
      hints[0] = this.hints_[0];
      hints[1] = this.hints_[1];
      return hints;
    }
    return this.hints_.slice();
  }
  calculateExtent(size) {
    const extent = this.calculateExtentInternal(size);
    return toUserExtent(extent, this.getProjection());
  }
  calculateExtentInternal(size) {
    size = size || this.getViewportSizeMinusPadding_();
    const center = this.getCenterInternal();
    assert(center, "The view center is not defined");
    const resolution = this.getResolution();
    assert(resolution !== void 0, "The view resolution is not defined");
    const rotation = this.getRotation();
    assert(rotation !== void 0, "The view rotation is not defined");
    return getForViewAndSize(center, resolution, rotation, size);
  }
  getMaxResolution() {
    return this.maxResolution_;
  }
  getMinResolution() {
    return this.minResolution_;
  }
  getMaxZoom() {
    return this.getZoomForResolution(this.minResolution_);
  }
  setMaxZoom(zoom) {
    this.applyOptions_(this.getUpdatedOptions_({ maxZoom: zoom }));
  }
  getMinZoom() {
    return this.getZoomForResolution(this.maxResolution_);
  }
  setMinZoom(zoom) {
    this.applyOptions_(this.getUpdatedOptions_({ minZoom: zoom }));
  }
  setConstrainResolution(enabled) {
    this.applyOptions_(this.getUpdatedOptions_({ constrainResolution: enabled }));
  }
  getProjection() {
    return this.projection_;
  }
  getResolution() {
    return this.get(ViewProperty.RESOLUTION);
  }
  getResolutions() {
    return this.resolutions_;
  }
  getResolutionForExtent(extent, size) {
    return this.getResolutionForExtentInternal(
      fromUserExtent(extent, this.getProjection()),
      size
    );
  }
  getResolutionForExtentInternal(extent, size) {
    size = size || this.getViewportSizeMinusPadding_();
    const xResolution = getWidth(extent) / size[0];
    const yResolution = getHeight(extent) / size[1];
    return Math.max(xResolution, yResolution);
  }
  getResolutionForValueFunction(power) {
    power = power || 2;
    const maxResolution = this.getConstrainedResolution(this.maxResolution_);
    const minResolution = this.minResolution_;
    const max = Math.log(maxResolution / minResolution) / Math.log(power);
    return function(value) {
      const resolution = maxResolution / Math.pow(power, value * max);
      return resolution;
    };
  }
  getRotation() {
    return this.get(ViewProperty.ROTATION);
  }
  getValueForResolutionFunction(power) {
    const logPower = Math.log(power || 2);
    const maxResolution = this.getConstrainedResolution(this.maxResolution_);
    const minResolution = this.minResolution_;
    const max = Math.log(maxResolution / minResolution) / logPower;
    return function(resolution) {
      const value = Math.log(maxResolution / resolution) / logPower / max;
      return value;
    };
  }
  getViewportSizeMinusPadding_(rotation) {
    let size = this.getViewportSize_(rotation);
    const padding = this.padding_;
    if (padding) {
      size = [
        size[0] - padding[1] - padding[3],
        size[1] - padding[0] - padding[2]
      ];
    }
    return size;
  }
  getState() {
    const projection = this.getProjection();
    const resolution = this.getResolution();
    const rotation = this.getRotation();
    let center = this.getCenterInternal();
    const padding = this.padding_;
    if (padding) {
      const reducedSize = this.getViewportSizeMinusPadding_();
      center = calculateCenterOn(
        center,
        this.getViewportSize_(),
        [reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]],
        resolution,
        rotation
      );
    }
    return {
      center: center.slice(0),
      projection: projection !== void 0 ? projection : null,
      resolution,
      nextCenter: this.nextCenter_,
      nextResolution: this.nextResolution_,
      nextRotation: this.nextRotation_,
      rotation,
      zoom: this.getZoom()
    };
  }
  getViewStateAndExtent() {
    return {
      viewState: this.getState(),
      extent: this.calculateExtent()
    };
  }
  getZoom() {
    let zoom;
    const resolution = this.getResolution();
    if (resolution !== void 0) {
      zoom = this.getZoomForResolution(resolution);
    }
    return zoom;
  }
  getZoomForResolution(resolution) {
    let offset = this.minZoom_ || 0;
    let max, zoomFactor;
    if (this.resolutions_) {
      const nearest = linearFindNearest(this.resolutions_, resolution, 1);
      offset = nearest;
      max = this.resolutions_[nearest];
      if (nearest == this.resolutions_.length - 1) {
        zoomFactor = 2;
      } else {
        zoomFactor = max / this.resolutions_[nearest + 1];
      }
    } else {
      max = this.maxResolution_;
      zoomFactor = this.zoomFactor_;
    }
    return offset + Math.log(max / resolution) / Math.log(zoomFactor);
  }
  getResolutionForZoom(zoom) {
    var _a;
    if ((_a = this.resolutions_) == null ? void 0 : _a.length) {
      if (this.resolutions_.length === 1) {
        return this.resolutions_[0];
      }
      const baseLevel = clamp(
        Math.floor(zoom),
        0,
        this.resolutions_.length - 2
      );
      const zoomFactor = this.resolutions_[baseLevel] / this.resolutions_[baseLevel + 1];
      return this.resolutions_[baseLevel] / Math.pow(zoomFactor, clamp(zoom - baseLevel, 0, 1));
    }
    return this.maxResolution_ / Math.pow(this.zoomFactor_, zoom - this.minZoom_);
  }
  fit(geometryOrExtent, options) {
    let geometry;
    assert(
      Array.isArray(geometryOrExtent) || typeof geometryOrExtent.getSimplifiedGeometry === "function",
      "Invalid extent or geometry provided as `geometry`"
    );
    if (Array.isArray(geometryOrExtent)) {
      assert(
        !isEmpty(geometryOrExtent),
        "Cannot fit empty extent provided as `geometry`"
      );
      const extent = fromUserExtent(geometryOrExtent, this.getProjection());
      geometry = fromExtent(extent);
    } else if (geometryOrExtent.getType() === "Circle") {
      const extent = fromUserExtent(
        geometryOrExtent.getExtent(),
        this.getProjection()
      );
      geometry = fromExtent(extent);
      geometry.rotate(this.getRotation(), getCenter(extent));
    } else {
      {
        geometry = geometryOrExtent;
      }
    }
    this.fitInternal(geometry, options);
  }
  rotatedExtentForGeometry(geometry) {
    const rotation = this.getRotation();
    const cosAngle = Math.cos(rotation);
    const sinAngle = Math.sin(-rotation);
    const coords = geometry.getFlatCoordinates();
    const stride = geometry.getStride();
    let minRotX = Infinity;
    let minRotY = Infinity;
    let maxRotX = -Infinity;
    let maxRotY = -Infinity;
    for (let i = 0, ii = coords.length; i < ii; i += stride) {
      const rotX = coords[i] * cosAngle - coords[i + 1] * sinAngle;
      const rotY = coords[i] * sinAngle + coords[i + 1] * cosAngle;
      minRotX = Math.min(minRotX, rotX);
      minRotY = Math.min(minRotY, rotY);
      maxRotX = Math.max(maxRotX, rotX);
      maxRotY = Math.max(maxRotY, rotY);
    }
    return [minRotX, minRotY, maxRotX, maxRotY];
  }
  fitInternal(geometry, options) {
    options = options || {};
    let size = options.size;
    if (!size) {
      size = this.getViewportSizeMinusPadding_();
    }
    const padding = options.padding !== void 0 ? options.padding : [0, 0, 0, 0];
    const nearest = options.nearest !== void 0 ? options.nearest : false;
    let minResolution;
    if (options.minResolution !== void 0) {
      minResolution = options.minResolution;
    } else if (options.maxZoom !== void 0) {
      minResolution = this.getResolutionForZoom(options.maxZoom);
    } else {
      minResolution = 0;
    }
    const rotatedExtent = this.rotatedExtentForGeometry(geometry);
    let resolution = this.getResolutionForExtentInternal(rotatedExtent, [
      size[0] - padding[1] - padding[3],
      size[1] - padding[0] - padding[2]
    ]);
    resolution = isNaN(resolution) ? minResolution : Math.max(resolution, minResolution);
    resolution = this.getConstrainedResolution(resolution, nearest ? 0 : 1);
    const rotation = this.getRotation();
    const sinAngle = Math.sin(rotation);
    const cosAngle = Math.cos(rotation);
    const centerRot = getCenter(rotatedExtent);
    centerRot[0] += (padding[1] - padding[3]) / 2 * resolution;
    centerRot[1] += (padding[0] - padding[2]) / 2 * resolution;
    const centerX = centerRot[0] * cosAngle - centerRot[1] * sinAngle;
    const centerY = centerRot[1] * cosAngle + centerRot[0] * sinAngle;
    const center = this.getConstrainedCenter([centerX, centerY], resolution);
    const callback = options.callback ? options.callback : VOID;
    if (options.duration !== void 0) {
      this.animateInternal(
        {
          resolution,
          center,
          duration: options.duration,
          easing: options.easing
        },
        callback
      );
    } else {
      this.targetResolution_ = resolution;
      this.targetCenter_ = center;
      this.applyTargetState_(false, true);
      animationCallback(callback, true);
    }
  }
  centerOn(coordinate, size, position) {
    this.centerOnInternal(
      fromUserCoordinate(coordinate, this.getProjection()),
      size,
      position
    );
  }
  centerOnInternal(coordinate, size, position) {
    this.setCenterInternal(
      calculateCenterOn(
        coordinate,
        size,
        position,
        this.getResolution(),
        this.getRotation()
      )
    );
  }
  calculateCenterShift(center, resolution, rotation, size) {
    let centerShift;
    const padding = this.padding_;
    if (padding && center) {
      const reducedSize = this.getViewportSizeMinusPadding_(-rotation);
      const shiftedCenter = calculateCenterOn(
        center,
        size,
        [reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]],
        resolution,
        rotation
      );
      centerShift = [
        center[0] - shiftedCenter[0],
        center[1] - shiftedCenter[1]
      ];
    }
    return centerShift;
  }
  isDef() {
    return !!this.getCenterInternal() && this.getResolution() !== void 0;
  }
  adjustCenter(deltaCoordinates) {
    const center = toUserCoordinate(this.targetCenter_, this.getProjection());
    this.setCenter([
      center[0] + deltaCoordinates[0],
      center[1] + deltaCoordinates[1]
    ]);
  }
  adjustCenterInternal(deltaCoordinates) {
    const center = this.targetCenter_;
    this.setCenterInternal([
      center[0] + deltaCoordinates[0],
      center[1] + deltaCoordinates[1]
    ]);
  }
  adjustResolution(ratio, anchor) {
    anchor = anchor && fromUserCoordinate(anchor, this.getProjection());
    this.adjustResolutionInternal(ratio, anchor);
  }
  adjustResolutionInternal(ratio, anchor) {
    const isMoving = this.getAnimating() || this.getInteracting();
    const size = this.getViewportSize_(this.getRotation());
    const newResolution = this.constraints_.resolution(
      this.targetResolution_ * ratio,
      0,
      size,
      isMoving
    );
    if (anchor) {
      this.targetCenter_ = this.calculateCenterZoom(newResolution, anchor);
    }
    this.targetResolution_ *= ratio;
    this.applyTargetState_();
  }
  adjustZoom(delta, anchor) {
    this.adjustResolution(Math.pow(this.zoomFactor_, -delta), anchor);
  }
  adjustRotation(delta, anchor) {
    if (anchor) {
      anchor = fromUserCoordinate(anchor, this.getProjection());
    }
    this.adjustRotationInternal(delta, anchor);
  }
  adjustRotationInternal(delta, anchor) {
    const isMoving = this.getAnimating() || this.getInteracting();
    const newRotation = this.constraints_.rotation(
      this.targetRotation_ + delta,
      isMoving
    );
    if (anchor) {
      this.targetCenter_ = this.calculateCenterRotate(newRotation, anchor);
    }
    this.targetRotation_ += delta;
    this.applyTargetState_();
  }
  setCenter(center) {
    this.setCenterInternal(
      center ? fromUserCoordinate(center, this.getProjection()) : center
    );
  }
  setCenterInternal(center) {
    this.targetCenter_ = center;
    this.applyTargetState_();
  }
  setHint(hint, delta) {
    this.hints_[hint] += delta;
    this.changed();
    return this.hints_[hint];
  }
  setResolution(resolution) {
    this.targetResolution_ = resolution;
    this.applyTargetState_();
  }
  setRotation(rotation) {
    this.targetRotation_ = rotation;
    this.applyTargetState_();
  }
  setZoom(zoom) {
    this.setResolution(this.getResolutionForZoom(zoom));
  }
  applyTargetState_(doNotCancelAnims, forceMoving) {
    const isMoving = this.getAnimating() || this.getInteracting() || forceMoving;
    const newRotation = this.constraints_.rotation(
      this.targetRotation_,
      isMoving
    );
    const size = this.getViewportSize_(newRotation);
    const newResolution = this.constraints_.resolution(
      this.targetResolution_,
      0,
      size,
      isMoving
    );
    const newCenter = this.constraints_.center(
      this.targetCenter_,
      newResolution,
      size,
      isMoving,
      this.calculateCenterShift(
        this.targetCenter_,
        newResolution,
        newRotation,
        size
      )
    );
    if (this.get(ViewProperty.ROTATION) !== newRotation) {
      this.set(ViewProperty.ROTATION, newRotation);
    }
    if (this.get(ViewProperty.RESOLUTION) !== newResolution) {
      this.set(ViewProperty.RESOLUTION, newResolution);
      this.set("zoom", this.getZoom(), true);
    }
    if (!newCenter || !this.get(ViewProperty.CENTER) || !equals(this.get(ViewProperty.CENTER), newCenter)) {
      this.set(ViewProperty.CENTER, newCenter);
    }
    if (this.getAnimating() && !doNotCancelAnims) {
      this.cancelAnimations();
    }
    this.cancelAnchor_ = void 0;
  }
  resolveConstraints(duration, resolutionDirection, anchor) {
    duration = duration !== void 0 ? duration : 200;
    const direction = resolutionDirection || 0;
    const newRotation = this.constraints_.rotation(this.targetRotation_);
    const size = this.getViewportSize_(newRotation);
    const newResolution = this.constraints_.resolution(
      this.targetResolution_,
      direction,
      size
    );
    const newCenter = this.constraints_.center(
      this.targetCenter_,
      newResolution,
      size,
      false,
      this.calculateCenterShift(
        this.targetCenter_,
        newResolution,
        newRotation,
        size
      )
    );
    if (duration === 0 && !this.cancelAnchor_) {
      this.targetResolution_ = newResolution;
      this.targetRotation_ = newRotation;
      this.targetCenter_ = newCenter;
      this.applyTargetState_();
      return;
    }
    anchor = anchor || (duration === 0 ? this.cancelAnchor_ : void 0);
    this.cancelAnchor_ = void 0;
    if (this.getResolution() !== newResolution || this.getRotation() !== newRotation || !this.getCenterInternal() || !equals(this.getCenterInternal(), newCenter)) {
      if (this.getAnimating()) {
        this.cancelAnimations();
      }
      this.animateInternal({
        rotation: newRotation,
        center: newCenter,
        resolution: newResolution,
        duration,
        easing: easeOut,
        anchor
      });
    }
  }
  beginInteraction() {
    this.resolveConstraints(0);
    this.setHint(ViewHint.INTERACTING, 1);
  }
  endInteraction(duration, resolutionDirection, anchor) {
    anchor = anchor && fromUserCoordinate(anchor, this.getProjection());
    this.endInteractionInternal(duration, resolutionDirection, anchor);
  }
  endInteractionInternal(duration, resolutionDirection, anchor) {
    if (!this.getInteracting()) {
      return;
    }
    this.setHint(ViewHint.INTERACTING, -1);
    this.resolveConstraints(duration, resolutionDirection, anchor);
  }
  getConstrainedCenter(targetCenter, targetResolution) {
    const size = this.getViewportSize_(this.getRotation());
    return this.constraints_.center(
      targetCenter,
      targetResolution || this.getResolution(),
      size
    );
  }
  getConstrainedZoom(targetZoom, direction) {
    const targetRes = this.getResolutionForZoom(targetZoom);
    return this.getZoomForResolution(
      this.getConstrainedResolution(targetRes, direction)
    );
  }
  getConstrainedResolution(targetResolution, direction) {
    direction = direction || 0;
    const size = this.getViewportSize_(this.getRotation());
    return this.constraints_.resolution(targetResolution, direction, size);
  }
}
function animationCallback(callback, returnValue) {
  setTimeout(function() {
    callback(returnValue);
  }, 0);
}
function createCenterConstraint(options) {
  if (options.extent !== void 0) {
    const smooth = options.smoothExtentConstraint !== void 0 ? options.smoothExtentConstraint : true;
    return createExtent(options.extent, options.constrainOnlyCenter, smooth);
  }
  const projection = createProjection(options.projection, "EPSG:3857");
  if (options.multiWorld !== true && projection.isGlobal()) {
    const extent = projection.getExtent().slice();
    extent[0] = -Infinity;
    extent[2] = Infinity;
    return createExtent(extent, false, false);
  }
  return none$1;
}
function createResolutionConstraint(options) {
  let resolutionConstraint;
  let maxResolution;
  let minResolution;
  const defaultMaxZoom = 28;
  const defaultZoomFactor = 2;
  let minZoom = options.minZoom !== void 0 ? options.minZoom : DEFAULT_MIN_ZOOM;
  let maxZoom = options.maxZoom !== void 0 ? options.maxZoom : defaultMaxZoom;
  const zoomFactor = options.zoomFactor !== void 0 ? options.zoomFactor : defaultZoomFactor;
  const multiWorld = options.multiWorld !== void 0 ? options.multiWorld : false;
  const smooth = options.smoothResolutionConstraint !== void 0 ? options.smoothResolutionConstraint : true;
  const showFullExtent = options.showFullExtent !== void 0 ? options.showFullExtent : false;
  const projection = createProjection(options.projection, "EPSG:3857");
  const projExtent = projection.getExtent();
  let constrainOnlyCenter = options.constrainOnlyCenter;
  let extent = options.extent;
  if (!multiWorld && !extent && projection.isGlobal()) {
    constrainOnlyCenter = false;
    extent = projExtent;
  }
  if (options.resolutions !== void 0) {
    const resolutions = options.resolutions;
    maxResolution = resolutions[minZoom];
    minResolution = resolutions[maxZoom] !== void 0 ? resolutions[maxZoom] : resolutions[resolutions.length - 1];
    if (options.constrainResolution) {
      resolutionConstraint = createSnapToResolutions(
        resolutions,
        smooth,
        !constrainOnlyCenter && extent,
        showFullExtent
      );
    } else {
      resolutionConstraint = createMinMaxResolution(
        maxResolution,
        minResolution,
        smooth,
        !constrainOnlyCenter && extent,
        showFullExtent
      );
    }
  } else {
    const size = !projExtent ? 360 * METERS_PER_UNIT$1.degrees / projection.getMetersPerUnit() : Math.max(getWidth(projExtent), getHeight(projExtent));
    const defaultMaxResolution = size / DEFAULT_TILE_SIZE / Math.pow(defaultZoomFactor, DEFAULT_MIN_ZOOM);
    const defaultMinResolution = defaultMaxResolution / Math.pow(defaultZoomFactor, defaultMaxZoom - DEFAULT_MIN_ZOOM);
    maxResolution = options.maxResolution;
    if (maxResolution !== void 0) {
      minZoom = 0;
    } else {
      maxResolution = defaultMaxResolution / Math.pow(zoomFactor, minZoom);
    }
    minResolution = options.minResolution;
    if (minResolution === void 0) {
      if (options.maxZoom !== void 0) {
        if (options.maxResolution !== void 0) {
          minResolution = maxResolution / Math.pow(zoomFactor, maxZoom);
        } else {
          minResolution = defaultMaxResolution / Math.pow(zoomFactor, maxZoom);
        }
      } else {
        minResolution = defaultMinResolution;
      }
    }
    maxZoom = minZoom + Math.floor(
      Math.log(maxResolution / minResolution) / Math.log(zoomFactor)
    );
    minResolution = maxResolution / Math.pow(zoomFactor, maxZoom - minZoom);
    if (options.constrainResolution) {
      resolutionConstraint = createSnapToPower(
        zoomFactor,
        maxResolution,
        minResolution,
        smooth,
        !constrainOnlyCenter && extent,
        showFullExtent
      );
    } else {
      resolutionConstraint = createMinMaxResolution(
        maxResolution,
        minResolution,
        smooth,
        !constrainOnlyCenter && extent,
        showFullExtent
      );
    }
  }
  return {
    constraint: resolutionConstraint,
    maxResolution,
    minResolution,
    minZoom,
    zoomFactor
  };
}
function createRotationConstraint(options) {
  const enableRotation = options.enableRotation !== void 0 ? options.enableRotation : true;
  if (enableRotation) {
    const constrainRotation = options.constrainRotation;
    if (constrainRotation === void 0 || constrainRotation === true) {
      return createSnapToZero();
    }
    if (constrainRotation === false) {
      return none;
    }
    if (typeof constrainRotation === "number") {
      return createSnapToN(constrainRotation);
    }
    return none;
  }
  return disable;
}
function isNoopAnimation(animation) {
  if (animation.sourceCenter && animation.targetCenter) {
    if (!equals(animation.sourceCenter, animation.targetCenter)) {
      return false;
    }
  }
  if (animation.sourceResolution !== animation.targetResolution) {
    return false;
  }
  if (animation.sourceRotation !== animation.targetRotation) {
    return false;
  }
  return true;
}
function calculateCenterOn(coordinate, size, position, resolution, rotation) {
  const cosAngle = Math.cos(-rotation);
  let sinAngle = Math.sin(-rotation);
  let rotX = coordinate[0] * cosAngle - coordinate[1] * sinAngle;
  let rotY = coordinate[1] * cosAngle + coordinate[0] * sinAngle;
  rotX += (size[0] / 2 - position[0]) * resolution;
  rotY += (position[1] - size[1] / 2) * resolution;
  sinAngle = -sinAngle;
  const centerX = rotX * cosAngle - rotY * sinAngle;
  const centerY = rotY * cosAngle + rotX * sinAngle;
  return [centerX, centerY];
}
const View$1 = View;
const LayerProperty = {
  OPACITY: "opacity",
  VISIBLE: "visible",
  EXTENT: "extent",
  Z_INDEX: "zIndex",
  MAX_RESOLUTION: "maxResolution",
  MIN_RESOLUTION: "minResolution",
  MAX_ZOOM: "maxZoom",
  MIN_ZOOM: "minZoom",
  SOURCE: "source",
  MAP: "map"
};
class BaseLayer extends BaseObject$1 {
  constructor(options) {
    super();
    this.on;
    this.once;
    this.un;
    this.background_ = options.background;
    const properties = Object.assign({}, options);
    if (typeof options.properties === "object") {
      delete properties.properties;
      Object.assign(properties, options.properties);
    }
    properties[LayerProperty.OPACITY] = options.opacity !== void 0 ? options.opacity : 1;
    assert(
      typeof properties[LayerProperty.OPACITY] === "number",
      "Layer opacity must be a number"
    );
    properties[LayerProperty.VISIBLE] = options.visible !== void 0 ? options.visible : true;
    properties[LayerProperty.Z_INDEX] = options.zIndex;
    properties[LayerProperty.MAX_RESOLUTION] = options.maxResolution !== void 0 ? options.maxResolution : Infinity;
    properties[LayerProperty.MIN_RESOLUTION] = options.minResolution !== void 0 ? options.minResolution : 0;
    properties[LayerProperty.MIN_ZOOM] = options.minZoom !== void 0 ? options.minZoom : -Infinity;
    properties[LayerProperty.MAX_ZOOM] = options.maxZoom !== void 0 ? options.maxZoom : Infinity;
    this.className_ = properties.className !== void 0 ? properties.className : "ol-layer";
    delete properties.className;
    this.setProperties(properties);
    this.state_ = null;
  }
  getBackground() {
    return this.background_;
  }
  getClassName() {
    return this.className_;
  }
  getLayerState(managed) {
    const state = this.state_ || {
      layer: this,
      managed: managed === void 0 ? true : managed
    };
    const zIndex = this.getZIndex();
    state.opacity = clamp(Math.round(this.getOpacity() * 100) / 100, 0, 1);
    state.visible = this.getVisible();
    state.extent = this.getExtent();
    state.zIndex = zIndex === void 0 && !state.managed ? Infinity : zIndex;
    state.maxResolution = this.getMaxResolution();
    state.minResolution = Math.max(this.getMinResolution(), 0);
    state.minZoom = this.getMinZoom();
    state.maxZoom = this.getMaxZoom();
    this.state_ = state;
    return state;
  }
  getLayersArray(array) {
    return abstract();
  }
  getLayerStatesArray(states) {
    return abstract();
  }
  getExtent() {
    return this.get(LayerProperty.EXTENT);
  }
  getMaxResolution() {
    return this.get(LayerProperty.MAX_RESOLUTION);
  }
  getMinResolution() {
    return this.get(LayerProperty.MIN_RESOLUTION);
  }
  getMinZoom() {
    return this.get(LayerProperty.MIN_ZOOM);
  }
  getMaxZoom() {
    return this.get(LayerProperty.MAX_ZOOM);
  }
  getOpacity() {
    return this.get(LayerProperty.OPACITY);
  }
  getSourceState() {
    return abstract();
  }
  getVisible() {
    return this.get(LayerProperty.VISIBLE);
  }
  getZIndex() {
    return this.get(LayerProperty.Z_INDEX);
  }
  setBackground(background) {
    this.background_ = background;
    this.changed();
  }
  setExtent(extent) {
    this.set(LayerProperty.EXTENT, extent);
  }
  setMaxResolution(maxResolution) {
    this.set(LayerProperty.MAX_RESOLUTION, maxResolution);
  }
  setMinResolution(minResolution) {
    this.set(LayerProperty.MIN_RESOLUTION, minResolution);
  }
  setMaxZoom(maxZoom) {
    this.set(LayerProperty.MAX_ZOOM, maxZoom);
  }
  setMinZoom(minZoom) {
    this.set(LayerProperty.MIN_ZOOM, minZoom);
  }
  setOpacity(opacity) {
    assert(typeof opacity === "number", "Layer opacity must be a number");
    this.set(LayerProperty.OPACITY, opacity);
  }
  setVisible(visible) {
    this.set(LayerProperty.VISIBLE, visible);
  }
  setZIndex(zindex) {
    this.set(LayerProperty.Z_INDEX, zindex);
  }
  disposeInternal() {
    if (this.state_) {
      this.state_.layer = null;
      this.state_ = null;
    }
    super.disposeInternal();
  }
}
const BaseLayer$1 = BaseLayer;
class Layer extends BaseLayer$1 {
  constructor(options) {
    const baseOptions = Object.assign({}, options);
    delete baseOptions.source;
    super(baseOptions);
    this.on;
    this.once;
    this.un;
    this.mapPrecomposeKey_ = null;
    this.mapRenderKey_ = null;
    this.sourceChangeKey_ = null;
    this.renderer_ = null;
    this.sourceReady_ = false;
    this.rendered = false;
    if (options.render) {
      this.render = options.render;
    }
    if (options.map) {
      this.setMap(options.map);
    }
    this.addChangeListener(
      LayerProperty.SOURCE,
      this.handleSourcePropertyChange_
    );
    const source = options.source ? options.source : null;
    this.setSource(source);
  }
  getLayersArray(array) {
    array = array ? array : [];
    array.push(this);
    return array;
  }
  getLayerStatesArray(states) {
    states = states ? states : [];
    states.push(this.getLayerState());
    return states;
  }
  getSource() {
    return this.get(LayerProperty.SOURCE) || null;
  }
  getRenderSource() {
    return this.getSource();
  }
  getSourceState() {
    const source = this.getSource();
    return !source ? "undefined" : source.getState();
  }
  handleSourceChange_() {
    this.changed();
    if (this.sourceReady_ || this.getSource().getState() !== "ready") {
      return;
    }
    this.sourceReady_ = true;
    this.dispatchEvent("sourceready");
  }
  handleSourcePropertyChange_() {
    if (this.sourceChangeKey_) {
      unlistenByKey(this.sourceChangeKey_);
      this.sourceChangeKey_ = null;
    }
    this.sourceReady_ = false;
    const source = this.getSource();
    if (source) {
      this.sourceChangeKey_ = listen(
        source,
        EventType.CHANGE,
        this.handleSourceChange_,
        this
      );
      if (source.getState() === "ready") {
        this.sourceReady_ = true;
        setTimeout(() => {
          this.dispatchEvent("sourceready");
        }, 0);
      }
    }
    this.changed();
  }
  getFeatures(pixel) {
    if (!this.renderer_) {
      return Promise.resolve([]);
    }
    return this.renderer_.getFeatures(pixel);
  }
  getData(pixel) {
    if (!this.renderer_ || !this.rendered) {
      return null;
    }
    return this.renderer_.getData(pixel);
  }
  isVisible(view) {
    let frameState;
    const map = this.getMapInternal();
    if (!view && map) {
      view = map.getView();
    }
    if (view instanceof View$1) {
      frameState = {
        viewState: view.getState(),
        extent: view.calculateExtent()
      };
    } else {
      frameState = view;
    }
    if (!frameState.layerStatesArray && map) {
      frameState.layerStatesArray = map.getLayerGroup().getLayerStatesArray();
    }
    let layerState;
    if (frameState.layerStatesArray) {
      layerState = frameState.layerStatesArray.find(
        (layerState2) => layerState2.layer === this
      );
      if (!layerState) {
        return false;
      }
    } else {
      layerState = this.getLayerState();
    }
    const layerExtent = this.getExtent();
    return inView(layerState, frameState.viewState) && (!layerExtent || intersects$1(layerExtent, frameState.extent));
  }
  getAttributions(view) {
    var _a;
    if (!this.isVisible(view)) {
      return [];
    }
    const getAttributions = (_a = this.getSource()) == null ? void 0 : _a.getAttributions();
    if (!getAttributions) {
      return [];
    }
    const frameState = view instanceof View$1 ? view.getViewStateAndExtent() : view;
    let attributions = getAttributions(frameState);
    if (!Array.isArray(attributions)) {
      attributions = [attributions];
    }
    return attributions;
  }
  render(frameState, target) {
    const layerRenderer = this.getRenderer();
    if (layerRenderer.prepareFrame(frameState)) {
      this.rendered = true;
      return layerRenderer.renderFrame(frameState, target);
    }
    return null;
  }
  unrender() {
    this.rendered = false;
  }
  getDeclutter() {
    return void 0;
  }
  renderDeclutter(frameState, layerState) {
  }
  renderDeferred(frameState) {
    const layerRenderer = this.getRenderer();
    if (!layerRenderer) {
      return;
    }
    layerRenderer.renderDeferred(frameState);
  }
  setMapInternal(map) {
    if (!map) {
      this.unrender();
    }
    this.set(LayerProperty.MAP, map);
  }
  getMapInternal() {
    return this.get(LayerProperty.MAP);
  }
  setMap(map) {
    if (this.mapPrecomposeKey_) {
      unlistenByKey(this.mapPrecomposeKey_);
      this.mapPrecomposeKey_ = null;
    }
    if (!map) {
      this.changed();
    }
    if (this.mapRenderKey_) {
      unlistenByKey(this.mapRenderKey_);
      this.mapRenderKey_ = null;
    }
    if (map) {
      this.mapPrecomposeKey_ = listen(
        map,
        RenderEventType.PRECOMPOSE,
        this.handlePrecompose_,
        this
      );
      this.mapRenderKey_ = listen(this, EventType.CHANGE, map.render, map);
      this.changed();
    }
  }
  handlePrecompose_(renderEvent) {
    const layerStatesArray = renderEvent.frameState.layerStatesArray;
    const layerState = this.getLayerState(false);
    assert(
      !layerStatesArray.some(
        (arrayLayerState) => arrayLayerState.layer === layerState.layer
      ),
      "A layer can only be added to the map once. Use either `layer.setMap()` or `map.addLayer()`, not both."
    );
    layerStatesArray.push(layerState);
  }
  setSource(source) {
    this.set(LayerProperty.SOURCE, source);
  }
  getRenderer() {
    if (!this.renderer_) {
      this.renderer_ = this.createRenderer();
    }
    return this.renderer_;
  }
  hasRenderer() {
    return !!this.renderer_;
  }
  createRenderer() {
    return null;
  }
  clearRenderer() {
    if (this.renderer_) {
      this.renderer_.dispose();
      delete this.renderer_;
    }
  }
  disposeInternal() {
    this.clearRenderer();
    this.setSource(null);
    super.disposeInternal();
  }
}
function inView(layerState, viewState) {
  if (!layerState.visible) {
    return false;
  }
  const resolution = viewState.resolution;
  if (resolution < layerState.minResolution || resolution >= layerState.maxResolution) {
    return false;
  }
  const zoom = viewState.zoom;
  return zoom > layerState.minZoom && zoom <= layerState.maxZoom;
}
const Layer$1 = Layer;
const Property = {
  RENDER_ORDER: "renderOrder"
};
class BaseVectorLayer extends Layer$1 {
  constructor(options) {
    options = options ? options : {};
    const baseOptions = Object.assign({}, options);
    delete baseOptions.style;
    delete baseOptions.renderBuffer;
    delete baseOptions.updateWhileAnimating;
    delete baseOptions.updateWhileInteracting;
    super(baseOptions);
    this.declutter_ = options.declutter ? String(options.declutter) : void 0;
    this.renderBuffer_ = options.renderBuffer !== void 0 ? options.renderBuffer : 100;
    this.style_ = null;
    this.styleFunction_ = void 0;
    this.setStyle(options.style);
    this.updateWhileAnimating_ = options.updateWhileAnimating !== void 0 ? options.updateWhileAnimating : false;
    this.updateWhileInteracting_ = options.updateWhileInteracting !== void 0 ? options.updateWhileInteracting : false;
  }
  getDeclutter() {
    return this.declutter_;
  }
  getFeatures(pixel) {
    return super.getFeatures(pixel);
  }
  getRenderBuffer() {
    return this.renderBuffer_;
  }
  getRenderOrder() {
    return this.get(Property.RENDER_ORDER);
  }
  getStyle() {
    return this.style_;
  }
  getStyleFunction() {
    return this.styleFunction_;
  }
  getUpdateWhileAnimating() {
    return this.updateWhileAnimating_;
  }
  getUpdateWhileInteracting() {
    return this.updateWhileInteracting_;
  }
  renderDeclutter(frameState, layerState) {
    const declutterGroup = this.getDeclutter();
    if (declutterGroup in frameState.declutter === false) {
      frameState.declutter[declutterGroup] = new RBush$2(9);
    }
    this.getRenderer().renderDeclutter(frameState, layerState);
  }
  setRenderOrder(renderOrder) {
    this.set(Property.RENDER_ORDER, renderOrder);
  }
  setStyle(style) {
    this.style_ = style === void 0 ? createDefaultStyle : style;
    const styleLike = toStyleLike(style);
    this.styleFunction_ = style === null ? void 0 : toFunction(styleLike);
    this.changed();
  }
  setDeclutter(declutter) {
    this.declutter_ = declutter ? String(declutter) : void 0;
    this.changed();
  }
}
function toStyleLike(style) {
  if (style === void 0) {
    return createDefaultStyle;
  }
  if (!style) {
    return null;
  }
  if (typeof style === "function") {
    return style;
  }
  if (style instanceof Style) {
    return style;
  }
  if (!Array.isArray(style)) {
    return flatStylesToStyleFunction([style]);
  }
  if (style.length === 0) {
    return [];
  }
  const length = style.length;
  const first = style[0];
  if (first instanceof Style) {
    const styles = new Array(length);
    for (let i = 0; i < length; ++i) {
      const candidate = style[i];
      if (!(candidate instanceof Style)) {
        throw new Error("Expected a list of style instances");
      }
      styles[i] = candidate;
    }
    return styles;
  }
  if ("style" in first) {
    const rules = new Array(length);
    for (let i = 0; i < length; ++i) {
      const candidate = style[i];
      if (!("style" in candidate)) {
        throw new Error("Expected a list of rules with a style property");
      }
      rules[i] = candidate;
    }
    return rulesToStyleFunction(rules);
  }
  const flatStyles = style;
  return flatStylesToStyleFunction(flatStyles);
}
const BaseVectorLayer$1 = BaseVectorLayer;
class VectorLayer extends BaseVectorLayer$1 {
  constructor(options) {
    super(options);
  }
  createRenderer() {
    return new CanvasVectorLayerRenderer$1(this);
  }
}
const VectorLayer$1 = VectorLayer;
const InteractionProperty = {
  ACTIVE: "active"
};
class Interaction extends BaseObject$1 {
  constructor(options) {
    super();
    this.on;
    this.once;
    this.un;
    if (options && options.handleEvent) {
      this.handleEvent = options.handleEvent;
    }
    this.map_ = null;
    this.setActive(true);
  }
  getActive() {
    return this.get(InteractionProperty.ACTIVE);
  }
  getMap() {
    return this.map_;
  }
  handleEvent(mapBrowserEvent) {
    return true;
  }
  setActive(active) {
    this.set(InteractionProperty.ACTIVE, active);
  }
  setMap(map) {
    this.map_ = map;
  }
}
const Interaction$1 = Interaction;
const SelectEventType = {
  SELECT: "select"
};
class SelectEvent extends Event {
  constructor(type, selected, deselected, mapBrowserEvent) {
    super(type);
    this.selected = selected;
    this.deselected = deselected;
    this.mapBrowserEvent = mapBrowserEvent;
  }
}
const originalFeatureStyles = {};
class Select extends Interaction$1 {
  constructor(options) {
    super();
    this.on;
    this.once;
    this.un;
    options = options ? options : {};
    this.boundAddFeature_ = this.addFeature_.bind(this);
    this.boundRemoveFeature_ = this.removeFeature_.bind(this);
    this.condition_ = options.condition ? options.condition : singleClick;
    this.addCondition_ = options.addCondition ? options.addCondition : never;
    this.removeCondition_ = options.removeCondition ? options.removeCondition : never;
    this.toggleCondition_ = options.toggleCondition ? options.toggleCondition : shiftKeyOnly;
    this.multi_ = options.multi ? options.multi : false;
    this.filter_ = options.filter ? options.filter : TRUE;
    this.hitTolerance_ = options.hitTolerance ? options.hitTolerance : 0;
    this.style_ = options.style !== void 0 ? options.style : getDefaultStyleFunction();
    this.features_ = options.features || new Collection$1();
    let layerFilter;
    if (options.layers) {
      if (typeof options.layers === "function") {
        layerFilter = options.layers;
      } else {
        const layers = options.layers;
        layerFilter = function(layer) {
          return layers.includes(layer);
        };
      }
    } else {
      layerFilter = TRUE;
    }
    this.layerFilter_ = layerFilter;
    this.featureLayerAssociation_ = {};
  }
  addFeatureLayerAssociation_(feature2, layer) {
    this.featureLayerAssociation_[getUid(feature2)] = layer;
  }
  getFeatures() {
    return this.features_;
  }
  getHitTolerance() {
    return this.hitTolerance_;
  }
  getLayer(feature2) {
    return this.featureLayerAssociation_[getUid(feature2)];
  }
  setHitTolerance(hitTolerance) {
    this.hitTolerance_ = hitTolerance;
  }
  setMap(map) {
    const currentMap = this.getMap();
    if (currentMap && this.style_) {
      this.features_.forEach(this.restorePreviousStyle_.bind(this));
    }
    super.setMap(map);
    if (map) {
      this.features_.addEventListener(
        CollectionEventType.ADD,
        this.boundAddFeature_
      );
      this.features_.addEventListener(
        CollectionEventType.REMOVE,
        this.boundRemoveFeature_
      );
      if (this.style_) {
        this.features_.forEach(this.applySelectedStyle_.bind(this));
      }
    } else {
      this.features_.removeEventListener(
        CollectionEventType.ADD,
        this.boundAddFeature_
      );
      this.features_.removeEventListener(
        CollectionEventType.REMOVE,
        this.boundRemoveFeature_
      );
    }
  }
  addFeature_(evt) {
    const feature2 = evt.element;
    if (this.style_) {
      this.applySelectedStyle_(feature2);
    }
    if (!this.getLayer(feature2)) {
      const layer = this.getMap().getAllLayers().find(function(layer2) {
        if (layer2 instanceof VectorLayer$1 && layer2.getSource() && layer2.getSource().hasFeature(feature2)) {
          return layer2;
        }
      });
      if (layer) {
        this.addFeatureLayerAssociation_(feature2, layer);
      }
    }
  }
  removeFeature_(evt) {
    if (this.style_) {
      this.restorePreviousStyle_(evt.element);
    }
  }
  getStyle() {
    return this.style_;
  }
  applySelectedStyle_(feature2) {
    const key = getUid(feature2);
    if (!(key in originalFeatureStyles)) {
      originalFeatureStyles[key] = feature2.getStyle();
    }
    feature2.setStyle(this.style_);
  }
  restorePreviousStyle_(feature2) {
    const interactions = this.getMap().getInteractions().getArray();
    for (let i = interactions.length - 1; i >= 0; --i) {
      const interaction = interactions[i];
      if (interaction !== this && interaction instanceof Select && interaction.getStyle() && interaction.getFeatures().getArray().lastIndexOf(feature2) !== -1) {
        feature2.setStyle(interaction.getStyle());
        return;
      }
    }
    const key = getUid(feature2);
    feature2.setStyle(originalFeatureStyles[key]);
    delete originalFeatureStyles[key];
  }
  removeFeatureLayerAssociation_(feature2) {
    delete this.featureLayerAssociation_[getUid(feature2)];
  }
  handleEvent(mapBrowserEvent) {
    if (!this.condition_(mapBrowserEvent)) {
      return true;
    }
    const add2 = this.addCondition_(mapBrowserEvent);
    const remove = this.removeCondition_(mapBrowserEvent);
    const toggle = this.toggleCondition_(mapBrowserEvent);
    const set = !add2 && !remove && !toggle;
    const map = mapBrowserEvent.map;
    const features = this.getFeatures();
    const deselected = [];
    const selected = [];
    if (set) {
      clear(this.featureLayerAssociation_);
      map.forEachFeatureAtPixel(
        mapBrowserEvent.pixel,
        (feature2, layer) => {
          if (!(feature2 instanceof Feature$1) || !this.filter_(feature2, layer)) {
            return;
          }
          this.addFeatureLayerAssociation_(feature2, layer);
          selected.push(feature2);
          return !this.multi_;
        },
        {
          layerFilter: this.layerFilter_,
          hitTolerance: this.hitTolerance_
        }
      );
      for (let i = features.getLength() - 1; i >= 0; --i) {
        const feature2 = features.item(i);
        const index2 = selected.indexOf(feature2);
        if (index2 > -1) {
          selected.splice(index2, 1);
        } else {
          features.remove(feature2);
          deselected.push(feature2);
        }
      }
      if (selected.length !== 0) {
        features.extend(selected);
      }
    } else {
      map.forEachFeatureAtPixel(
        mapBrowserEvent.pixel,
        (feature2, layer) => {
          if (!(feature2 instanceof Feature$1) || !this.filter_(feature2, layer)) {
            return;
          }
          if ((add2 || toggle) && !features.getArray().includes(feature2)) {
            this.addFeatureLayerAssociation_(feature2, layer);
            selected.push(feature2);
          } else if ((remove || toggle) && features.getArray().includes(feature2)) {
            deselected.push(feature2);
            this.removeFeatureLayerAssociation_(feature2);
          }
          return !this.multi_;
        },
        {
          layerFilter: this.layerFilter_,
          hitTolerance: this.hitTolerance_
        }
      );
      for (let j = deselected.length - 1; j >= 0; --j) {
        features.remove(deselected[j]);
      }
      features.extend(selected);
    }
    if (selected.length > 0 || deselected.length > 0) {
      this.dispatchEvent(
        new SelectEvent(
          SelectEventType.SELECT,
          selected,
          deselected,
          mapBrowserEvent
        )
      );
    }
    return true;
  }
}
function getDefaultStyleFunction() {
  const styles = createEditingStyle();
  extend$2(styles["Polygon"], styles["LineString"]);
  extend$2(styles["GeometryCollection"], styles["LineString"]);
  return function(feature2) {
    if (!feature2.getGeometry()) {
      return null;
    }
    return styles[feature2.getGeometry().getType()];
  };
}
const Select$1 = Select;
class CreateClusterLayer {
  constructor(id, points, props = {}) {
    __publicField(this, "gyMapObj");
    __publicField(this, "mapFinish");
    __publicField(this, "layer");
    __publicField(this, "oneStyle");
    __publicField(this, "clusterSource");
    __publicField(this, "props");
    __publicField(this, "currentResolution");
    __publicField(this, "maxFeatureCount");
    __publicField(this, "isDraw");
    __publicField(this, "points");
    this.layer = null;
    this.clusterSource = null;
    this.oneStyle = null;
    this.gyMapObj = gyMap$1(id);
    this.isDraw = false;
    this.points = points;
    this.props = props;
    this.mapFinish = computed(() => this.gyMapObj.value && this.gyMapObj.value.mapFinish);
    this.currentResolution = 0;
    this.maxFeatureCount = 0;
    this.draw();
  }
  draw() {
    this.createLayer();
    this.addWatchFun();
    this.addLayerToMap();
  }
  calculateClusterInfo(resolution) {
    const features = this.layer.getSource().getFeatures();
    let feature2, radius;
    for (let i = features.length - 1; i >= 0; --i) {
      feature2 = features[i];
      const originalFeatures = feature2.get("features");
      const extent = createEmpty();
      let j, jj;
      for (j = 0, jj = originalFeatures.length; j < jj; ++j) {
        extend$1(extent, originalFeatures[j].getGeometry().getExtent());
      }
      this.maxFeatureCount = Math.max(this.maxFeatureCount, jj);
      radius = this.props.radiusMultiplier * (getWidth(extent) + getHeight(extent)) / resolution;
      feature2.set("radius", radius);
    }
  }
  styleFunction(feature2, resolution) {
    if (resolution != this.currentResolution) {
      this.calculateClusterInfo(resolution);
      this.currentResolution = resolution;
    }
    let style;
    let size = feature2.get("features").length;
    if (size > 1) {
      style = new Style$1({
        image: new Circle$1({
          radius: feature2.get("radius"),
          fill: this.props.clusterFullColor ? new Fill$2({
            color: this.props.clusterFullColor
          }) : new Fill$2({
            color: [255, 153, 0, Math.min(0.9, 0.5 + size / this.maxFeatureCount)]
          }),
          stroke: this.props.clusterStrokeWidth === 0 ? null : new Stroke$2({
            color: this.props.clusterStrokeColor || "rgb(0,0,0)",
            width: this.props.clusterStrokeWidth || 1
          })
        }),
        text: new Text$2({
          text: size.toString(),
          fill: new Fill$2({
            color: this.props.clusterTextColor || "#fff"
          })
        })
      });
    } else {
      let originalFeature = feature2.get("features")[0];
      style = this.createPolygonStyle(originalFeature);
    }
    return style;
  }
  createPolygonStyle(feature2) {
    let style;
    if (this.oneStyle) {
      style = this.oneStyle.clone();
      style.setGeometry(feature2.getGeometry());
    } else {
      style = new Style$1({
        geometry: feature2.getGeometry(),
        image: new Circle$1({
          radius: 5,
          fill: new Fill$2({
            color: [255, 255, 255, 0.5]
          }),
          stroke: new Stroke$2({
            color: "#31d3f0",
            width: 1
          })
        })
      });
    }
    return style;
  }
  setOneSyle(style) {
    this.oneStyle = style;
  }
  createLayer() {
    this.clusterSource = new VectorSource$2({
      features: []
    });
    const cluster = new Cluster$1({
      distance: this.props.distance || 30,
      source: this.clusterSource
    });
    this.layer = new VectorLayer$2({
      source: cluster,
      style: this.styleFunction.bind(this),
      minZoom: this.props.minZoom,
      maxZoom: this.props.maxZoom,
      opacity: this.props.opacity
    });
  }
  addLayerToMap() {
    var _a, _b;
    if (!this.isDraw && this.mapFinish.value) {
      this.isDraw = true;
      (_b = (_a = this.gyMapObj.value) == null ? void 0 : _a.map) == null ? void 0 : _b.addLayer(this.layer);
      this.addSelectFeatureFun();
    }
  }
  addWatchFun() {
    watch(this.mapFinish, () => {
      this.addLayerToMap();
    });
  }
  selectStyleFunction(feature2) {
    const styles = [
      new Style$1({
        image: new Circle$1({
          radius: 10,
          fill: new Fill$2({
            color: "rgba(255, 255, 255, 0)"
          })
        })
      })
    ];
    const originalFeatures = feature2.get("features");
    let originalFeature;
    for (let i = originalFeatures.length - 1; i >= 0; --i) {
      originalFeature = originalFeatures[i];
      styles.push(this.createPolygonStyle(originalFeature));
    }
    return styles;
  }
  addSelectFeatureFun() {
    var _a, _b;
    if (!this.props.isSelect) {
      return;
    }
    const select = new Select$1({
      condition: function(evt) {
        return evt.type == "pointermove" || evt.type == "singleclick";
      },
      style: this.selectStyleFunction.bind(this)
    });
    (_b = (_a = this.gyMapObj.value) == null ? void 0 : _a.map) == null ? void 0 : _b.addInteraction(select);
  }
}
const __vue2_script = defineComponent({
  name: "GymapClusters",
  props: {
    mapId: {
      type: String,
      default: ""
    },
    isSelect: {
      type: Boolean,
      default: false
    },
    distance: {
      type: Number,
      default: 30
    },
    radiusMultiplier: {
      type: Number,
      default: 0.5
    },
    clusterFullColor: {
      type: String,
      default: ""
    },
    clusterStrokeColor: {
      type: String,
      default: ""
    },
    clusterTextColor: {
      type: String,
      default: ""
    },
    clusterStrokeWidth: {
      type: Number,
      default: 1
    },
    minZoom: {
      type: Number,
      default: 1
    },
    maxZoom: {
      type: Number,
      default: 18
    },
    opacity: {
      type: Number,
      default: 1
    }
  },
  emits: ["clickFun"],
  setup(props, { emit }) {
    const { proxy } = getCurrentInstance();
    const mapId = props.mapId || proxy.$parent.id;
    const clusters = new CreateClusterLayer(mapId, props.points, props);
    const clusterSource = clusters.clusterSource;
    const setParentStylesByLayer = (layer) => {
      clusters.setOneSyle(layer.getStyle());
    };
    onMounted(() => {
    });
    onBeforeUnmount(() => {
    });
    return {
      id: mapId,
      clusterSource,
      setParentStylesByLayer
    };
  }
});
var render = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div", [_vm._t("default")], 2);
};
var staticRenderFns = [];
const __cssModules = {};
var __component__ = /* @__PURE__ */ normalizeComponent(
  __vue2_script,
  render,
  staticRenderFns,
  false,
  __vue2_injectStyles,
  null,
  null,
  null
);
function __vue2_injectStyles(context) {
  for (let o in __cssModules) {
    this[o] = __cssModules[o];
  }
}
const GymapClusters = /* @__PURE__ */ function() {
  return __component__.exports;
}();
const components = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  Gymap,
  GymapHtml,
  GymapPolygon,
  GymapLine,
  GymapTask,
  GymapCircle,
  GymapText,
  GymapImage,
  GymapDraw,
  GymapHeat,
  GymapLonlat,
  GymapClusters
}, Symbol.toStringTag, { value: "Module" }));
const MapEventType = {
  POSTRENDER: "postrender",
  MOVESTART: "movestart",
  MOVEEND: "moveend",
  LOADSTART: "loadstart",
  LOADEND: "loadend"
};
class Control extends BaseObject$1 {
  constructor(options) {
    super();
    const element = options.element;
    if (element && !options.target && !element.style.pointerEvents) {
      element.style.pointerEvents = "auto";
    }
    this.element = element ? element : null;
    this.target_ = null;
    this.map_ = null;
    this.listenerKeys = [];
    if (options.render) {
      this.render = options.render;
    }
    if (options.target) {
      this.setTarget(options.target);
    }
  }
  disposeInternal() {
    var _a;
    (_a = this.element) == null ? void 0 : _a.remove();
    super.disposeInternal();
  }
  getMap() {
    return this.map_;
  }
  setMap(map) {
    var _a, _b;
    if (this.map_) {
      (_a = this.element) == null ? void 0 : _a.remove();
    }
    for (let i = 0, ii = this.listenerKeys.length; i < ii; ++i) {
      unlistenByKey(this.listenerKeys[i]);
    }
    this.listenerKeys.length = 0;
    this.map_ = map;
    if (map) {
      const target = (_b = this.target_) != null ? _b : map.getOverlayContainerStopEvent();
      if (this.element) {
        target.appendChild(this.element);
      }
      if (this.render !== VOID) {
        this.listenerKeys.push(
          listen(map, MapEventType.POSTRENDER, this.render, this)
        );
      }
      map.render();
    }
  }
  render(mapEvent) {
  }
  setTarget(target) {
    this.target_ = typeof target === "string" ? document.getElementById(target) : target;
  }
}
const Control$1 = Control;
class Attribution extends Control$1 {
  constructor(options) {
    options = options ? options : {};
    super({
      element: document.createElement("div"),
      render: options.render,
      target: options.target
    });
    this.ulElement_ = document.createElement("ul");
    this.collapsed_ = options.collapsed !== void 0 ? options.collapsed : true;
    this.userCollapsed_ = this.collapsed_;
    this.overrideCollapsible_ = options.collapsible !== void 0;
    this.collapsible_ = options.collapsible !== void 0 ? options.collapsible : true;
    if (!this.collapsible_) {
      this.collapsed_ = false;
    }
    this.attributions_ = options.attributions;
    const className = options.className !== void 0 ? options.className : "ol-attribution";
    const tipLabel = options.tipLabel !== void 0 ? options.tipLabel : "Attributions";
    const expandClassName = options.expandClassName !== void 0 ? options.expandClassName : className + "-expand";
    const collapseLabel = options.collapseLabel !== void 0 ? options.collapseLabel : "\u203A";
    const collapseClassName = options.collapseClassName !== void 0 ? options.collapseClassName : className + "-collapse";
    if (typeof collapseLabel === "string") {
      this.collapseLabel_ = document.createElement("span");
      this.collapseLabel_.textContent = collapseLabel;
      this.collapseLabel_.className = collapseClassName;
    } else {
      this.collapseLabel_ = collapseLabel;
    }
    const label = options.label !== void 0 ? options.label : "i";
    if (typeof label === "string") {
      this.label_ = document.createElement("span");
      this.label_.textContent = label;
      this.label_.className = expandClassName;
    } else {
      this.label_ = label;
    }
    const activeLabel = this.collapsible_ && !this.collapsed_ ? this.collapseLabel_ : this.label_;
    this.toggleButton_ = document.createElement("button");
    this.toggleButton_.setAttribute("type", "button");
    this.toggleButton_.setAttribute("aria-expanded", String(!this.collapsed_));
    this.toggleButton_.title = tipLabel;
    this.toggleButton_.appendChild(activeLabel);
    this.toggleButton_.addEventListener(
      EventType.CLICK,
      this.handleClick_.bind(this),
      false
    );
    const cssClasses = className + " " + CLASS_UNSELECTABLE + " " + CLASS_CONTROL + (this.collapsed_ && this.collapsible_ ? " " + CLASS_COLLAPSED : "") + (this.collapsible_ ? "" : " ol-uncollapsible");
    const element = this.element;
    element.className = cssClasses;
    element.appendChild(this.toggleButton_);
    element.appendChild(this.ulElement_);
    this.renderedAttributions_ = [];
    this.renderedVisible_ = true;
  }
  collectSourceAttributions_(frameState) {
    const layers = this.getMap().getAllLayers();
    const visibleAttributions = new Set(
      layers.flatMap((layer) => layer.getAttributions(frameState))
    );
    if (this.attributions_ !== void 0) {
      Array.isArray(this.attributions_) ? this.attributions_.forEach((item) => visibleAttributions.add(item)) : visibleAttributions.add(this.attributions_);
    }
    if (!this.overrideCollapsible_) {
      const collapsible = !layers.some(
        (layer) => {
          var _a;
          return ((_a = layer.getSource()) == null ? void 0 : _a.getAttributionsCollapsible()) === false;
        }
      );
      this.setCollapsible(collapsible);
    }
    return Array.from(visibleAttributions);
  }
  async updateElement_(frameState) {
    if (!frameState) {
      if (this.renderedVisible_) {
        this.element.style.display = "none";
        this.renderedVisible_ = false;
      }
      return;
    }
    const attributions = await Promise.all(
      this.collectSourceAttributions_(frameState).map(
        (attribution) => toPromise(() => attribution)
      )
    );
    const visible = attributions.length > 0;
    if (this.renderedVisible_ != visible) {
      this.element.style.display = visible ? "" : "none";
      this.renderedVisible_ = visible;
    }
    if (equals$2(attributions, this.renderedAttributions_)) {
      return;
    }
    removeChildren(this.ulElement_);
    for (let i = 0, ii = attributions.length; i < ii; ++i) {
      const element = document.createElement("li");
      element.innerHTML = attributions[i];
      this.ulElement_.appendChild(element);
    }
    this.renderedAttributions_ = attributions;
  }
  handleClick_(event) {
    event.preventDefault();
    this.handleToggle_();
    this.userCollapsed_ = this.collapsed_;
  }
  handleToggle_() {
    this.element.classList.toggle(CLASS_COLLAPSED);
    if (this.collapsed_) {
      replaceNode(this.collapseLabel_, this.label_);
    } else {
      replaceNode(this.label_, this.collapseLabel_);
    }
    this.collapsed_ = !this.collapsed_;
    this.toggleButton_.setAttribute("aria-expanded", String(!this.collapsed_));
  }
  getCollapsible() {
    return this.collapsible_;
  }
  setCollapsible(collapsible) {
    if (this.collapsible_ === collapsible) {
      return;
    }
    this.collapsible_ = collapsible;
    this.element.classList.toggle("ol-uncollapsible");
    if (this.userCollapsed_) {
      this.handleToggle_();
    }
  }
  setCollapsed(collapsed) {
    this.userCollapsed_ = collapsed;
    if (!this.collapsible_ || this.collapsed_ === collapsed) {
      return;
    }
    this.handleToggle_();
  }
  getCollapsed() {
    return this.collapsed_;
  }
  render(mapEvent) {
    this.updateElement_(mapEvent.frameState);
  }
}
const Attribution$1 = Attribution;
class Rotate extends Control$1 {
  constructor(options) {
    options = options ? options : {};
    super({
      element: document.createElement("div"),
      render: options.render,
      target: options.target
    });
    const className = options.className !== void 0 ? options.className : "ol-rotate";
    const label = options.label !== void 0 ? options.label : "\u21E7";
    const compassClassName = options.compassClassName !== void 0 ? options.compassClassName : "ol-compass";
    this.label_ = null;
    if (typeof label === "string") {
      this.label_ = document.createElement("span");
      this.label_.className = compassClassName;
      this.label_.textContent = label;
    } else {
      this.label_ = label;
      this.label_.classList.add(compassClassName);
    }
    const tipLabel = options.tipLabel ? options.tipLabel : "Reset rotation";
    const button = document.createElement("button");
    button.className = className + "-reset";
    button.setAttribute("type", "button");
    button.title = tipLabel;
    button.appendChild(this.label_);
    button.addEventListener(
      EventType.CLICK,
      this.handleClick_.bind(this),
      false
    );
    const cssClasses = className + " " + CLASS_UNSELECTABLE + " " + CLASS_CONTROL;
    const element = this.element;
    element.className = cssClasses;
    element.appendChild(button);
    this.callResetNorth_ = options.resetNorth ? options.resetNorth : void 0;
    this.duration_ = options.duration !== void 0 ? options.duration : 250;
    this.autoHide_ = options.autoHide !== void 0 ? options.autoHide : true;
    this.rotation_ = void 0;
    if (this.autoHide_) {
      this.element.classList.add(CLASS_HIDDEN);
    }
  }
  handleClick_(event) {
    event.preventDefault();
    if (this.callResetNorth_ !== void 0) {
      this.callResetNorth_();
    } else {
      this.resetNorth_();
    }
  }
  resetNorth_() {
    const map = this.getMap();
    const view = map.getView();
    if (!view) {
      return;
    }
    const rotation = view.getRotation();
    if (rotation !== void 0) {
      if (this.duration_ > 0 && rotation % (2 * Math.PI) !== 0) {
        view.animate({
          rotation: 0,
          duration: this.duration_,
          easing: easeOut
        });
      } else {
        view.setRotation(0);
      }
    }
  }
  render(mapEvent) {
    const frameState = mapEvent.frameState;
    if (!frameState) {
      return;
    }
    const rotation = frameState.viewState.rotation;
    if (rotation != this.rotation_) {
      const transform = "rotate(" + rotation + "rad)";
      if (this.autoHide_) {
        const contains2 = this.element.classList.contains(CLASS_HIDDEN);
        if (!contains2 && rotation === 0) {
          this.element.classList.add(CLASS_HIDDEN);
        } else if (contains2 && rotation !== 0) {
          this.element.classList.remove(CLASS_HIDDEN);
        }
      }
      this.label_.style.transform = transform;
    }
    this.rotation_ = rotation;
  }
}
const Rotate$1 = Rotate;
class Zoom extends Control$1 {
  constructor(options) {
    options = options ? options : {};
    super({
      element: document.createElement("div"),
      target: options.target
    });
    const className = options.className !== void 0 ? options.className : "ol-zoom";
    const delta = options.delta !== void 0 ? options.delta : 1;
    const zoomInClassName = options.zoomInClassName !== void 0 ? options.zoomInClassName : className + "-in";
    const zoomOutClassName = options.zoomOutClassName !== void 0 ? options.zoomOutClassName : className + "-out";
    const zoomInLabel = options.zoomInLabel !== void 0 ? options.zoomInLabel : "+";
    const zoomOutLabel = options.zoomOutLabel !== void 0 ? options.zoomOutLabel : "\u2013";
    const zoomInTipLabel = options.zoomInTipLabel !== void 0 ? options.zoomInTipLabel : "Zoom in";
    const zoomOutTipLabel = options.zoomOutTipLabel !== void 0 ? options.zoomOutTipLabel : "Zoom out";
    const inElement = document.createElement("button");
    inElement.className = zoomInClassName;
    inElement.setAttribute("type", "button");
    inElement.title = zoomInTipLabel;
    inElement.appendChild(
      typeof zoomInLabel === "string" ? document.createTextNode(zoomInLabel) : zoomInLabel
    );
    inElement.addEventListener(
      EventType.CLICK,
      this.handleClick_.bind(this, delta),
      false
    );
    const outElement = document.createElement("button");
    outElement.className = zoomOutClassName;
    outElement.setAttribute("type", "button");
    outElement.title = zoomOutTipLabel;
    outElement.appendChild(
      typeof zoomOutLabel === "string" ? document.createTextNode(zoomOutLabel) : zoomOutLabel
    );
    outElement.addEventListener(
      EventType.CLICK,
      this.handleClick_.bind(this, -delta),
      false
    );
    const cssClasses = className + " " + CLASS_UNSELECTABLE + " " + CLASS_CONTROL;
    const element = this.element;
    element.className = cssClasses;
    element.appendChild(inElement);
    element.appendChild(outElement);
    this.duration_ = options.duration !== void 0 ? options.duration : 250;
  }
  handleClick_(delta, event) {
    event.preventDefault();
    this.zoomByDelta_(delta);
  }
  zoomByDelta_(delta) {
    const map = this.getMap();
    const view = map.getView();
    if (!view) {
      return;
    }
    const currentZoom = view.getZoom();
    if (currentZoom !== void 0) {
      const newZoom = view.getConstrainedZoom(currentZoom + delta);
      if (this.duration_ > 0) {
        if (view.getAnimating()) {
          view.cancelAnimations();
        }
        view.animate({
          zoom: newZoom,
          duration: this.duration_,
          easing: easeOut
        });
      } else {
        view.setZoom(newZoom);
      }
    }
  }
}
const Zoom$1 = Zoom;
function defaults(options) {
  options = options ? options : {};
  const controls = new Collection$1();
  const zoomControl = options.zoom !== void 0 ? options.zoom : true;
  if (zoomControl) {
    controls.push(new Zoom$1(options.zoomOptions));
  }
  const rotateControl = options.rotate !== void 0 ? options.rotate : true;
  if (rotateControl) {
    controls.push(new Rotate$1(options.rotateOptions));
  }
  const attributionControl = options.attribution !== void 0 ? options.attribution : true;
  if (attributionControl) {
    controls.push(new Attribution$1(options.attributionOptions));
  }
  return controls;
}
let gyMapResultObj = {};
const gyMapInit = (type) => {
  type = type || "";
  if (type && gyMapResultObj[type]) {
    return gyMapResultObj[type];
  }
  const getRightZoom = (zoom2) => {
    return Math.max(mapOpt.minZoom, Math.min(Number(zoom2 || 0), mapOpt.maxZoom));
  };
  const formatOpt = () => {
    mapOpt.minZoom = Math.min(1, mapOpt.minZoom);
    mapOpt.maxZoom = Math.max(18, mapOpt.maxZoom);
    zoom.value = getRightZoom(mapOpt.zoom);
  };
  let map = ref(null);
  let view = ref(null);
  let mapOpt = {
    layerOpacity: 1,
    maplayerIndex: 0,
    centerPoint: [116.40531, 39.896884],
    minZoom: 1,
    maxZoom: 18,
    zoom: 16,
    extent: void 0,
    stopPropagation: true,
    mapUrlList: [
      "http://wprd01.is.autonavi.com/appmaptile?style=7&x={x}&y={y}&z={z}"
    ]
  };
  let zoom = ref(getRightZoom(mapOpt.zoom));
  let contentId = "";
  let tileLayerList = [];
  let layerIndex = -1;
  ({
    ...gyMapUtils
  });
  let mapFinish = ref(false);
  const init = (id, opt) => {
    if (!id) {
      console.error(`not find ${id}`);
      return;
    }
    initOptions(id, opt);
    initTileLayerList();
    initMap();
    changeMapLayer(mapOpt.maplayerIndex);
  };
  let initOptions = (id, opt) => {
    contentId = id;
    mapOpt = Object.assign({}, mapOpt, opt);
    formatOpt();
    let extent = mapOpt.extent || void 0;
    if (extent) {
      let lonlat1 = extent[0];
      let lonlat2 = extent[1];
      if (lonlat1 && lonlat2) {
        let c1 = gyMapUtils.formatLonLatToPosition(lonlat1);
        let c2 = gyMapUtils.formatLonLatToPosition(lonlat2);
        let ex = [
          Math.min(c1[0], c2[0]),
          Math.min(c1[1], c2[1]),
          Math.max(c1[0], c2[0]),
          Math.max(c1[1], c2[1])
        ];
        mapOpt.extent = ex;
      } else {
        mapOpt.extent = void 0;
      }
    }
  };
  const initMap = () => {
    view.value = markRaw(new View$2({
      center: gyMapUtils.formatLonLatToPosition(mapOpt.centerPoint),
      zoom: zoom.value,
      minZoom: mapOpt.minZoom,
      maxZoom: mapOpt.maxZoom,
      extent: mapOpt.extent
    }));
    map.value = markRaw(new Map({
      layers: tileLayerList,
      target: contentId,
      view: view.value,
      controls: defaults({
        zoom: mapOpt.isShowControls,
        attribution: false,
        rotate: true
      }),
      interactions: defaults$1(
        mapOpt.interactionsObj || {}
      )
    }));
    mapFinish.value = true;
    map.value.on("click", (e) => {
      map.value.forEachFeatureAtPixel(e.pixel, function(feature2) {
        feature2.dispatchEvent({ type: "click", e });
        return mapOpt.stopPropagation;
      });
    });
    map.value.on("moveend", function(e) {
      zoom.value = map.value.getView().getZoom();
    });
  };
  const initTileLayerList = () => {
    tileLayerList = [];
    let mapUrlList = mapOpt.mapUrlList;
    if (!Array.isArray(mapUrlList)) {
      mapUrlList = [mapUrlList];
    }
    mapUrlList.forEach((v) => {
      tileLayerList.push(
        new TileLayer({
          visible: false,
          opacity: mapOpt.layerOpacity,
          source: new XYZ({
            maxZoom: 18,
            url: v
          })
        })
      );
    });
  };
  const zoomSetFun = (val) => {
    let zoomVal = getRightZoom(Number(val));
    if (zoomVal === zoom.value) {
      return;
    }
    view.value && view.value.animate({ zoom: zoomVal, duration: 800 });
    zoom.value = zoomVal;
  };
  const zoomAddFun = () => {
    zoomSetFun(zoom.value + 1);
  };
  const zoomSubFun = () => {
    zoomSetFun(zoom.value - 1);
  };
  const changeMapLayer = (index2) => {
    var _a, _b;
    index2 = Number(index2 || 0);
    if (layerIndex === index2) {
      return;
    }
    let len = tileLayerList.length;
    let i = Math.max(0, Math.min(index2, len));
    if (layerIndex !== -1) {
      (_a = tileLayerList[layerIndex]) == null ? void 0 : _a.setVisible(false);
    }
    (_b = tileLayerList[i]) == null ? void 0 : _b.setVisible(true);
    layerIndex = i;
  };
  const changeCenterPoint = (center) => {
    let point = gyMapUtils.formatLonLatToPosition(center);
    view.value && view.value.animate({ center: point, duration: 800 });
  };
  const drawHtmlToMap = (id, {
    position,
    offset = [0, 0],
    stopEvent = true,
    className = ""
  }) => {
    let dom = null;
    if (typeof id === "object") {
      if (id instanceof HTMLElement) {
        dom = [id];
      } else {
        console.error(`\u8BF7\u4F20\u5165\u6B63\u786E\u7684dom\u5BF9\u8C61\uFF01`);
        return null;
      }
    } else if (typeof id === "string") {
      dom = document.querySelectorAll(id);
      if (dom.length === 0) {
        console.error(`not find ${id}`);
        return null;
      }
    }
    if (!Array.isArray(position)) {
      console.error(`position \u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u5E94\u8BE5\u4E3A [\u7ECF\u5EA6\uFF0C\u7EAC\u5EA6]`);
      return null;
    }
    let overlayList = [];
    Array.prototype.forEach.call(dom, (v) => {
      let overlay = new Overlay({
        element: v,
        position: gyMapUtils.formatLonLatToPosition(position),
        insertFirst: false,
        autoPan: false,
        stopEvent,
        className: "ol-overlay-container ol-selectable " + className,
        offset
      });
      map.value && map.value.addOverlay(overlay);
      overlayList.push(overlay);
    });
    if (overlayList.length === 1) {
      return overlayList[0];
    } else {
      return overlayList;
    }
  };
  const removeOverlay = (overlay) => {
    overlay && map.value && map.value.removeOverlay(overlay);
  };
  const setLayerOpacity = (val) => {
    let layer = tileLayerList[layerIndex];
    layer && layer.setOpacity(val);
  };
  const destory = () => {
    delete gyMapResultObj[type];
  };
  let result = ref({
    contentId: type,
    map,
    view,
    mapFinish,
    zoom,
    init,
    zoomSetFun,
    zoomAddFun,
    zoomSubFun,
    changeMapLayer,
    changeCenterPoint,
    drawHtmlToMap,
    removeOverlay,
    setLayerOpacity,
    destory
  });
  gyMapResultObj[type] = result;
  return result;
};
const gyMap = (type) => {
  if (gyMapResultObj[type]) {
    return gyMapResultObj[type];
  }
  return gyMapInit.call(void 0, type);
};
const gyMap$1 = gyMap;
let install = (Vue) => {
  if (!install.installed) {
    const _components = Object.keys(components).map(
      (key) => components[key]
    );
    _components.forEach((component) => {
      if ((component.hasOwnProperty("name") || component.hasOwnProperty("__name")) && component.hasOwnProperty("setup")) {
        Vue.component(component.name || component.__name, component);
      }
    });
  }
};
const index = {
  install
};
export {
  Gymap,
  GymapCircle,
  GymapClusters,
  GymapDraw,
  GymapHeat,
  GymapHtml,
  GymapImage,
  GymapLine,
  GymapLonlat,
  GymapPolygon,
  GymapTask,
  GymapText,
  index as default,
  gyMap$1 as gyMap,
  gyMapUtils,
  install
};