UNPKG

3d-tiles-renderer

Version:

https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/specification

5,322 lines 201 kB
import { Q as Un, b as Vn, C as Fn, a as Nn } from "./QuantizedMeshLoaderBase-DA143Nnz.js";
import { PlaneGeometry as qt, Mesh as Oe, MeshBasicMaterial as Ue, Vector2 as q, MathUtils as M, Vector3 as E, Sphere as he, Texture as kn, SRGBColorSpace as Ks, TextureUtils as Gn, DefaultLoadingManager as jn, BufferGeometry as et, MeshStandardMaterial as en, BufferAttribute as J, DataTexture as Wt, RGFormat as tn, UnsignedByteType as sn, LinearMipMapLinearFilter as zn, LinearFilter as nn, Triangle as Xt, Vector4 as Ve, Matrix4 as K, Matrix3 as Hn, Matrix2 as qn, WebGLRenderer as Wn, WebGLRenderTarget as Ft, ShaderMaterial as rn, OneFactor as Xn, ZeroFactor as Yn, CustomBlending as $n, Box2 as Qn, FileLoader as Zn, Quaternion as on, BatchedMesh as Jn, Source as Kn, Box3 as lt, REVISION as ei, WebGLArrayRenderTarget as ss, Raycaster as ti, DoubleSide as an, OrthographicCamera as si, Color as Yt, CanvasTexture as ln, Ray as ni, LineSegments as cn, LineBasicMaterial as ii, EdgesGeometry as ri, BoxGeometry as oi, Group as Ge, Box3Helper as ai, PointsMaterial as li } from "three";
import { a as un, O as ci, W as ui, g as hi, c as di, b as pi } from "./MemoryUtils-R1TfIs9h.js";
import { GLTFLoader as fi } from "three/examples/jsm/loaders/GLTFLoader.js";
import { FullScreenQuad as hn } from "three/examples/jsm/postprocessing/Pass.js";
import { L as mi, f as gi, e as ns, W as dn } from "./constants-z3YLhXg0.js";
import { b as yi, L as pn } from "./LoaderBase-CfTLVHyZ.js";
const fe = /* @__PURE__ */ new q(), xe = Symbol("TILE_X"), Te = Symbol("TILE_Y"), oe = Symbol("TILE_LEVEL");
class fn {
  get tiling() {
    return this.imageSource.tiling;
  }
  constructor(e = {}) {
    const {
      pixelSize: t = null,
      center: s = !1,
      useRecommendedSettings: n = !0,
      imageSource: i = null
    } = e;
    this.priority = -10, this.tiles = null, this.imageSource = i, this.pixelSize = t, this.center = s, this.useRecommendedSettings = n, t !== null && console.warn('ImageFormatPlugin: "pixelSize" has been deprecated in favor of scaling the tiles root.');
  }
  // Plugin functions
  init(e) {
    this.useRecommendedSettings && (e.errorTarget = 1), this.tiles = e, this.imageSource.fetchOptions = e.fetchOptions, this.imageSource.fetchData = (t, s) => (e.invokeAllPlugins((n) => t = n.preprocessURL ? n.preprocessURL(t, null) : t), e.invokeOnePlugin((n) => n !== this && n.fetchData && n.fetchData(t, s)));
  }
  async loadRootTileset() {
    const { tiles: e, imageSource: t } = this;
    return t.url = t.url || e.rootURL, e.invokeAllPlugins((s) => t.url = s.preprocessURL ? s.preprocessURL(t.url, null) : t.url), await t.init(), e.rootURL = t.url, this.getTileset(t.url);
  }
  async parseToMesh(e, t, s, n, i) {
    if (i.aborted)
      return null;
    const { imageSource: r } = this, o = t[xe], l = t[Te], c = t[oe], u = await r.processBufferToTexture(e);
    if (i.aborted)
      return u.dispose(), u.image.close(), null;
    r.setData(o, l, c, u);
    let h = 1, d = 1, m = 0, f = 0, p = 0;
    const g = t.boundingVolume.box;
    g && ([m, f, p] = g, h = g[3], d = g[7]);
    const y = new qt(2 * h, 2 * d), x = new Oe(y, new Ue({ map: u, transparent: !0 }));
    x.position.set(m, f, p);
    const _ = r.tiling.getTileContentUVBounds(o, l, c), { uv: S } = y.attributes;
    for (let b = 0; b < S.count; b++)
      fe.fromBufferAttribute(S, b), fe.x = M.mapLinear(fe.x, 0, 1, _[0], _[2]), fe.y = M.mapLinear(fe.y, 0, 1, _[1], _[3]), S.setXY(b, fe.x, fe.y);
    return x;
  }
  preprocessNode(e) {
    const { tiling: t } = this, s = t.maxLevel;
    e[oe] < s && e.parent !== null && this.expandChildren(e);
  }
  disposeTile(e) {
    const t = e[xe], s = e[Te], n = e[oe], { imageSource: i } = this;
    i.has(t, s, n) && i.release(t, s, n);
  }
  // Local functions
  getTileset(e) {
    const { tiling: t, tiles: s } = this, n = t.minLevel, { tileCountX: i, tileCountY: r } = t.getLevel(n), o = [];
    for (let c = 0; c < i; c++)
      for (let u = 0; u < r; u++) {
        const h = this.createChild(c, u, n);
        h !== null && o.push(h);
      }
    const l = {
      asset: {
        version: "1.1"
      },
      geometricError: 1e5,
      root: {
        refine: "REPLACE",
        geometricError: 1e5,
        boundingVolume: this.createBoundingVolume(0, 0, -1),
        children: o,
        [oe]: -1,
        [xe]: 0,
        [Te]: 0
      }
    };
    return s.preprocessTileset(l, e), l;
  }
  getUrl(e, t, s) {
    return this.imageSource.getUrl(e, t, s);
  }
  createBoundingVolume(e, t, s) {
    const { center: n, pixelSize: i, tiling: r } = this, { pixelWidth: o, pixelHeight: l } = r.getLevel(r.maxLevel), [c, u, h, d] = s === -1 ? r.getContentBounds(!0) : r.getTileBounds(e, t, s, !0);
    let m = (h - c) / 2, f = (d - u) / 2, p = c + m, g = u + f;
    return n && (p -= 0.5, g -= 0.5), i ? (p *= o * i, m *= o * i, g *= l * i, f *= l * i) : (p *= r.aspectRatio, m *= r.aspectRatio), {
      box: [
        // center
        p,
        g,
        0,
        // x, y, z half vectors
        m,
        0,
        0,
        0,
        f,
        0,
        0,
        0,
        0
      ]
    };
  }
  createChild(e, t, s) {
    const { pixelSize: n, tiling: i } = this;
    if (!i.getTileExists(e, t, s))
      return null;
    const { pixelWidth: r, pixelHeight: o } = i.getLevel(s);
    let l = Math.max(i.aspectRatio / r, 1 / o);
    if (n) {
      const c = i.getLevel(i.maxLevel);
      l *= n * Math.max(c.pixelWidth, c.pixelHeight);
    }
    return {
      refine: "REPLACE",
      geometricError: l,
      boundingVolume: this.createBoundingVolume(e, t, s),
      content: {
        uri: this.getUrl(e, t, s)
      },
      children: [],
      // save the tile params so we can expand later
      [xe]: e,
      [Te]: t,
      [oe]: s
    };
  }
  expandChildren(e) {
    const t = e[oe], s = e[xe], n = e[Te];
    for (let i = 0; i < 2; i++)
      for (let r = 0; r < 2; r++) {
        const o = this.createChild(2 * s + i, 2 * n + r, t + 1);
        o && e.children.push(o);
      }
  }
}
const pt = /* @__PURE__ */ new E(), je = /* @__PURE__ */ new E();
function xi(a, e, t) {
  const n = t + 1e-5;
  let i = e + 1e-5;
  Math.abs(i) > Math.PI / 2 && (i = i - 1e-5), a.getCartographicToPosition(e, t, 0, pt), a.getCartographicToPosition(i, t, 0, je);
  const r = pt.distanceTo(je) / 1e-5;
  return a.getCartographicToPosition(e, n, 0, je), [pt.distanceTo(je) / 1e-5, r];
}
const Ti = 30, bi = 15, ft = /* @__PURE__ */ new E(), is = /* @__PURE__ */ new E(), ie = /* @__PURE__ */ new q(), mt = /* @__PURE__ */ new he();
class ct extends fn {
  get projection() {
    return this.tiling.projection;
  }
  constructor(e = {}) {
    const {
      shape: t = "planar",
      endCaps: s = !0,
      ...n
    } = e;
    super(n), this.shape = t, this.endCaps = s;
  }
  // override the parse to mesh logic to support a region mesh
  async parseToMesh(e, t, ...s) {
    const n = await super.parseToMesh(e, t, ...s), { shape: i, projection: r, tiles: o, tiling: l } = this;
    if (i === "ellipsoid") {
      const c = o.ellipsoid, u = t[oe], h = t[xe], d = t[Te], [m, f, p, g] = t.boundingVolume.region, y = Math.ceil((g - f) * M.RAD2DEG * 0.25), x = Math.ceil((p - m) * M.RAD2DEG * 0.25), T = Math.max(bi, y), _ = Math.max(Ti, x), S = new qt(1, 1, _, T), [b, C, A, w] = l.getTileBounds(h, d, u, !0, !0), P = l.getTileContentUVBounds(h, d, u), { position: U, normal: B, uv: W } = S.attributes, $ = U.count;
      t.cached.boundingVolume.getSphere(mt);
      for (let z = 0; z < $; z++) {
        ft.fromBufferAttribute(U, z), ie.fromBufferAttribute(W, z);
        const L = r.convertProjectionToLongitude(M.mapLinear(ie.x, 0, 1, b, A));
        let v = r.convertProjectionToLatitude(M.mapLinear(ie.y, 0, 1, C, w));
        if (r.isMercator && this.endCaps && (w === 1 && ie.y === 1 && (v = Math.PI / 2), C === 0 && ie.y === 0 && (v = -Math.PI / 2)), r.isMercator && ie.y !== 0 && ie.y !== 1) {
          const I = r.convertProjectionToLatitude(1), N = 1 / T, Q = M.mapLinear(ie.y - N, 0, 1, f, g), k = M.mapLinear(ie.y + N, 0, 1, f, g);
          v > I && Q < I && (v = I), v < -I && k > -I && (v = -I);
        }
        c.getCartographicToPosition(v, L, 0, ft).sub(mt.center), c.getCartographicToNormal(v, L, is);
        const D = M.mapLinear(r.convertLongitudeToProjection(L), b, A, P[0], P[2]), V = M.mapLinear(r.convertLatitudeToProjection(v), C, w, P[1], P[3]);
        W.setXY(z, D, V), U.setXYZ(z, ...ft), B.setXYZ(z, ...is);
      }
      n.geometry = S, n.position.copy(mt.center);
    }
    return n;
  }
  createBoundingVolume(e, t, s) {
    if (this.shape === "ellipsoid") {
      const { tiling: n, endCaps: i } = this, r = s === -1, o = r ? n.getContentBounds(!0) : n.getTileBounds(e, t, s, !0, !0), l = r ? n.getContentBounds() : n.getTileBounds(e, t, s, !1, !0);
      return i && (o[3] === 1 && (l[3] = Math.PI / 2), o[1] === 0 && (l[1] = -Math.PI / 2)), {
        region: [...l, -1, 1]
      };
    } else
      return super.createBoundingVolume(e, t, s);
  }
  createChild(...e) {
    const t = super.createChild(...e), { shape: s, projection: n, tiling: i } = this;
    if (t && s === "ellipsoid") {
      const r = t[oe], o = t[xe], l = t[Te];
      if (r === -1)
        return t.geometricError = 1e50, parent;
      const [c, u, h, d] = i.getTileBounds(o, l, r, !0), { tilePixelWidth: m, tilePixelHeight: f } = i.getLevel(r), p = (h - c) / m, g = (d - u) / f, [
        /* west */
        ,
        y,
        x,
        T
      ] = i.getTileBounds(o, l, r), _ = y > 0 != T > 0 ? 0 : Math.min(Math.abs(y), Math.abs(T)), S = n.convertLatitudeToProjection(_), b = n.getLongitudeDerivativeAtProjection(c), C = n.getLatitudeDerivativeAtProjection(S), [A, w] = xi(this.tiles.ellipsoid, _, x), P = Math.max(p * b * A, g * C * w);
      t.geometricError = P;
    }
    return t;
  }
}
class de {
  get isMercator() {
    return this.scheme === "EPSG:3857";
  }
  constructor(e = "EPSG:4326") {
    this.scheme = e, this.tileCountX = 1, this.tileCountY = 1, this.setScheme(e);
  }
  setScheme(e) {
    switch (this.scheme = e, e) {
      // equirect
      case "CRS:84":
      case "EPSG:4326":
        this.tileCountX = 2, this.tileCountY = 1;
        break;
      // mercator
      case "EPSG:3857":
        this.tileCountX = 1, this.tileCountY = 1;
        break;
      default:
        throw new Error(`ProjectionScheme: Unknown projection scheme "${e}"`);
    }
  }
  convertProjectionToLatitude(e) {
    if (this.isMercator) {
      const t = M.mapLinear(e, 0, 1, -1, 1);
      return 2 * Math.atan(Math.exp(t * Math.PI)) - Math.PI / 2;
    } else
      return M.mapLinear(e, 0, 1, -Math.PI / 2, Math.PI / 2);
  }
  convertProjectionToLongitude(e) {
    return M.mapLinear(e, 0, 1, -Math.PI, Math.PI);
  }
  convertLatitudeToProjection(e) {
    if (this.isMercator) {
      const t = Math.log(Math.tan(Math.PI / 4 + e / 2));
      return 1 / 2 + 1 * t / (2 * Math.PI);
    } else
      return M.mapLinear(e, -Math.PI / 2, Math.PI / 2, 0, 1);
  }
  convertLongitudeToProjection(e) {
    return (e + Math.PI) / (2 * Math.PI);
  }
  getLongitudeDerivativeAtProjection(e) {
    return 2 * Math.PI;
  }
  getLatitudeDerivativeAtProjection(e) {
    let s = e - 1e-5;
    return s < 0 && (s = e + 1e-5), this.isMercator ? Math.abs(this.convertProjectionToLatitude(e) - this.convertProjectionToLatitude(s)) / 1e-5 : Math.PI;
  }
  getBounds() {
    return [
      this.convertProjectionToLongitude(0),
      this.convertProjectionToLatitude(0),
      this.convertProjectionToLongitude(1),
      this.convertProjectionToLatitude(1)
    ];
  }
}
function ve(...a) {
  return a.join("_");
}
class _i {
  constructor() {
    this.cache = {}, this.count = 0, this.cachedBytes = 0, this.active = 0;
  }
  // overridable
  fetchItem() {
  }
  disposeItem() {
  }
  getMemoryUsage(e) {
    return 0;
  }
  // sets the data in the cache explicitly without need to load
  setData(...e) {
    const { cache: t } = this, s = e.pop(), n = ve(...e);
    if (n in t)
      throw new Error(`DataCache: "${n}" is already present.`);
    return this.cache[n] = {
      abortController: new AbortController(),
      result: s,
      count: 1,
      bytes: this.getMemoryUsage(s)
    }, this.count++, this.cachedBytes += this.cache[n].bytes, s;
  }
  // fetches the associated data if it doesn't exist and increments the lock counter
  lock(...e) {
    const { cache: t } = this, s = ve(...e);
    if (s in t)
      t[s].count++;
    else {
      const n = new AbortController(), i = {
        abortController: n,
        result: null,
        count: 1,
        bytes: 0
      };
      this.active++, i.result = this.fetchItem(e, n.signal), i.result instanceof Promise ? i.result.then((r) => (i.result = r, i.bytes = this.getMemoryUsage(r), this.cachedBytes += i.bytes, r)).finally(() => {
        this.active--;
      }).catch((r) => {
      }) : (this.active--, i.bytes = this.getMemoryUsage(i.result), this.cachedBytes += i.bytes), this.cache[s] = i, this.count++;
    }
    return t[s].result;
  }
  // decrements the lock counter for the item and deletes the item if it has reached zero
  release(...e) {
    const t = ve(...e);
    this.releaseViaFullKey(t);
  }
  // get the loaded item
  get(...e) {
    const { cache: t } = this, s = ve(...e);
    return s in t && t[s].count > 0 ? t[s].result : null;
  }
  has(...e) {
    const { cache: t } = this;
    return ve(...e) in t;
  }
  // dispose all items
  dispose() {
    const { cache: e } = this;
    for (const t in e) {
      const { abortController: s } = e[t];
      s.abort(), this.releaseViaFullKey(t, !0);
    }
    this.cache = {};
  }
  // releases an item with an optional force flag
  releaseViaFullKey(e, t = !1) {
    const { cache: s } = this;
    if (e in s && s[e].count > 0) {
      const n = s[e];
      if (n.count--, n.count === 0 || t) {
        const i = () => {
          if (s[e] !== n)
            return;
          const { result: r, abortController: o } = n;
          o.abort(), r instanceof Promise ? r.then((l) => {
            this.disposeItem(l), this.count--, this.cachedBytes -= n.bytes;
          }).catch(() => {
          }) : (this.disposeItem(r), this.count--, this.cachedBytes -= n.bytes), delete s[e];
        };
        t ? i() : queueMicrotask(() => {
          n.count === 0 && i();
        });
      }
      return !0;
    }
    throw new Error("DataCache: Attempting to release key that does not exist");
  }
}
function rs(a, e) {
  const [t, s, n, i] = a, [r, o, l, c] = e;
  return !(t >= l || n <= r || s >= c || i <= o);
}
class mn {
  get levelCount() {
    return this._levels.length;
  }
  get maxLevel() {
    return this.levelCount - 1;
  }
  get minLevel() {
    const e = this._levels;
    for (let t = 0; t < e.length; t++)
      if (e[t] !== null)
        return t;
    return -1;
  }
  // prioritize user-set bounds over projection bounds if present
  get contentBounds() {
    var e;
    return this._contentBounds ?? ((e = this.projection) == null ? void 0 : e.getBounds()) ?? [0, 0, 1, 1];
  }
  get aspectRatio() {
    const { pixelWidth: e, pixelHeight: t } = this.getLevel(this.maxLevel);
    return e / t;
  }
  constructor() {
    this.flipY = !1, this.pixelOverlap = 0, this._contentBounds = null, this.projection = null, this._levels = [];
  }
  // build the zoom levels
  setLevel(e, t = {}) {
    const s = this._levels;
    for (; s.length < e; )
      s.push(null);
    const {
      tilePixelWidth: n = 256,
      tilePixelHeight: i = 256,
      tileCountX: r = 2 ** e,
      tileCountY: o = 2 ** e,
      tileBounds: l = null
    } = t, {
      pixelWidth: c = n * r,
      pixelHeight: u = i * o
    } = t;
    s[e] = {
      // The pixel resolution of each tile.
      tilePixelWidth: n,
      tilePixelHeight: i,
      // The total pixel resolution of the final image at this level. These numbers
      // may not be a round multiple of the tile width.
      pixelWidth: c,
      pixelHeight: u,
      // Or the total number of tiles that can be loaded at this level.
      tileCountX: r,
      tileCountY: o,
      // The bounds covered by the extent of the tiles at this loaded. The actual content covered by the overall tileset
      // may be a subset of this range (eg there may be unused space).
      tileBounds: l
    };
  }
  generateLevels(e, t, s, n = {}) {
    const {
      minLevel: i = 0,
      tilePixelWidth: r = 256,
      tilePixelHeight: o = 256
    } = n, l = e - 1, {
      pixelWidth: c = r * t * 2 ** l,
      pixelHeight: u = o * s * 2 ** l
    } = n;
    for (let h = i; h < e; h++) {
      const d = e - h - 1, m = Math.ceil(c * 2 ** -d), f = Math.ceil(u * 2 ** -d), p = Math.ceil(m / r), g = Math.ceil(f / o);
      this.setLevel(h, {
        tilePixelWidth: r,
        tilePixelHeight: o,
        pixelWidth: m,
        pixelHeight: f,
        tileCountX: p,
        tileCountY: g
      });
    }
  }
  getLevel(e) {
    return this._levels[e];
  }
  // bounds representing the contentful region of the image
  setContentBounds(e, t, s, n) {
    this._contentBounds = [e, t, s, n];
  }
  setProjection(e) {
    this.projection = e;
  }
  // query functions
  getTileAtPoint(e, t, s, n = !1) {
    const { flipY: i } = this, { tileCountX: r, tileCountY: o, tileBounds: l } = this.getLevel(s), c = 1 / r, u = 1 / o;
    if (n || ([e, t] = this.toNormalizedPoint(e, t)), l) {
      const m = this.toNormalizedRange(l);
      e = M.mapLinear(e, m[0], m[2], 0, 1), t = M.mapLinear(t, m[1], m[3], 0, 1);
    }
    const h = Math.floor(e / c);
    let d = Math.floor(t / u);
    return i && (d = o - 1 - d), [h, d];
  }
  getTilesInRange(e, t, s, n, i, r = !1) {
    const o = [e, t, s, n], l = this.getContentBounds(r);
    let c = this.getLevel(i).tileBounds;
    if (!rs(o, l))
      return [0, 0, -1, -1];
    if (c && (r && (c = this.toNormalizedRange(c)), !rs(o, l)))
      return [0, 0, -1, -1];
    const [u, h, d, m] = this.clampToContentBounds(o, r), f = this.getTileAtPoint(u, h, i, r), p = this.getTileAtPoint(d, m, i, r);
    this.flipY && ([f[1], p[1]] = [p[1], f[1]]);
    const { tileCountX: g, tileCountY: y } = this.getLevel(i), [x, T] = f, [_, S] = p;
    return _ < 0 || S < 0 || x >= g || T >= y ? [0, 0, -1, -1] : [
      M.clamp(x, 0, g - 1),
      M.clamp(T, 0, y - 1),
      M.clamp(_, 0, g - 1),
      M.clamp(S, 0, y - 1)
    ];
  }
  getTileExists(e, t, s) {
    const [n, i, r, o] = this.contentBounds, [l, c, u, h] = this.getTileBounds(e, t, s);
    return !(l >= u || c >= h) && l <= r && c <= o && u >= n && h >= i;
  }
  getContentBounds(e = !1) {
    const { projection: t } = this, s = [...this.contentBounds];
    return t && e && (s[0] = t.convertLongitudeToProjection(s[0]), s[1] = t.convertLatitudeToProjection(s[1]), s[2] = t.convertLongitudeToProjection(s[2]), s[3] = t.convertLatitudeToProjection(s[3])), s;
  }
  // returns the UV range associated with the content in the given tile
  getTileContentUVBounds(e, t, s) {
    const [n, i, r, o] = this.getTileBounds(e, t, s, !0, !0), [l, c, u, h] = this.getTileBounds(e, t, s, !0, !1);
    return [
      M.mapLinear(n, l, u, 0, 1),
      M.mapLinear(i, c, h, 0, 1),
      M.mapLinear(r, l, u, 0, 1),
      M.mapLinear(o, c, h, 0, 1)
    ];
  }
  getTileBounds(e, t, s, n = !1, i = !0) {
    const { flipY: r, pixelOverlap: o, projection: l } = this, { tilePixelWidth: c, tilePixelHeight: u, pixelWidth: h, pixelHeight: d, tileBounds: m } = this.getLevel(s);
    let f = c * e - o, p = u * t - o, g = f + c + o * 2, y = p + u + o * 2;
    if (f = Math.max(f, 0), p = Math.max(p, 0), g = Math.min(g, h), y = Math.min(y, d), f = f / h, g = g / h, p = p / d, y = y / d, r) {
      const T = (y - p) / 2, S = 1 - (p + y) / 2;
      p = S - T, y = S + T;
    }
    let x = [f, p, g, y];
    if (m) {
      const T = this.toNormalizedRange(m);
      x[0] = M.mapLinear(x[0], 0, 1, T[0], T[2]), x[2] = M.mapLinear(x[2], 0, 1, T[0], T[2]), x[1] = M.mapLinear(x[1], 0, 1, T[1], T[3]), x[3] = M.mapLinear(x[3], 0, 1, T[1], T[3]);
    }
    return i && (x = this.clampToProjectionBounds(x, !0)), l && !n && (x[0] = l.convertProjectionToLongitude(x[0]), x[1] = l.convertProjectionToLatitude(x[1]), x[2] = l.convertProjectionToLongitude(x[2]), x[3] = l.convertProjectionToLatitude(x[3])), x;
  }
  toNormalizedPoint(e, t) {
    const { projection: s } = this, n = [e, t];
    return this.projection && (n[0] = s.convertLongitudeToProjection(n[0]), n[1] = s.convertLatitudeToProjection(n[1])), n;
  }
  toNormalizedRange(e) {
    return [
      ...this.toNormalizedPoint(e[0], e[1]),
      ...this.toNormalizedPoint(e[2], e[3])
    ];
  }
  toCartographicPoint(e, t) {
    const { projection: s } = this, n = [e, t];
    if (this.projection)
      n[0] = s.convertProjectionToLongitude(n[0]), n[1] = s.convertProjectionToLatitude(n[1]);
    else
      throw new Error("TilingScheme: Projection not available.");
    return n;
  }
  toCartographicRange(e) {
    return [
      ...this.toCartographicPoint(e[0], e[1]),
      ...this.toCartographicPoint(e[2], e[3])
    ];
  }
  clampToContentBounds(e, t = !1) {
    const s = [...e], [n, i, r, o] = this.getContentBounds(t);
    return s[0] = M.clamp(s[0], n, r), s[1] = M.clamp(s[1], i, o), s[2] = M.clamp(s[2], n, r), s[3] = M.clamp(s[3], i, o), s;
  }
  clampToProjectionBounds(e, t = !1) {
    const s = [...e], { projection: n } = this;
    let i;
    t || !n ? i = [0, 0, 1, 1] : i = n.getBounds();
    const [r, o, l, c] = i;
    return s[0] = M.clamp(s[0], r, l), s[1] = M.clamp(s[1], o, c), s[2] = M.clamp(s[2], r, l), s[3] = M.clamp(s[3], o, c), s;
  }
}
class Ae extends _i {
  constructor(e = {}) {
    super();
    const {
      fetchOptions: t = {}
    } = e;
    this.tiling = new mn(), this.fetchOptions = t, this.fetchData = (...s) => fetch(...s);
  }
  // async function for initializing the tiled image set
  init() {
  }
  // helper for processing the buffer into a texture
  async processBufferToTexture(e) {
    const t = new Blob([e]), s = await createImageBitmap(t, {
      premultiplyAlpha: "none",
      colorSpaceConversion: "none",
      imageOrientation: "flipY"
    }), n = new kn(s);
    return n.generateMipmaps = !1, n.colorSpace = Ks, n.needsUpdate = !0, n;
  }
  getMemoryUsage(e) {
    const { format: t, type: s, image: n, generateMipmaps: i } = e, { width: r, height: o } = n, l = Gn.getByteLength(r, o, t, s);
    return i ? l * 4 / 3 : l;
  }
  // fetch the item with the given key fields
  fetchItem(e, t) {
    const s = {
      ...this.fetchOptions,
      signal: t
    }, n = this.getUrl(...e);
    return this.fetchData(n, s).then((i) => i.arrayBuffer()).then((i) => this.processBufferToTexture(i));
  }
  // dispose of the item that was fetched
  disposeItem(e) {
    e.dispose(), e.image instanceof ImageBitmap && e.image.close();
  }
  getUrl(...e) {
  }
}
class Fe extends Ae {
  constructor(e = {}) {
    const {
      levels: t = 20,
      tileDimension: s = 256,
      url: n = null,
      ...i
    } = e;
    super(i), this.tileDimension = s, this.levels = t, this.url = n;
  }
  getUrl(e, t, s) {
    return this.url.replace(/{\s*z\s*}/gi, s).replace(/{\s*x\s*}/gi, e).replace(/{\s*(y|reverseY|-\s*y)\s*}/gi, t);
  }
  init() {
    const { tiling: e, tileDimension: t, levels: s, url: n } = this;
    return e.flipY = !/{\s*reverseY|-\s*y\s*}/g.test(n), e.setProjection(new de("EPSG:3857")), e.setContentBounds(...e.projection.getBounds()), e.generateLevels(s, e.projection.tileCountX, e.projection.tileCountY, {
      tilePixelWidth: t,
      tilePixelHeight: t
    }), this.url = n, Promise.resolve();
  }
}
class $t extends Ae {
  constructor(e = {}) {
    const {
      url: t = null,
      ...s
    } = e;
    super(s), this.tileSets = null, this.extension = null, this.url = t;
  }
  getUrl(e, t, s) {
    const { url: n, extension: i, tileSets: r, tiling: o } = this;
    return new URL(`${parseInt(r[s - o.minLevel].href)}/${e}/${t}.${i}`, n).toString();
  }
  init() {
    const { url: e } = this;
    return this.fetchData(new URL("tilemapresource.xml", e), this.fetchOptions).then((t) => t.text()).then((t) => {
      const { tiling: s } = this, n = new DOMParser().parseFromString(t, "text/xml"), i = n.querySelector("BoundingBox"), r = n.querySelector("TileFormat"), l = [...n.querySelector("TileSets").querySelectorAll("TileSet")].map((y) => ({
        href: parseInt(y.getAttribute("href")),
        unitsPerPixel: parseFloat(y.getAttribute("units-per-pixel")),
        order: parseInt(y.getAttribute("order"))
      })).sort((y, x) => y.order - x.order), c = parseFloat(i.getAttribute("minx")) * M.DEG2RAD, u = parseFloat(i.getAttribute("maxx")) * M.DEG2RAD, h = parseFloat(i.getAttribute("miny")) * M.DEG2RAD, d = parseFloat(i.getAttribute("maxy")) * M.DEG2RAD, m = parseInt(r.getAttribute("width")), f = parseInt(r.getAttribute("height")), p = r.getAttribute("extension"), g = n.querySelector("SRS").textContent;
      this.extension = p, this.url = e, this.tileSets = l, s.setProjection(new de(g)), s.setContentBounds(c, h, u, d), l.forEach(({ order: y }) => {
        s.setLevel(y, {
          tileCountX: s.projection.tileCountX * 2 ** y,
          tilePixelWidth: m,
          tilePixelHeight: f
        });
      });
    });
  }
}
function Mi(a) {
  return /(:84|:crs84)$/i.test(a);
}
class gn extends Ae {
  constructor(e = {}) {
    const {
      capabilities: t = null,
      layer: s = null,
      tileMatrixSet: n = null,
      style: i = null,
      url: r = null,
      dimensions: o = {},
      ...l
    } = e;
    super(l), this.capabilities = t, this.layer = s, this.tileMatrixSet = n, this.style = i, this.dimensions = o, this.url = r;
  }
  getUrl(e, t, s) {
    return this.url.replace(/{\s*TileMatrix\s*}/gi, s).replace(/{\s*TileCol\s*}/gi, e).replace(/{\s*TileRow\s*}/gi, t);
  }
  init() {
    const { tiling: e, dimensions: t, capabilities: s } = this;
    let { layer: n, tileMatrixSet: i, style: r, url: o } = this;
    n ? typeof n == "string" && (n = s.layers.find((u) => u.identifier === n)) : n = s.layers[0], i ? typeof i == "string" && (i = n.tileMatrixSets.find((u) => u.identifier === i)) : i = n.tileMatrixSets[0], r || (r = n.styles.find((u) => u.isDefault).identifier), o || (o = n.resourceUrls[0].template);
    const l = i.supportedCRS, c = l.includes("4326") || Mi(l) ? "EPSG:4326" : "EPSG:3857";
    e.flipY = !0, e.setProjection(new de(c)), n.boundingBox !== null ? e.setContentBounds(...n.boundingBox.bounds) : e.setContentBounds(...e.projection.getBounds()), i.tileMatrices.forEach((u, h) => {
      const { tileWidth: d, tileHeight: m, matrixWidth: f, matrixHeight: p } = u;
      e.setLevel(h, {
        tilePixelWidth: d,
        tilePixelHeight: m,
        tileCountX: f || e.projection.tileCountX * 2 ** h,
        tileCountY: p || e.projection.tileCountY * 2 ** h,
        tileBounds: u.bounds
      });
    }), o = o.replace(/{\s*TileMatrixSet\s*}/g, i.identifier).replace(/{\s*Style\s*}/g, r);
    for (const u in t)
      o = o.replace(new RegExp(`{\\s*${u}\\s*}`), t[u]);
    return n.dimensions.forEach((u) => {
      o = o.replace(new RegExp(`{\\s*${u.identifier}\\s*}`), u.defaultValue);
    }), this.url = o, Promise.resolve();
  }
}
class yn extends Ae {
  // TODO: layer and styles can be arrays, comma separated lists
  constructor(e = {}) {
    const {
      url: t = null,
      layer: s = null,
      styles: n = null,
      contentBoundingBox: i = null,
      version: r = "1.3.0",
      crs: o = "EPSG:4326",
      format: l = "image/png",
      transparent: c = !1,
      levels: u = 18,
      tileDimension: h = 256,
      ...d
    } = e;
    super(d), this.url = t, this.layer = s, this.crs = o, this.format = l, this.tileDimension = h, this.styles = n, this.version = r, this.levels = u, this.transparent = c, this.contentBoundingBox = i;
  }
  init() {
    const { tiling: e, levels: t, tileDimension: s, contentBoundingBox: n } = this;
    return e.setProjection(new de(this.crs)), e.flipY = !0, e.generateLevels(t, e.projection.tileCountX, e.projection.tileCountY, {
      tilePixelWidth: s,
      tilePixelHeight: s
    }), n !== null ? e.setContentBounds(...n) : e.setContentBounds(...e.projection.getBounds()), Promise.resolve();
  }
  // TODO: handle this in ProjectionScheme or TilingScheme? Or Loader?
  normalizedToMercatorX(e) {
    return M.mapLinear(e, 0, 1, -20037508342789244e-9, 20037508342789244e-9);
  }
  normalizedToMercatorY(e) {
    return M.mapLinear(e, 0, 1, -20037508342789244e-9, 20037508342789244e-9);
  }
  getUrl(e, t, s) {
    const {
      tiling: n,
      layer: i,
      crs: r,
      format: o,
      tileDimension: l,
      styles: c,
      version: u,
      transparent: h
    } = this, d = u === "1.1.1" ? "SRS" : "CRS";
    let m;
    if (r === "EPSG:3857") {
      const p = n.getTileBounds(e, t, s, !0, !1), g = this.normalizedToMercatorX(p[0]), y = this.normalizedToMercatorY(p[1]), x = this.normalizedToMercatorX(p[2]), T = this.normalizedToMercatorY(p[3]);
      m = [g, y, x, T];
    } else {
      const [p, g, y, x] = n.getTileBounds(e, t, s, !1, !1).map((T) => T * M.RAD2DEG);
      r === "EPSG:4326" ? u === "1.1.1" ? m = [p, g, y, x] : m = [g, p, x, y] : m = [p, g, y, x];
    }
    const f = new URLSearchParams({
      SERVICE: "WMS",
      REQUEST: "GetMap",
      VERSION: u,
      LAYERS: i,
      [d]: r,
      BBOX: m.join(","),
      WIDTH: l,
      HEIGHT: l,
      FORMAT: o,
      TRANSPARENT: h ? "TRUE" : "FALSE"
    });
    return c != null && f.set("STYLES", c), new URL("?" + f.toString(), this.url).toString();
  }
}
class no extends ct {
  constructor(e = {}) {
    const {
      levels: t,
      tileDimension: s,
      url: n,
      ...i
    } = e;
    super(i), this.name = "XYZ_TILES_PLUGIN", this.imageSource = new Fe({ url: n, levels: t, tileDimension: s });
  }
}
class Si extends ct {
  constructor(e = {}) {
    const { url: t, ...s } = e;
    super(s), this.name = "TMS_TILES_PLUGIN", this.imageSource = new $t({ url: t });
  }
}
class io extends ct {
  constructor(e = {}) {
    const {
      capabilities: t,
      layer: s,
      tileMatrixSet: n,
      style: i,
      dimensions: r,
      ...o
    } = e;
    super(o), this.name = "WTMS_TILES_PLUGIN", this.imageSource = new gn({
      capabilities: t,
      layer: s,
      tileMatrixSet: n,
      style: i,
      dimensions: r
    });
  }
}
class ro extends ct {
  constructor(e = {}) {
    const {
      url: t,
      layer: s,
      crs: n,
      format: i,
      tileDimension: r,
      styles: o,
      version: l,
      ...c
    } = e;
    super(c), this.name = "WMS_TILES_PLUGIN", this.imageSource = new yn({
      url: t,
      layer: s,
      crs: n,
      format: i,
      tileDimension: r,
      styles: o,
      version: l
    });
  }
}
const os = /* @__PURE__ */ new E(), ze = /* @__PURE__ */ new Xt(), F = /* @__PURE__ */ new E(), re = /* @__PURE__ */ new E();
class Ci extends Un {
  constructor(e = jn) {
    super(), this.manager = e, this.ellipsoid = new un(), this.skirtLength = 1e3, this.smoothSkirtNormals = !0, this.generateNormals = !0, this.solid = !1, this.minLat = -Math.PI / 2, this.maxLat = Math.PI / 2, this.minLon = -Math.PI, this.maxLon = Math.PI;
  }
  parse(e) {
    const {
      ellipsoid: t,
      solid: s,
      skirtLength: n,
      smoothSkirtNormals: i,
      generateNormals: r,
      minLat: o,
      maxLat: l,
      minLon: c,
      maxLon: u
    } = this, {
      header: h,
      indices: d,
      vertexData: m,
      edgeIndices: f,
      extensions: p
    } = super.parse(e), g = new et(), y = new en(), x = new Oe(g, y);
    x.position.set(...h.center);
    const T = "octvertexnormals" in p, _ = T || r, S = m.u.length, b = [], C = [], A = [], w = [];
    let P = 0, U = 0;
    for (let L = 0; L < S; L++)
      W(L, F), $(F.x, F.y, F.z, re), C.push(F.x, F.y), b.push(...re);
    for (let L = 0, v = d.length; L < v; L++)
      A.push(d[L]);
    if (_)
      if (T) {
        const L = p.octvertexnormals.normals;
        for (let v = 0, D = L.length; v < D; v++)
          w.push(L[v]);
      } else {
        const L = new et(), v = d.length > 21845 ? new Uint32Array(d) : new Uint16Array(d);
        L.setIndex(new J(v, 1, !1)), L.setAttribute("position", new J(new Float32Array(b), 3, !1)), L.computeVertexNormals();
        const V = L.getAttribute("normal").array;
        p.octvertexnormals = { normals: V };
        for (let I = 0, N = V.length; I < N; I++)
          w.push(V[I]);
      }
    if (g.addGroup(P, d.length, U), P += d.length, U++, s) {
      const L = b.length / 3;
      for (let v = 0; v < S; v++)
        W(v, F), $(F.x, F.y, F.z, re, -n), C.push(F.x, F.y), b.push(...re);
      for (let v = d.length - 1; v >= 0; v--)
        A.push(d[v] + L);
      if (_) {
        const v = p.octvertexnormals.normals;
        for (let D = 0, V = v.length; D < V; D++)
          w.push(-v[D]);
      }
      g.addGroup(P, d.length, U), P += d.length, U++;
    }
    if (n > 0) {
      const {
        westIndices: L,
        eastIndices: v,
        southIndices: D,
        northIndices: V
      } = f;
      let I;
      const N = z(L);
      I = b.length / 3, C.push(...N.uv), b.push(...N.positions);
      for (let O = 0, Z = N.indices.length; O < Z; O++)
        A.push(N.indices[O] + I);
      const Q = z(v);
      I = b.length / 3, C.push(...Q.uv), b.push(...Q.positions);
      for (let O = 0, Z = Q.indices.length; O < Z; O++)
        A.push(Q.indices[O] + I);
      const k = z(D);
      I = b.length / 3, C.push(...k.uv), b.push(...k.positions);
      for (let O = 0, Z = k.indices.length; O < Z; O++)
        A.push(k.indices[O] + I);
      const G = z(V);
      I = b.length / 3, C.push(...G.uv), b.push(...G.positions);
      for (let O = 0, Z = G.indices.length; O < Z; O++)
        A.push(G.indices[O] + I);
      _ && (w.push(...N.normals), w.push(...Q.normals), w.push(...k.normals), w.push(...G.normals)), g.addGroup(P, d.length, U), P += d.length, U++;
    }
    for (let L = 0, v = b.length; L < v; L += 3)
      b[L + 0] -= h.center[0], b[L + 1] -= h.center[1], b[L + 2] -= h.center[2];
    const B = b.length / 3 > 65535 ? new Uint32Array(A) : new Uint16Array(A);
    if (g.setIndex(new J(B, 1, !1)), g.setAttribute("position", new J(new Float32Array(b), 3, !1)), g.setAttribute("uv", new J(new Float32Array(C), 2, !1)), _ && g.setAttribute("normal", new J(new Float32Array(w), 3, !1)), "watermask" in p) {
      const { mask: L, size: v } = p.watermask, D = new Uint8Array(2 * v * v);
      for (let I = 0, N = L.length; I < N; I++) {
        const Q = L[I] === 255 ? 0 : 255;
        D[2 * I + 0] = Q, D[2 * I + 1] = Q;
      }
      const V = new Wt(D, v, v, tn, sn);
      V.flipY = !0, V.minFilter = zn, V.magFilter = nn, V.needsUpdate = !0, y.roughnessMap = V;
    }
    return x.userData.minHeight = h.minHeight, x.userData.maxHeight = h.maxHeight, "metadata" in p && (x.userData.metadata = p.metadata.json), x;
    function W(L, v) {
      return v.x = m.u[L], v.y = m.v[L], v.z = m.height[L], v;
    }
    function $(L, v, D, V, I = 0) {
      const N = M.lerp(h.minHeight, h.maxHeight, D), Q = M.lerp(c, u, L), k = M.lerp(o, l, v);
      return t.getCartographicToPosition(k, Q, N + I, V), V;
    }
    function z(L) {
      const v = [], D = [], V = [], I = [], N = [];
      for (let G = 0, O = L.length; G < O; G++)
        W(L[G], F), v.push(F.x, F.y), V.push(F.x, F.y), $(F.x, F.y, F.z, re), D.push(...re), $(F.x, F.y, F.z, re, -n), I.push(...re);
      const Q = L.length - 1;
      for (let G = 0; G < Q; G++) {
        const O = G, Z = G + 1, pe = G + L.length, ht = G + L.length + 1;
        N.push(O, pe, Z), N.push(Z, pe, ht);
      }
      let k = null;
      if (_) {
        const G = (D.length + I.length) / 3;
        if (i) {
          k = new Array(G * 3);
          const O = p.octvertexnormals.normals, Z = k.length / 2;
          for (let pe = 0, ht = G / 2; pe < ht; pe++) {
            const dt = L[pe], _e = 3 * pe, Kt = O[3 * dt + 0], es = O[3 * dt + 1], ts = O[3 * dt + 2];
            k[_e + 0] = Kt, k[_e + 1] = es, k[_e + 2] = ts, k[Z + _e + 0] = Kt, k[Z + _e + 1] = es, k[Z + _e + 2] = ts;
          }
        } else {
          k = [], ze.a.fromArray(D, 0), ze.b.fromArray(I, 0), ze.c.fromArray(D, 3), ze.getNormal(os);
          for (let O = 0; O < G; O++)
            k.push(...os);
        }
      }
      return {
        uv: [...v, ...V],
        positions: [...D, ...I],
        indices: N,
        normals: k
      };
    }
  }
}
const j = 0, le = ["a", "b", "c"], R = /* @__PURE__ */ new Ve(), as = /* @__PURE__ */ new Ve(), ls = /* @__PURE__ */ new Ve(), cs = /* @__PURE__ */ new Ve();
class xn {
  constructor() {
    this.attributeList = null, this.splitOperations = [], this.trianglePool = new Ai();
  }
  forEachSplitPermutation(e) {
    const { splitOperations: t } = this, s = (n = 0) => {
      if (n >= t.length) {
        e();
        return;
      }
      t[n].keepPositive = !0, s(n + 1), t[n].keepPositive = !1, s(n + 1);
    };
    s();
  }
  // Takes an operation that returns a value for the given vertex passed to the callback. Triangles
  // are clipped along edges where the interpolated value is equal to 0. The polygons on the positive
  // side of the operation are kept if "keepPositive" is true.
  // callback( geometry, i0, i1, i2, barycoord );
  addSplitOperation(e, t = !0) {
    this.splitOperations.push({
      callback: e,
      keepPositive: t
    });
  }
  // Removes all split operations
  clearSplitOperations() {
    this.splitOperations.length = 0;
  }
  // clips an object hierarchy
  clipObject(e) {
    const t = e.clone(), s = [];
    return t.traverse((n) => {
      n.isMesh && (n.geometry = this.clip(n).geometry, (n.geometry.index ? n.geometry.index.count / 3 : n.attributes.position.count / 3) === 0 && s.push(n));
    }), s.forEach((n) => {
      n.removeFromParent();
    }), t;
  }
  // Returns a new mesh that has been clipped by the split operations. Range indicates the range of
  // elements to include when clipping.
  clip(e, t = null) {
    const s = this.getClippedData(e, t);
    return this.constructMesh(s.attributes, s.index, e);
  }
  // Appends the clip operation data to the given "target" object so multiple ranges can be appended.
  // The "target" object is returned with an "index" field, "vertexIsClipped" field, and series of arrays
  // in "attributes".
  // attributes - set of attribute arrays
  // index - triangle indices referencing vertices in attributes
  // vertexIsClipped - array indicating whether a vertex is on a clipped edge
  getClippedData(e, t = null, s = {}) {
    const { trianglePool: n, splitOperations: i, attributeList: r } = this, o = e.geometry, l = o.attributes.position, c = o.index;
    let u = 0;
    const h = {};
    s.index = s.index || [], s.vertexIsClipped = s.vertexIsClipped || [], s.attributes = s.attributes || {};
    for (const p in o.attributes) {
      if (r !== null) {
        if (r instanceof Function && !r(p))
          continue;
        if (Array.isArray(r) && !r.includes(p))
          continue;
      }
      s.attributes[p] = [];
    }
    let d = 0, m = c ? c.count : l.count;
    t !== null && (d = t.start, m = t.count);
    for (let p = d, g = d + m; p < g; p += 3) {
      let y = p + 0, x = p + 1, T = p + 2;
      c && (y = c.getX(y), x = c.getX(x), T = c.getX(T));
      const _ = n.get();
      _.initFromIndices(y, x, T);
      let S = [_];
      for (let b = 0; b < i.length; b++) {
        const { keepPositive: C, callback: A } = i[b], w = [];
        for (let P = 0; P < S.length; P++) {
          const U = S[P], { indices: B, barycoord: W } = U;
          U.clipValues.a = A(o, B.a, B.b, B.c, W.a, e.matrixWorld), U.clipValues.b = A(o, B.a, B.b, B.c, W.b, e.matrixWorld), U.clipValues.c = A(o, B.a, B.b, B.c, W.c, e.matrixWorld), this.splitTriangle(U, !C, w);
        }
        S = w;
      }
      for (let b = 0, C = S.length; b < C; b++) {
        const A = S[b];
        f(A, o);
      }
      n.reset();
    }
    return s;
    function f(p, g) {
      for (let y = 0; y < 3; y++) {
        const x = p.getVertexHash(y, g);
        x in h || (h[x] = u, u++, p.getVertexData(y, g, s.attributes), s.vertexIsClipped.push(p.clipValues[le[y]] === j));
        const T = h[x];
        s.index.push(T);
      }
    }
  }
  // Takes the set of resultant data and constructs a mesh
  constructMesh(e, t, s) {
    const n = s.geometry, i = new et(), r = e.position.length / 3 > 65535 ? new Uint32Array(t) : new Uint16Array(t);
    i.setIndex(new J(r, 1, !1));
    for (const l in e) {
      const c = n.getAttribute(l), u = new c.array.constructor(e[l]), h = new J(u, c.itemSize, c.normalized);
      h.gpuType = c.gpuType, i.setAttribute(l, h);
    }
    const o = new Oe(i, s.material.clone());
    return o.position.copy(s.position), o.quaternion.copy(s.quaternion), o.scale.copy(s.scale), o;
  }
  // Splits the given triangle
  splitTriangle(e, t, s) {
    const { trianglePool: n } = this, i = [], r = [], o = [];
    for (let l = 0; l < 3; l++) {
      const c = le[l], u = le[(l + 1) % 3], h = e.clipValues[c], d = e.clipValues[u];
      (h < j != d < j || h === j) && (i.push(l), r.push([c, u]), h === d ? o.push(0) : o.push(M.mapLinear(j, h, d, 0, 1)));
    }
    if (i.length !== 2)
      Math.min(
        e.clipValues.a,
        e.clipValues.b,
        e.clipValues.c
      ) < j === t && s.push(e);
    else if (i.length === 2) {
      const l = n.get().initFromTriangle(e), c = n.get().initFromTriangle(e), u = n.get().initFromTriangle(e);
      (i[0] + 1) % 3 === i[1] ? (l.lerpVertexFromEdge(e, r[0][0], r[0][1], o[0], "a"), l.copyVertex(e, r[0][1], "b"), l.lerpVertexFromEdge(e, r[1][0], r[1][1], o[1], "c"), l.clipValues.a = j, l.clipValues.c = j, c.lerpVertexFromEdge(e, r[0][0], r[0][1], o[0], "a"), c.copyVertex(e, r[1][1], "b"), c.copyVertex(e, r[0][0], "c"), c.clipValues.a = j, u.lerpVertexFromEdge(e, r[0][0], r[0][1], o[0], "a"), u.lerpVertexFromEdge(e, r[1][0], r[1][1], o[1], "b"), u.copyVertex(e, r[1][1], "c"), u.clipValues.a = j, u.clipValues.b = j) : (l.lerpVertexFromEdge(e, r[0][0], r[0][1], o[0], "a"), l.lerpVertexFromEdge(e, r[1][0], r[1][1], o[1], "b"), l.copyVertex(e, r[0][0], "c"), l.clipValues.a = j, l.clipValues.b = j, c.lerpVertexFromEdge(e, r[0][0], r[0][1], o[0], "a"), c.copyVertex(e, r[0][1], "b"), c.lerpVertexFromEdge(e, r[1][0], r[1][1], o[1], "c"), c.clipValues.a = j, c.clipValues.c = j, u.copyVertex(e, r[0][1], "a"), u.copyVertex(e, r[1][0], "b"), u.lerpVertexFromEdge(e, r[1][0], r[1][1], o[1], "c"), u.clipValues.c = j);
      let d, m;
      d = Math.min(l.clipValues.a, l.clipValues.b, l.clipValues.c), m = d < j, m === t && s.push(l), d = Math.min(c.clipValues.a, c.clipValues.b, c.clipValues.c), m = d < j, m === t && s.push(c), d = Math.min(u.clipValues.a, u.clipValues.b, u.clipValues.c), m = d < j, m === t && s.push(u);
    }
  }
}
class Ai {
  constructor() {
    this.pool = [], this.index = 0;
  }
  get() {
    if (this.index >= this.pool.length) {
      const t = new vi();
      this.pool.push(t);
    }
    const e = this.pool[this.index];
    return this.index++, e;
  }
  reset() {
    this.index = 0;
  }
}
class vi {
  constructor() {
    this.indices = {
      a: -1,
      b: -1,
      c: -1
    }, this.clipValues = {
      a: -1,
      b: -1,
      c: -1
    }, this.barycoord = new Xt();
  }
  // returns a hash for the given [0, 2] index based on attributes of the referenced geometry
  getVertexHash(e, t) {
    const { barycoord: s, indices: n } = this, i = le[e], r = s[i];
    if (r.x === 1)
      return n[le[0]];
    if (r.y === 1)
      return n[le[1]];
    if (r.z === 1)
      return n[le[2]];
    {
      const { attributes: o } = t;
      let l = "";
      for (const c in o) {
        const u = o[c];
        switch (us(u, n.a, n.b, n.c, r, R), (c === "normal" || c === "tangent" || c === "bitangent") && R.normalize(), u.itemSize) {
          case 4:
            l += Pe(R.x, R.y, R.z, R.w);
            break;
          case 3:
            l += Pe(R.x, R.y, R.z);
            break;
          case 2:
            l += Pe(R.x, R.y);
            break;
          case 1:
            l += Pe(R.x);
            break;
        }
        l += "|";
      }
      return l;
    }
  }
  // Accumulate the vertex data in the given attribute arrays
  getVertexData(e, t, s) {
    const { barycoord: n, indices: i } = this, r = le[e], o = n[r], { attributes: l } = t;
    for (const c in l) {
      if (!s[c])
        continue;
      const u = l[c], h = s[c];
      switch (us(u, i.a, i.b, i.c, o, R), (c === "normal" || c === "tangent" || c === "bitangent") && R.normalize(), u.itemSize) {
        case 4:
          h.push(R.x, R.y, R.z, R.w);
          break;
        case 3:
          h.push(R.x, R.y, R.z);
          break;
        case 2:
          h.push(R.x, R.y);
          break;
        case 1:
          h.push(R.x);
          break;
      }
    }
  }
  // Copy the indices from a target triangle
  initFromTriangle(e) {
    return this.initFromIndices(
      e.indices.a,
      e.indices.b,
      e.indices.c
    );
  }
  // Set the indices for the given
  initFromIndices(e, t, s) {
    return this.indices.a = e, this.indices.b = t, this.indices.c = s, this.clipValues.a = -1, this.clipValues.b = -1, this.clipValues.c = -1, this.barycoord.a.set(1, 0, 0), this.barycoord.b.set(0, 1, 0), this.barycoord.c.set(0, 0, 1), this;
  }
  // Lerp the given vertex along to the provided edge of the provided triangle
  lerpVertexFromEdge(e, t, s, n, i) {
    this.clipValues[i] = M.lerp(e.clipValues[t], e.clipValues[s], n), this.barycoord[i].lerpVectors(e.barycoord[t], e.barycoord[s], n);
  }
  // Copy a vertex from the provided triangle
  copyVertex(e, t, s) {
    this.clipValues[s] = e.clipValues[t], this.barycoord[s].copy(e.barycoord[t]);
  }
}
function us(a, e, t, s, n, i) {
  switch (as.fromBufferAttribute(a, e), ls.fromBufferAttribute(a, t), cs.fromBufferAttribute(a, s), i.set(0, 0, 0, 0).addScaledVector(as, n.x).addScaledVector(ls, n.y).addScaledVector(cs, n.z), a.itemSize) {
    case 3:
      R.w = 0;
      break;
    case 2:
      R.w = 0, R.z = 0;
      break;
    case 1:
      R.w = 0, R.z = 0, R.y = 0;
      break;
  }
  return i;
}
function Pe(...a) {
  let s = "";
  for (let n = 0, i = a.length; n < i; n++)
    s += ~~(a[n] * 1e5 + 0.5), n !== i - 1 && (s += "_");
  return s;
}
const hs = {}, Li = /* @__PURE__ */ new E(), gt = /* @__PURE__ */ new E(), yt = /* @__PURE__ */ new E(), Ii = /* @__PURE__ */ new E(), Ei = /* @__PURE__ */ new E(), Y = /* @__PURE__ */ new E(), Me = /* @__PURE__ */ new E(), X = /* @__PURE__ */ new q(), ae = /* @__PURE__ */ new q(), ds = /* @__PURE__ */ new q();
class wi extends xn {
  constructor() {
    super(), this.ellipsoid = new un(), this.skirtLength = 1e3, this.smoothSkirtNormals = !0, this.solid = !1, this.minLat = -Math.PI / 2, this.maxLat = Math.PI / 2, this.minLon = -Math.PI, this.maxLon = Math.PI, this.attributeList = ["position", "normal", "uv"];
  }
  clipToQuadrant(e, t, s) {
    const { solid: n, skirtLength: i, ellipsoid: r, smoothSkirtNormals: o } = this;
    this.clearSplitOperations(), this.addSplitOperation(ps("x"), !t), this.addSplitOperation(ps("y"), !s);
    let l, c;
    const u = e.geometry.groups[0], h = this.getClippedData(e, u);
    if (this.adjustVertices(h, e.position, 0), n) {
      l = {
        index: h.index.slice().reverse(),
        attributes: {}
      };
      for (const S in h.attributes)
        l.attributes[S] = h.attributes[S].slice();
      const _ = l.attributes.normal;
      if (_)
        for (let S = 0; S < _.length; S += 3)
          _[S + 0] *= -1, _[S + 1] *= -1, _[S + 2] *= -1;
      this.adjustVertices(l, e.position, -i);
    }
    if (i > 0) {
      c = {
        index: [],
        attributes: {
          position: [],
          normal: [],
          uv: []
        }
      };
      let _ = 0;
      const S = {}, b = (B, W, $) => {
        const z = Pe(...B, ...$, ...W);
        z in S || (S[z] = _, _++, c.attributes.position.push(...B), c.attributes.normal.push(...$), c.attributes.uv.push(...W)), c.index.push(S[z]);
      }, C = h.index, A = h.attributes.uv, w = h.attributes.position, P = h.attributes.normal, U = h.index.length / 3;
      for (let B = 0; B < U; B++) {
        const W = 3 * B;
        for (let $ = 0; $ < 3; $++) {
          const z = ($ + 1) % 3, L = C[W + $], v = C[W + z];
          if (X.fromArray(A, L * 2), ae.fromArray(A, v * 2), X.x === ae.x && (X.x === 0 || X.x === 0.5 || X.x === 1) || X.y === ae.y && (X.y === 0 || X.y === 0.5 || X.y === 1)) {
            gt.fromArray(w, L * 3), yt.fromArray(w, v * 3);
            const D = gt, V = yt, I = Ii.copy(gt), N = Ei.copy(yt);
            Y.copy(I).add(e.position), r.getPositionToNormal(Y, Y), I.addScaledVector(Y, -i), Y.copy(N).add(e.position), r.getPositionToNormal(Y, Y), N.addScaledVector(Y, -i), o && P ? (Y.fromArray(P, L * 3), Me.fromArray(P, v * 3)) : (Y.subVectors(D, V), Me.subVectors(D, I).cross(Y).normalize(), Y.copy(Me)), b(V, ae, Me), b(D, X, Y), b(I, X, Y), b(V, ae, Me), b(I, X, Y), b(N, ae, Me);
          }
        }
      }
    }
    const d = h.index.length, m = h;
    if (l) {
      const { index: _, attributes: S } = l, b = m.attributes.position.length / 3;
      for (let C = 0, A = _.length; C < A; C++)
        m.index.push(_[C] + b);
      for (const C in h.attributes)
        m.attributes[C].push(...S[C]);
    }
    if (c) {
      const { index: _, attributes: S } = c, b = m.attributes.position.length / 3;
      for (let C = 0, A = _.length; C < A; C++)
        m.index.push(_[C] + b);
      for (const C in h.attributes)
        m.attributes[C].push(...S[C]);
    }
    const f = t ? 0 : -0.5, p = s ? 0 : -0.5, g = m.attributes.uv;
    for (let _ = 0, S = g.length; _ < S; _ += 2)
      g[_] = (g[_] + f) * 2, g[_ + 1] = (g[_ + 1] + p) * 2;
    const y = this.constructMesh(m.attributes, m.index, e);
    y.userData.minHeight = e.userData.minHeight, y.userData.maxHeight = e.userData.maxHeight;
    let x = 0, T = 0;
    return y.geometry.addGroup(T, d, x), T += d, x++, l && (y.geometry.addGroup(T, l.index.length, x), T += l.index.length, x++), c && (y.geometry.addGroup(T, c.index.length, x), T += c.index.length, x++), y;
  }
  adjustVertices(e, t, s) {
    const { ellipsoid: n, minLat: i, maxLat: r, minLon: o, maxLon: l } = this, { attributes: c, vertexIsClipped: u } = e, h = c.position, d = c.uv, m = h.length / 3;
    for (let f = 0; f < m; f++) {
      const p = X.fromArray(d, f * 2);
      u && u[f] && (Math.abs(p.x - 0.5) < 1e-10 && (p.x = 0.5), Math.abs(p.y - 0.5) < 1e-10 && (p.y = 0.5), X.toArray(d, f * 2));
      const g = M.lerp(i, r, p.y), y = M.lerp(o, l, p.x), x = Li.fromArray(h, f * 3).add(t);
      n.getPositionToCartographic(x, hs), n.getCartographicToPosition(g, y, hs.height + s, x), x.sub(t), x.toArray(h, f * 3);
    }
  }
}
function ps(a) {
  return (e, t, s, n, i) => {
    const r = e.attributes.uv;
    return X.fromBufferAttribute(r, t), ae.fromBufferAttribute(r, s), ds.fromBufferAttribute(r, n), X[a] * i.x + ae[a] * i.y + ds[a] * i.z - 0.5;
  };
}
const fs = Symbol("TILE_X"), ms = Symbol("TILE_Y"), Re = Symbol("TILE_LEVEL"), me = Symbol("TILE_AVAILABLE"), He = 1e4, gs = /* @__PURE__ */ new E();
function Pi(a, e, t, s) {
  if (a && e < a.length) {
    const n = a[e];
    for (let i = 0, r = n.length; i < r; i++) {
      const { startX: o, startY: l, endX: c, endY: u } = n[i];
      if (t >= o && t <= c && s >= l && s <= u)
        return !0;
    }
  }
  return !1;
}
function Tn(a) {
  const { available: e = null, maxzoom: t = null } = a;
  return t === null ? e.length - 1 : t;
}
function Ri(a) {
  const { metadataAvailability: e = -1 } = a;
  return e;
}
function xt(a, e) {
  const t = a[Re], s = Ri(e), n = Tn(e);
  return t < n && s !== -1 && t % s === 0;
}
function Bi(a, e, t, s, n) {
  return n.tiles[0].replace(/{\s*z\s*}/g, t).replace(/{\s*x\s*}/g, a).replace(/{\s*y\s*}/g, e).replace(/{\s*version\s*}/g, s);
}
class Di {
  constructor(e = {}) {
    const {
      useRecommendedSettings: t = !0,
      skirtLength: s = null,
      smoothSkirtNormals: n = !0,
      generateNormals: i = !0,
      solid: r = !1
    } = e;
    this.name = "QUANTIZED_MESH_PLUGIN", this.priority = -1e3, this.tiles = null, this.layer = null, this.useRecommendedSettings = t, this.skirtLength = s, this.smoothSkirtNormals = n, this.solid = r, this.generateNormals = i, this.attribution = null, this.tiling = new mn(), this.projection = new de();
  }
  // Plugin function
  init(e) {
    e.fetchOptions.headers = e.fetchOptions.headers || {}, e.fetchOptions.headers.Accept = "application/vnd.quantized-mesh,application/octet-stream;q=0.9", this.useRecommendedSettings && (e.errorTarget = 2), this.tiles = e;
  }
  loadRootTileset() {
    const { tiles: e } = this;
    let t = new URL("layer.json", new URL(e.rootURL, location.href));
    return e.invokeAllPlugins((s) => t = s.preprocessURL ? s.preprocessURL(t, null) : t), e.invokeOnePlugin((s) => s.fetchData && s.fetchData(t, this.tiles.fetchOptions)).then((s) => s.json()).then((s) => {
      this.layer = s;
      const {
        projection: n = "EPSG:4326",
        extensions: i = [],
        attribution: r = "",
        available: o = null
      } = s, {
        tiling: l,
        tiles: c,
        projection: u
      } = this;
      r && (this.attribution = {
        value: r,
        type: "string",
        collapsible: !0
      }), i.length > 0 && (c.fetchOptions.headers.Accept += `;extensions=${i.join("-")}`), u.setScheme(n);
      const { tileCountX: h, tileCountY: d } = u;
      l.setProjection(u), l.generateLevels(Tn(s) + 1, h, d);
      const m = [];
      for (let g = 0; g < h; g++) {
        const y = this.createChild(0, g, 0, o);
        y && m.push(y);
      }
      const f = {
        asset: {
          version: "1.1"
        },
        geometricError: 1 / 0,
        root: {
          refine: "REPLACE",
          geometricError: 1 / 0,
          boundingVolume: {
            region: [...this.tiling.getContentBounds(), -He, He]
          },
          children: m,
          [me]: o,
          [Re]: -1
        }
      };
      let p = c.rootURL;
      return c.invokeAllPlugins((g) => p = g.preprocessURL ? g.preprocessURL(p, null) : p), c.preprocessTileset(f, p), f;
    });
  }
  parseToMesh(e, t, s, n) {
    const {
      skirtLength: i,
      solid: r,
      smoothSkirtNormals: o,
      generateNormals: l,
      tiles: c
    } = this, u = c.ellipsoid;
    let h;
    if (s === "quantized_tile_split") {
      const p = new URL(n).searchParams, g = p.get("left") === "true", y = p.get("bottom") === "true", x = new wi();
      x.ellipsoid.copy(u), x.solid = r, x.smoothSkirtNormals = o, x.skirtLength = i === null ? t.geometricError : i;
      const [T, _, S, b] = t.parent.boundingVolume.region;
      x.minLat = _, x.maxLat = b, x.minLon = T, x.maxLon = S, h = x.clipToQuadrant(t.parent.cached.scene, g, y);
    } else if (s === "terrain") {
      const p = new Ci(c.manager);
      p.ellipsoid.copy(u), p.solid = r, p.smoothSkirtNormals = o, p.generateNormals = l, p.skirtLength = i === null ? t.geometricError : i;
      const [g, y, x, T] = t.boundingVolume.region;
      p.minLat = y, p.maxLat = T, p.minLon = g, p.maxLon = x, h = p.parse(e);
    } else
      return;
    const { minHeight: d, maxHeight: m, metadata: f } = h.userData;
    return t.boundingVolume.region[4] = d, t.boundingVolume.region[5] = m, t.cached.boundingVolume.setRegionData(u, ...t.boundingVolume.region), f && ("geometricerror" in f && (t.geometricError = f.geometricerror), xt(t, this.layer) && "available" in f && t.children.length === 0 && (t[me] = [
      ...new Array(t[Re] + 1).fill(null),
      ...f.available
    ])), this.expandChildren(t), h;
  }
  getAttributions(e) {
    this.attribution && e.push(this.attribution);
  }
  // Local functions
  createChild(e, t, s, n) {
    const { tiles: i, layer: r, tiling: o, projection: l } = this, c = i.ellipsoid, u = n === null && e === 0 || Pi(n, e, t, s), h = Bi(t, s, e, 1, r), d = [...o.getTileBounds(t, s, e), -He, He], [
      /* west */
      ,
      m,
      /* east */
      ,
      f,
      /* minHeight */
      ,
      p
    ] = d, g = m > 0 != f > 0 ? 0 : Math.min(Math.abs(m), Math.abs(f));
    c.getCartographicToPosition(g, 0, p, gs), gs.z = 0;
    const y = l.tileCountX, _ = Math.max(...c.radius) * 2 * Math.PI * 0.25 / (65 * y) / 2 ** e, S = {
      [me]: null,
      [Re]: e,
      [fs]: t,
      [ms]: s,
      refine: "REPLACE",
      geometricError: _,
      boundingVolume: { region: d },
      content: u ? { uri: h } : null,
      children: []
    };
    return xt(S, r) || (S[me] = n), S;
  }
  expandChildren(e) {
    const t = e[Re], s = e[fs], n = e[ms], i = e[me];
    if (t >= this.tiling.maxLevel)
      return;
    let r = !1;
    for (let o = 0; o < 2; o++)
      for (let l = 0; l < 2; l++) {
        const c = this.createChild(t + 1, 2 * s + o, 2 * n + l, i);
        c.content !== null ? (e.children.push(c), r = !0) : (e.children.push(c), c.content = { uri: `tile.quantized_tile_split?bottom=${l === 0}&left=${o === 0}` });
      }
    r || (e.children.length = 0);
  }
  fetchData(e, t) {
    if (/quantized_tile_split/.test(e))
      return new ArrayBuffer();
  }
  disposeTile(e) {
    xt(e, this.layer) && (e[me] = null), me in e && (e.children.forEach((t) => {
      this.tiles.processNodeQueue.remove(t);
    }), e.children.length = 0, e.__childrenProcessed = 0);
  }
}
let oo = class extends Vn {
  constructor(e = {}) {
    super({
      assetTypeHandler: (t, s, n) => {
        t === "TERRAIN" && s.getPluginByName("QUANTIZED_MESH_PLUGIN") === null ? (console.warn(
          'CesiumIonAuthPlugin: CesiumIonAuthPlugin plugin auto-registration has been deprecated. Please implement a custom "assetTypeHandler" for "TERRAIN" using "QuantizedMeshPlugin", instead.'
        ), s.registerPlugin(new Di({
          useRecommendedSettings: this.useRecommendedSettings
        }))) : t === "IMAGERY" && s.getPluginByName("TMS_TILES_PLUGIN") === null ? (console.warn(
          'CesiumIonAuthPlugin: CesiumIonAuthPlugin plugin auto-registration has been deprecated. Please implement a custom "assetTypeHandler" for "IMAGERY" using "TMSTilesPlugin", instead.'
        ), s.registerPlugin(new Si({
          useRecommendedSettings: this.useRecommendedSettings,
          shape: "ellipsoid"
        }))) : console.warn(`CesiumIonAuthPlugin: Cesium Ion asset type "${t}" unhandled.`);
      },
      ...e
    }), e.__suppress_warning__ && console.warn(
      'CesiumIonAuthPlugin: Plugin has been moved to "3d-tiles-renderer/core/plugins".'
    );
  }
};
const Tt = /* @__PURE__ */ new K();
class lo {
  constructor() {
    this.name = "UPDATE_ON_CHANGE_PLUGIN", this.tiles = null, this.needsUpdate = !1, this.cameraMatrices = /* @__PURE__ */ new Map();
  }
  init(e) {
    this.tiles = e, this._needsUpdateCallback = () => {
      this.needsUpdate = !0;
    }, this._onCameraAdd = ({ camera: t }) => {
      this.needsUpdate = !0, this.cameraMatrices.set(t, new K());
    }, this._onCameraDelete = ({ camera: t }) => {
      this.needsUpdate = !0, this.cameraMatrices.delete(t);
    }, e.addEventListener("needs-update", this._needsUpdateCallback), e.addEventListener("add-camera", this._onCameraAdd), e.addEventListener("delete-camera", this._onCameraDelete), e.addEventListener("camera-resolution-change", this._needsUpdateCallback), e.cameras.forEach((t) => {
      this._onCameraAdd({ camera: t });
    });
  }
  doTilesNeedUpdate() {
    const e = this.tiles;
    let t = !1;
    this.cameraMatrices.forEach((n, i) => {
      Tt.copy(e.group.matrixWorld).premultiply(i.matrixWorldInverse).premultiply(i.projectionMatrixInverse), t = t || !Tt.equals(n), n.copy(Tt);
    });
    const s = this.needsUpdate;
    return this.needsUpdate = !1, s || t;
  }
  preprocessNode() {
    this.needsUpdate = !0;
  }
  dispose() {
    const e = this.tiles;
    e.removeEventListener("camera-resolution-change", this._needsUpdateCallback), e.removeEventListener("needs-update", this._needsUpdateCallback), e.removeEventListener("add-camera", this._onCameraAdd), e.removeEventListener("delete-camera", this._onCameraDelete);
  }
}
const ys = /* @__PURE__ */ new E();
function Le(a, e) {
  if (a.isInterleavedBufferAttribute || a.array instanceof e)
    return a;
  const s = e === Int8Array || e === Int16Array || e === Int32Array ? -1 : 0, n = new e(a.count * a.itemSize), i = new J(n, a.itemSize, !0), r = a.itemSize, o = a.count;
  for (let l = 0; l < o; l++)
    for (let c = 0; c < r; c++) {
      const u = M.clamp(a.getComponent(l, c), s, 1);
      i.setComponent(l, c, u);
    }
  return i;
}
function Oi(a, e = Int16Array) {
  const t = a.geometry, s = t.attributes, n = s.position;
  if (n.isInterleavedBufferAttribute || n.array instanceof e)
    return n;
  const i = new e(n.count * n.itemSize), r = new J(i, n.itemSize, !1), o = n.itemSize, l = n.count;
  t.computeBoundingBox();
  const c = t.boundingBox, { min: u, max: h } = c, d = 2 ** (8 * e.BYTES_PER_ELEMENT - 1) - 1, m = -d;
  for (let f = 0; f < l; f++)
    for (let p = 0; p < o; p++) {
      const g = p === 0 ? "x" : p === 1 ? "y" : "z", y = u[g], x = h[g], T = M.mapLinear(
        n.getComponent(f, p),
        y,
        x,
        m,
        d
      );
      r.setComponent(f, p, T);
    }
  c.getCenter(ys).multiply(a.scale).applyQuaternion(a.quaternion), a.position.add(ys), a.scale.x *= 0.5 * (h.x - u.x) / d, a.scale.y *= 0.5 * (h.y - u.y) / d, a.scale.z *= 0.5 * (h.z - u.z) / d, s.position = r, a.geometry.boundingBox = null, a.geometry.boundingSphere = null, a.updateMatrixWorld();
}
class co {
  constructor(e) {
    this._options = {
      // whether to generate normals if they don't already exist.
      generateNormals: !1,
      // whether to disable use of mipmaps since they are typically not necessary
      // with something like 3d tiles.
      disableMipmaps: !0,
      // whether to compress certain attributes
      compressIndex: !0,
      compressNormals: !1,
      compressUvs: !1,
      compressPosition: !1,
      // the TypedArray type to use when compressing the attributes
      uvType: Int8Array,
      normalType: Int8Array,
      positionType: Int16Array,
      ...e
    }, this.name = "TILES_COMPRESSION_PLUGIN", this.priority = -100;
  }
  processTileModel(e, t) {
    const {
      generateNormals: s,
      disableMipmaps: n,
      compressIndex: i,
      compressUvs: r,
      compressNormals: o,
      compressPosition: l,
      uvType: c,
      normalType: u,
      positionType: h
    } = this._options;
    e.traverse((d) => {
      if (d.material && n) {
        const m = d.material;
        for (const f in m) {
          const p = m[f];
          p && p.isTexture && p.generateMipmaps && (p.generateMipmaps = !1, p.minFilter = nn);
        }
      }
      if (d.geometry) {
        const m = d.geometry, f = m.attributes;
        if (r) {
          const { uv: p, uv1: g, uv2: y, uv3: x } = f;
          p && (f.uv = Le(p, c)), g && (f.uv1 = Le(g, c)), y && (f.uv2 = Le(y, c)), x && (f.uv3 = Le(x, c));
        }
        if (s && !f.normals && m.computeVertexNormals(), o && f.normals && (f.normals = Le(f.normals, u)), l && Oi(d, h), i && m.index) {
          const p = f.position.count, g = m.index, y = p > 65535 ? Uint32Array : p > 255 ? Uint16Array : Uint8Array;
          if (!(g.array instanceof y)) {
            const x = new y(m.index.count);
            x.set(g.array);
            const T = new J(x, 1);
            m.setIndex(T);
          }
        }
      }
    });
  }
}
function H(a, e, t) {
  return a && e in a ? a[e] : t;
}
function bn(a) {
  return a !== "BOOLEAN" && a !== "STRING" && a !== "ENUM";
}
function Ui(a) {
  return /^FLOAT/.test(a);
}
function Ne(a) {
  return /^VEC/.test(a);
}
function ke(a) {
  return /^MAT/.test(a);
}
function _n(a, e, t, s = null) {
  return ke(t) || Ne(t) ? s.fromArray(a, e) : a[e];
}
function Nt(a) {
  const { type: e, componentType: t } = a;
  switch (e) {
    case "SCALAR":
      return t === "INT64" ? 0n : 0;
    case "VEC2":
      return new q();
    case "VEC3":
      return new E();
    case "VEC4":
      return new Ve();
    case "MAT2":
      return new qn();
    case "MAT3":
      return new Hn();
    case "MAT4":
      return new K();
    case "BOOLEAN":
      return !1;
    case "STRING":
      return "";
    // the final value for enums is a string but are represented as integers
    // during intermediate steps
    case "ENUM":
      return 0;
  }
}
function xs(a, e) {
  if (e == null)
    return !1;
  switch (a) {
    case "SCALAR":
      return typeof e == "number" || typeof e == "bigint";
    case "VEC2":
      return e.isVector2;
    case "VEC3":
      return e.isVector3;
    case "VEC4":
      return e.isVector4;
    case "MAT2":
      return e.isMatrix2;
    case "MAT3":
      return e.isMatrix3;
    case "MAT4":
      return e.isMatrix4;
    case "BOOLEAN":
      return typeof e == "boolean";
    case "STRING":
      return typeof e == "string";
    case "ENUM":
      return typeof e == "number" || typeof e == "bigint";
  }
  throw new Error("ClassProperty: invalid type.");
}
function De(a, e = null) {
  switch (a) {
    case "INT8":
      return Int8Array;
    case "INT16":
      return Int16Array;
    case "INT32":
      return Int32Array;
    case "INT64":
      return BigInt64Array;
    case "UINT8":
      return Uint8Array;
    case "UINT16":
      return Uint16Array;
    case "UINT32":
      return Uint32Array;
    case "UINT64":
      return BigUint64Array;
    case "FLOAT32":
      return Float32Array;
    case "FLOAT64":
      return Float64Array;
  }
  switch (e) {
    case "BOOLEAN":
      return Uint8Array;
    case "STRING":
      return Uint8Array;
  }
  throw new Error("ClassProperty: invalid type.");
}
function Vi(a, e = null) {
  if (a.array) {
    e = e && Array.isArray(e) ? e : [], e.length = a.count;
    for (let s = 0, n = e.length; s < n; s++)
      e[s] = tt(a, e[s]);
  } else
    e = tt(a, e);
  return e;
}
function tt(a, e = null) {
  const t = a.default, s = a.type;
  if (e = e || Nt(a), t === null) {
    switch (s) {
      case "SCALAR":
        return 0;
      case "VEC2":
        return e.set(0, 0);
      case "VEC3":
        return e.set(0, 0, 0);
      case "VEC4":
        return e.set(0, 0, 0, 0);
      case "MAT2":
        return e.identity();
      case "MAT3":
        return e.identity();
      case "MAT4":
        return e.identity();
      case "BOOLEAN":
        return !1;
      case "STRING":
        return "";
      case "ENUM":
        return "";
    }
    throw new Error("ClassProperty: invalid type.");
  } else if (ke(s))
    e.fromArray(t);
  else if (Ne(s))
    e.fromArray(t);
  else
    return t;
}
function Fi(a, e) {
  if (a.noData === null)
    return e;
  const t = a.noData, s = a.type;
  if (Array.isArray(e))
    for (let r = 0, o = e.length; r < o; r++)
      e[r] = n(e[r]);
  else
    e = n(e);
  return e;
  function n(r) {
    return i(r) && (r = tt(a, r)), r;
  }
  function i(r) {
    if (ke(s)) {
      const o = r.elements;
      for (let l = 0, c = t.length; l < c; l++)
        if (t[l] !== o[l])
          return !1;
      return !0;
    } else if (Ne(s)) {
      for (let o = 0, l = t.length; o < l; o++)
        if (t[o] !== r.getComponent(o))
          return !1;
      return !0;
    } else
      return t === r;
  }
}
function Ni(a, e) {
  switch (a) {
    case "INT8":
      return Math.max(e / 127, -1);
    case "INT16":
      return Math.max(e, 32767, -1);
    case "INT32":
      return Math.max(e / 2147483647, -1);
    case "INT64":
      return Math.max(Number(e) / 9223372036854776e3, -1);
    // eslint-disable-line no-loss-of-precision
    case "UINT8":
      return e / 255;
    case "UINT16":
      return e / 65535;
    case "UINT32":
      return e / 4294967295;
    case "UINT64":
      return Number(e) / 18446744073709552e3;
  }
}
function ki(a, e) {
  const {
    type: t,
    componentType: s,
    scale: n,
    offset: i,
    normalized: r
  } = a;
  if (Array.isArray(e))
    for (let h = 0, d = e.length; h < d; h++)
      e[h] = o(e[h]);
  else
    e = o(e);
  return e;
  function o(h) {
    return ke(t) ? h = c(h) : Ne(t) ? h = l(h) : h = u(h), h;
  }
  function l(h) {
    return h.x = u(h.x), h.y = u(h.y), "z" in h && (h.z = u(h.z)), "w" in h && (h.w = u(h.w)), h;
  }
  function c(h) {
    const d = h.elements;
    for (let m = 0, f = d.length; m < f; m++)
      d[m] = u(d[m]);
    return h;
  }
  function u(h) {
    return r && (h = Ni(s, h)), (r || Ui(s)) && (h = h * n + i), h;
  }
}
function Qt(a, e, t = null) {
  if (a.array) {
    Array.isArray(e) || (e = new Array(a.count || 0)), e.length = t !== null ? t : a.count;
    for (let s = 0, n = e.length; s < n; s++)
      xs(a.type, e[s]) || (e[s] = Nt(a));
  } else
    xs(a.type, e) || (e = Nt(a));
  return e;
}
function st(a, e) {
  for (const t in e)
    t in a || delete e[t];
  for (const t in a) {
    const s = a[t];
    e[t] = Qt(s, e[t]);
  }
}
function Gi(a) {
  switch (a) {
    case "ENUM":
      return 1;
    case "SCALAR":
      return 1;
    case "VEC2":
      return 2;
    case "VEC3":
      return 3;
    case "VEC4":
      return 4;
    case "MAT2":
      return 4;
    case "MAT3":
      return 9;
    case "MAT4":
      return 16;
    // unused
    case "BOOLEAN":
      return -1;
    case "STRING":
      return -1;
    default:
      return -1;
  }
}
class ut {
  constructor(e, t, s = null) {
    this.name = t.name || null, this.description = t.description || null, this.type = t.type, this.componentType = t.componentType || null, this.enumType = t.enumType || null, this.array = t.array || !1, this.count = t.count || 0, this.normalized = t.normalized || !1, this.offset = t.offset || 0, this.scale = H(t, "scale", 1), this.max = H(t, "max", 1 / 0), this.min = H(t, "min", -1 / 0), this.required = t.required || !1, this.noData = H(t, "noData", null), this.default = H(t, "default", null), this.semantic = H(t, "semantic", null), this.enumSet = null, this.accessorProperty = s, s && (this.offset = H(s, "offset", this.offset), this.scale = H(s, "scale", this.scale), this.max = H(s, "max", this.max), this.min = H(s, "min", this.min)), t.type === "ENUM" && (this.enumSet = e[this.enumType], this.componentType === null && (this.componentType = H(this.enumSet, "valueType", "UINT16")));
  }
  // shape the given target to match the data type of the property
  // enums are set to their integer value
  shapeToProperty(e, t = null) {
    return Qt(this, e, t);
  }
  // resolve the given object to the default value for the property for a single element
  // enums are set to a default string
  resolveDefaultElement(e) {
    return tt(this, e);
  }
  // resolve the target to the default value for the property for every element if it's an array
  // enums are set to a default string
  resolveDefault(e) {
    return Vi(this, e);
  }
  // converts any instances of no data to the default value
  resolveNoData(e) {
    return Fi(this, e);
  }
  // converts enums integers in the given target to strings
  resolveEnumsToStrings(e) {
    const t = this.enumSet;
    if (this.type === "ENUM")
      if (Array.isArray(e))
        for (let n = 0, i = e.length; n < i; n++)
          e[n] = s(e[n]);
      else
        e = s(e);
    return e;
    function s(n) {
      const i = t.values.find((r) => r.value === n);
      return i === null ? "" : i.name;
    }
  }
  // apply scales
  adjustValueScaleOffset(e) {
    return bn(this.type) ? ki(this, e) : e;
  }
}
class Zt {
  constructor(e, t = {}, s = {}, n = null) {
    this.definition = e, this.class = t[e.class], this.className = e.class, this.enums = s, this.data = n, this.name = "name" in e ? e.name : null, this.properties = null;
  }
  getPropertyNames() {
    return Object.keys(this.class.properties);
  }
  includesData(e) {
    return !!this.definition.properties[e];
  }
  dispose() {
  }
  _initProperties(e = ut) {
    const t = {};
    for (const s in this.class.properties)
      t[s] = new e(this.enums, this.class.properties[s], this.definition.properties[s]);
    this.properties = t;
  }
}
class ji extends ut {
  constructor(e, t, s = null) {
    super(e, t, s), this.attribute = (s == null ? void 0 : s.attribute) ?? null;
  }
}
class zi extends Zt {
  constructor(...e) {
    super(...e), this.isPropertyAttributeAccessor = !0, this._initProperties(ji);
  }
  getData(e, t, s = {}) {
    const n = this.properties;
    st(n, s);
    for (const i in n)
      s[i] = this.getPropertyValue(i, e, t, s[i]);
    return s;
  }
  getPropertyValue(e, t, s, n = null) {
    if (t >= this.count)
      throw new Error("PropertyAttributeAccessor: Requested index is outside the range of the buffer.");
    const i = this.properties[e], r = i.type;
    if (i) {
      if (!this.definition.properties[e])
        return i.resolveDefault(n);
    } else throw new Error("PropertyAttributeAccessor: Requested class property does not exist.");
    n = i.shapeToProperty(n);
    const o = s.getAttribute(i.attribute.toLowerCase());
    if (ke(r)) {
      const l = n.elements;
      for (let c = 0, u = l.length; c < u; c < u)
        l[c] = o.getComponent(t, c);
    } else if (Ne(r))
      n.fromBufferAttribute(o, t);
    else if (r === "SCALAR" || r === "ENUM")
      n = o.getX(t);
    else
      throw new Error("StructuredMetadata.PropertyAttributeAccessor: BOOLEAN and STRING types are not supported by property attributes.");
    return n = i.adjustValueScaleOffset(n), n = i.resolveEnumsToStrings(n), n = i.resolveNoData(n), n;
  }
}
class Hi extends ut {
  constructor(e, t, s = null) {
    super(e, t, s), this.values = (s == null ? void 0 : s.values) ?? null, this.valueLength = Gi(this.type), this.arrayOffsets = H(s, "arrayOffsets", null), this.stringOffsets = H(s, "stringOffsets", null), this.arrayOffsetType = H(s, "arrayOffsetType", "UINT32"), this.stringOffsetType = H(s, "stringOffsetType", "UINT32");
  }
  // returns the necessary array length based on the array offsets if present
  getArrayLengthFromId(e, t) {
    let s = this.count;
    if (this.arrayOffsets !== null) {
      const { arrayOffsets: n, arrayOffsetType: i } = this, r = De(i), o = new r(e[n]);
      s = o[t + 1] - o[t];
    }
    return s;
  }
  // returns the index offset into the data buffer for the given id based on the
  // the array offsets if present
  getIndexOffsetFromId(e, t) {
    let s = t;
    if (this.arrayOffsets) {
      const { arrayOffsets: n, arrayOffsetType: i } = this, r = De(i);
      s = new r(e[n])[s];
    } else this.array && (s *= this.count);
    return s;
  }
}
class qi extends Zt {
  constructor(...e) {
    super(...e), this.isPropertyTableAccessor = !0, this.count = this.definition.count, this._initProperties(Hi);
  }
  getData(e, t = {}) {
    const s = this.properties;
    st(s, t);
    for (const n in s)
      t[n] = this.getPropertyValue(n, e, t[n]);
    return t;
  }
  // reads an individual element
  _readValueAtIndex(e, t, s, n = null) {
    const i = this.properties[e], { componentType: r, type: o } = i, l = this.data, c = l[i.values], u = De(r, o), h = new u(c), d = i.getIndexOffsetFromId(l, t);
    if (bn(o) || o === "ENUM")
      return _n(h, (d + s) * i.valueLength, o, n);
    if (o === "STRING") {
      let m = d + s, f = 0;
      if (i.stringOffsets !== null) {
        const { stringOffsets: g, stringOffsetType: y } = i, x = De(y), T = new x(l[g]);
        f = T[m + 1] - T[m], m = T[m];
      }
      const p = new Uint8Array(h.buffer, m, f);
      n = new TextDecoder().decode(p);
    } else if (o === "BOOLEAN") {
      const m = d + s, f = Math.floor(m / 8), p = m % 8;
      n = (h[f] >> p & 1) === 1;
    }
    return n;
  }
  // Reads the data for the given table index
  getPropertyValue(e, t, s = null) {
    if (t >= this.count)
      throw new Error("PropertyTableAccessor: Requested index is outside the range of the table.");
    const n = this.properties[e];
    if (n) {
      if (!this.definition.properties[e])
        return n.resolveDefault(s);
    } else throw new Error("PropertyTableAccessor: Requested property does not exist.");
    const i = n.array, r = this.data, o = n.getArrayLengthFromId(r, t);
    if (s = n.shapeToProperty(s, o), i)
      for (let l = 0, c = s.length; l < c; l++)
        s[l] = this._readValueAtIndex(e, t, l, s[l]);
    else
      s = this._readValueAtIndex(e, t, 0, s);
    return s = n.adjustValueScaleOffset(s), s = n.resolveEnumsToStrings(s), s = n.resolveNoData(s), s;
  }
}
const Ie = /* @__PURE__ */ new Qn();
class Ts {
  constructor() {
    this._renderer = new Wn(), this._target = new Ft(1, 1), this._texTarget = new Ft(), this._quad = new hn(new rn({
      blending: $n,
      blendDst: Yn,
      blendSrc: Xn,
      uniforms: {
        map: { value: null },
        pixel: { value: new q() }
      },
      vertexShader: (
        /* glsl */
        `
				void main() {

					gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

				}
			`
      ),
      fragmentShader: (
        /* glsl */
        `
				uniform sampler2D map;
				uniform ivec2 pixel;

				void main() {

					gl_FragColor = texelFetch( map, pixel, 0 );

				}
			`
      )
    }));
  }
  // increases the width of the target render target to support more data
  increaseSizeTo(e) {
    this._target.setSize(Math.max(this._target.width, e), 1);
  }
  // read data from the rendered texture asynchronously
  readDataAsync(e) {
    const { _renderer: t, _target: s } = this;
    return t.readRenderTargetPixelsAsync(s, 0, 0, e.length / 4, 1, e);
  }
  // read data from the rendered texture
  readData(e) {
    const { _renderer: t, _target: s } = this;
    t.readRenderTargetPixels(s, 0, 0, e.length / 4, 1, e);
  }
  // render a single pixel from the source at the destination point on the render target
  // takes the texture, pixel to read from, and pixel to render in to
  renderPixelToTarget(e, t, s) {
    const { _renderer: n, _target: i } = this;
    Ie.min.copy(t), Ie.max.copy(t), Ie.max.x += 1, Ie.max.y += 1, n.initRenderTarget(i), n.copyTextureToTexture(e, i.texture, Ie, s, 0);
  }
}
const ue = /* @__PURE__ */ new class {
  constructor() {
    let a = null;
    Object.getOwnPropertyNames(Ts.prototype).forEach((e) => {
      e !== "constructor" && (this[e] = (...t) => (a = a || new Ts(), a[e](...t)));
    });
  }
}(), bs = /* @__PURE__ */ new q(), _s = /* @__PURE__ */ new q(), Ms = /* @__PURE__ */ new q();
function Wi(a, e) {
  return e === 0 ? a.getAttribute("uv") : a.getAttribute(`uv${e}`);
}
function Mn(a, e, t = new Array(3)) {
  let s = 3 * e, n = 3 * e + 1, i = 3 * e + 2;
  return a.index && (s = a.index.getX(s), n = a.index.getX(n), i = a.index.getX(i)), t[0] = s, t[1] = n, t[2] = i, t;
}
function Sn(a, e, t, s, n) {
  const [i, r, o] = s, l = Wi(a, e);
  bs.fromBufferAttribute(l, i), _s.fromBufferAttribute(l, r), Ms.fromBufferAttribute(l, o), n.set(0, 0, 0).addScaledVector(bs, t.x).addScaledVector(_s, t.y).addScaledVector(Ms, t.z);
}
function Cn(a, e, t, s) {
  const n = a.x - Math.floor(a.x), i = a.y - Math.floor(a.y), r = Math.floor(n * e % e), o = Math.floor(i * t % t);
  return s.set(r, o), s;
}
const Ss = /* @__PURE__ */ new q(), Cs = /* @__PURE__ */ new q(), As = /* @__PURE__ */ new q();
class Xi extends ut {
  constructor(e, t, s = null) {
    super(e, t, s), this.channels = H(s, "channels", [0]), this.index = H(s, "index", null), this.texCoord = H(s, "texCoord", null), this.valueLength = parseInt(this.type.replace(/[^0-9]/g, "")) || 1;
  }
  // takes the buffer to read from and the value index to read
  readDataFromBuffer(e, t, s = null) {
    const n = this.type;
    if (n === "BOOLEAN" || n === "STRING")
      throw new Error("PropertyTextureAccessor: BOOLEAN and STRING types not supported.");
    return _n(e, t * this.valueLength, n, s);
  }
}
class Yi extends Zt {
  constructor(...e) {
    super(...e), this.isPropertyTextureAccessor = !0, this._asyncRead = !1, this._initProperties(Xi);
  }
  // Reads the full set of property data
  getData(e, t, s, n = {}) {
    const i = this.properties;
    st(i, n);
    const r = Object.keys(i), o = r.map((l) => n[l]);
    return this.getPropertyValuesAtTexel(r, e, t, s, o), r.forEach((l, c) => n[l] = o[c]), n;
  }
  // Reads the full set of property data asynchronously
  async getDataAsync(e, t, s, n = {}) {
    const i = this.properties;
    st(i, n);
    const r = Object.keys(i), o = r.map((l) => n[l]);
    return await this.getPropertyValuesAtTexelAsync(r, e, t, s, o), r.forEach((l, c) => n[l] = o[c]), n;
  }
  // Reads values asynchronously
  getPropertyValuesAtTexelAsync(...e) {
    this._asyncRead = !0;
    const t = this.getPropertyValuesAtTexel(...e);
    return this._asyncRead = !1, t;
  }
  // Reads values from the textures synchronously
  getPropertyValuesAtTexel(e, t, s, n, i = []) {
    for (; i.length < e.length; ) i.push(null);
    i.length = e.length, ue.increaseSizeTo(i.length);
    const r = this.data, o = this.definition.properties, l = this.properties, c = Mn(n, t);
    for (let d = 0, m = e.length; d < m; d++) {
      const f = e[d];
      if (!o[f])
        continue;
      const p = l[f], g = r[p.index];
      Sn(n, p.texCoord, s, c, Ss), Cn(Ss, g.image.width, g.image.height, Cs), As.set(d, 0), ue.renderPixelToTarget(g, Cs, As);
    }
    const u = new Uint8Array(e.length * 4);
    if (this._asyncRead)
      return ue.readDataAsync(u).then(() => (h.call(this), i));
    return ue.readData(u), h.call(this), i;
    function h() {
      for (let d = 0, m = e.length; d < m; d++) {
        const f = e[d], p = l[f], g = p.type;
        if (i[d] = Qt(p, i[d]), p) {
          if (!o[f]) {
            i[d] = p.resolveDefault(i);
            continue;
          }
        } else throw new Error("PropertyTextureAccessor: Requested property does not exist.");
        const y = p.valueLength * (p.count || 1), x = p.channels.map((b) => u[4 * d + b]), T = p.componentType, _ = De(T, g), S = new _(y);
        if (new Uint8Array(S.buffer).set(x), p.array) {
          const b = i[d];
          for (let C = 0, A = b.length; C < A; C++)
            b[C] = p.readDataFromBuffer(S, C, b[C]);
        } else
          i[d] = p.readDataFromBuffer(S, 0, i[d]);
        i[d] = p.adjustValueScaleOffset(i[d]), i[d] = p.resolveEnumsToStrings(i[d]), i[d] = p.resolveNoData(i[d]);
      }
    }
  }
  // dispose all of the texture data used
  dispose() {
    this.data.forEach((e) => {
      e && (e.dispose(), e.image instanceof ImageBitmap && e.image.close());
    });
  }
}
class vs {
  constructor(e, t, s, n = null, i = null) {
    const {
      schema: r,
      propertyTables: o = [],
      propertyTextures: l = [],
      propertyAttributes: c = []
    } = e, { enums: u, classes: h } = r, d = o.map((p) => new qi(p, h, u, s));
    let m = [], f = [];
    n && (n.propertyTextures && (m = n.propertyTextures.map((p) => new Yi(l[p], h, u, t))), n.propertyAttributes && (f = n.propertyAttributes.map((p) => new zi(c[p], h, u)))), this.schema = r, this.tableAccessors = d, this.textureAccessors = m, this.attributeAccessors = f, this.object = i, this.textures = t, this.nodeMetadata = n;
  }
  // Property Tables
  getPropertyTableData(e, t, s = null) {
    if (!Array.isArray(e) || !Array.isArray(t))
      s = s || {}, s = this.tableAccessors[e].getData(t, s);
    else {
      s = s || [];
      const n = Math.min(e.length, t.length);
      s.length = n;
      for (let i = 0; i < n; i++) {
        const r = this.tableAccessors[e[i]];
        s[i] = r.getData(t[i], s[i]);
      }
    }
    return s;
  }
  getPropertyTableInfo(e = null) {
    if (e === null && (e = this.tableAccessors.map((t, s) => s)), Array.isArray(e))
      return e.map((t) => {
        const s = this.tableAccessors[t];
        return {
          name: s.name,
          className: s.definition.class
        };
      });
    {
      const t = this.tableAccessors[e];
      return {
        name: t.name,
        className: t.definition.class
      };
    }
  }
  // Property Textures
  getPropertyTextureData(e, t, s = []) {
    const n = this.textureAccessors;
    s.length = n.length;
    for (let i = 0; i < n.length; i++) {
      const r = n[i];
      s[i] = r.getData(e, t, this.object.geometry, s[i]);
    }
    return s;
  }
  async getPropertyTextureDataAsync(e, t, s = []) {
    const n = this.textureAccessors;
    s.length = n.length;
    const i = [];
    for (let r = 0; r < n.length; r++) {
      const l = n[r].getDataAsync(e, t, this.object.geometry, s[r]).then((c) => {
        s[r] = c;
      });
      i.push(l);
    }
    return await Promise.all(i), s;
  }
  getPropertyTextureInfo() {
    return this.textureAccessors;
  }
  // Property Attributes
  getPropertyAttributeData(e, t = []) {
    const s = this.attributeAccessors;
    t.length = s.length;
    for (let n = 0; n < s.length; n++) {
      const i = s[n];
      t[n] = i.getData(e, this.object.geometry, t[n]);
    }
    return t;
  }
  getPropertyAttributeInfo() {
    return this.attributeAccessors.map((e) => ({
      name: e.name,
      className: e.definition.class
    }));
  }
  dispose() {
    this.textureAccessors.forEach((e) => e.dispose()), this.tableAccessors.forEach((e) => e.dispose()), this.attributeAccessors.forEach((e) => e.dispose());
  }
}
const Ee = "EXT_structural_metadata";
function $i(a, e = []) {
  var n;
  const t = ((n = a.json.textures) == null ? void 0 : n.length) || 0, s = new Array(t).fill(null);
  return e.forEach(({ properties: i }) => {
    for (const r in i) {
      const { index: o } = i[r];
      s[o] === null && (s[o] = a.loadTexture(o));
    }
  }), Promise.all(s);
}
function Qi(a, e = []) {
  var n;
  const t = ((n = a.json.bufferViews) == null ? void 0 : n.length) || 0, s = new Array(t).fill(null);
  return e.forEach(({ properties: i }) => {
    for (const r in i) {
      const { values: o, arrayOffsets: l, stringOffsets: c } = i[r];
      s[o] === null && (s[o] = a.loadBufferView(o)), s[l] === null && (s[l] = a.loadBufferView(l)), s[c] === null && (s[c] = a.loadBufferView(c));
    }
  }), Promise.all(s);
}
class Zi {
  constructor(e) {
    this.parser = e, this.name = Ee;
  }
  async afterRoot({ scene: e, parser: t }) {
    const s = t.json.extensionsUsed;
    if (!s || !s.includes(Ee))
      return;
    let n = null, i = t.json.extensions[Ee];
    if (i.schemaUri) {
      const { manager: c, path: u, requestHeader: h, crossOrigin: d } = t.options, m = new URL(i.schemaUri, u).toString(), f = new Zn(c);
      f.setCrossOrigin(d), f.setResponseType("json"), f.setRequestHeader(h), n = f.loadAsync(m).then((p) => {
        i = { ...i, schema: p };
      });
    }
    const [r, o] = await Promise.all([
      $i(t, i.propertyTextures),
      Qi(t, i.propertyTables),
      n
    ]), l = new vs(i, r, o);
    e.userData.structuralMetadata = l, e.traverse((c) => {
      var u;
      if (t.associations.has(c)) {
        const { meshes: h, primitives: d } = t.associations.get(c), m = (u = t.json.meshes[h]) == null ? void 0 : u.primitives[d];
        if (m && m.extensions && m.extensions[Ee]) {
          const f = m.extensions[Ee];
          c.userData.structuralMetadata = new vs(i, r, o, f, c);
        } else
          c.userData.structuralMetadata = l;
      }
    });
  }
}
const Ls = /* @__PURE__ */ new q(), Is = /* @__PURE__ */ new q(), Es = /* @__PURE__ */ new q();
function Ji(a) {
  return a.x > a.y && a.x > a.z ? 0 : a.y > a.z ? 1 : 2;
}
class Ki {
  constructor(e, t, s) {
    this.geometry = e, this.textures = t, this.data = s, this._asyncRead = !1, this.featureIds = s.featureIds.map((n) => {
      const { texture: i, ...r } = n, o = {
        label: null,
        propertyTable: null,
        nullFeatureId: null,
        ...r
      };
      return i && (o.texture = {
        texCoord: 0,
        channels: [0],
        ...i
      }), o;
    });
  }
  // returns list of textures
  getTextures() {
    return this.textures;
  }
  // returns a set of info for each feature
  getFeatureInfo() {
    return this.featureIds;
  }
  // performs texture data read back asynchronously
  getFeaturesAsync(...e) {
    this._asyncRead = !0;
    const t = this.getFeatures(...e);
    return this._asyncRead = !1, t;
  }
  // returns all features for the given point on the given triangle
  getFeatures(e, t) {
    const { geometry: s, textures: n, featureIds: i } = this, r = new Array(i.length).fill(null), o = i.length;
    ue.increaseSizeTo(o);
    const l = Mn(s, e), c = l[Ji(t)];
    for (let d = 0, m = i.length; d < m; d++) {
      const f = i[d], p = "nullFeatureId" in f ? f.nullFeatureId : null;
      if ("texture" in f) {
        const g = n[f.texture.index];
        Sn(s, f.texture.texCoord, t, l, Ls), Cn(Ls, g.image.width, g.image.height, Is), Es.set(d, 0), ue.renderPixelToTarget(n[f.texture.index], Is, Es);
      } else if ("attribute" in f) {
        const y = s.getAttribute(`_feature_id_${f.attribute}`).getX(c);
        y !== p && (r[d] = y);
      } else {
        const g = c;
        g !== p && (r[d] = g);
      }
    }
    const u = new Uint8Array(o * 4);
    if (this._asyncRead)
      return ue.readDataAsync(u).then(() => (h(), r));
    return ue.readData(u), h(), r;
    function h() {
      const d = new Uint32Array(1);
      for (let m = 0, f = i.length; m < f; m++) {
        const p = i[m], g = "nullFeatureId" in p ? p.nullFeatureId : null;
        if ("texture" in p) {
          const { channels: y } = p.texture, x = y.map((_) => u[4 * m + _]);
          new Uint8Array(d.buffer).set(x);
          const T = d[0];
          T !== g && (r[m] = T);
        }
      }
    }
  }
  // dispose all of the texture data used
  dispose() {
    this.textures.forEach((e) => {
      e && (e.dispose(), e.image instanceof ImageBitmap && e.image.close());
    });
  }
}
const nt = "EXT_mesh_features";
function ws(a, e, t) {
  a.traverse((s) => {
    var n;
    if (e.associations.has(s)) {
      const { meshes: i, primitives: r } = e.associations.get(s), o = (n = e.json.meshes[i]) == null ? void 0 : n.primitives[r];
      o && o.extensions && o.extensions[nt] && t(s, o.extensions[nt]);
    }
  });
}
class er {
  constructor(e) {
    this.parser = e, this.name = nt;
  }
  async afterRoot({ scene: e, parser: t }) {
    var o;
    const s = t.json.extensionsUsed;
    if (!s || !s.includes(nt))
      return;
    const n = ((o = t.json.textures) == null ? void 0 : o.length) || 0, i = new Array(n).fill(null);
    ws(e, t, (l, { featureIds: c }) => {
      c.forEach((u) => {
        if (u.texture && i[u.texture.index] === null) {
          const h = u.texture.index;
          i[h] = t.loadTexture(h);
        }
      });
    });
    const r = await Promise.all(i);
    ws(e, t, (l, c) => {
      l.userData.meshFeatures = new Ki(l.geometry, r, c);
    });
  }
}
class tr {
  constructor() {
    this.name = "CESIUM_RTC";
  }
  afterRoot(e) {
    if (e.parser.json.extensions && e.parser.json.extensions.CESIUM_RTC) {
      const { center: t } = e.parser.json.extensions.CESIUM_RTC;
      t && (e.scene.position.x += t[0], e.scene.position.y += t[1], e.scene.position.z += t[2]);
    }
  }
}
class uo {
  constructor(e) {
    e = {
      metadata: !0,
      rtc: !0,
      plugins: [],
      dracoLoader: null,
      ktxLoader: null,
      meshoptDecoder: null,
      autoDispose: !0,
      ...e
    }, this.tiles = null, this.metadata = e.metadata, this.rtc = e.rtc, this.plugins = e.plugins, this.dracoLoader = e.dracoLoader, this.ktxLoader = e.ktxLoader, this.meshoptDecoder = e.meshoptDecoder, this._gltfRegex = /\.(gltf|glb)$/g, this._dracoRegex = /\.drc$/g, this._loader = null;
  }
  init(e) {
    const t = new fi(e.manager);
    this.dracoLoader && (t.setDRACOLoader(this.dracoLoader), e.manager.addHandler(this._dracoRegex, this.dracoLoader)), this.ktxLoader && t.setKTX2Loader(this.ktxLoader), this.meshoptDecoder && t.setMeshoptDecoder(this.meshoptDecoder), this.rtc && t.register(() => new tr()), this.metadata && (t.register(() => new Zi()), t.register(() => new er())), this.plugins.forEach((s) => t.register(s)), e.manager.addHandler(this._gltfRegex, t), this.tiles = e, this._loader = t;
  }
  dispose() {
    this.tiles.manager.removeHandler(this._gltfRegex), this.tiles.manager.removeHandler(this._dracoRegex), this.autoDispose && (this.ktxLoader.dispose(), this.dracoLoader.dispose());
  }
}
const qe = /* @__PURE__ */ new he();
class ho {
  constructor(e) {
    e = {
      up: "+z",
      recenter: !0,
      lat: null,
      lon: null,
      height: 0,
      azimuth: 0,
      elevation: 0,
      roll: 0,
      ...e
    }, this.tiles = null, this.up = e.up.toLowerCase().replace(/\s+/, ""), this.lat = e.lat, this.lon = e.lon, this.height = e.height, this.azimuth = e.azimuth, this.elevation = e.elevation, this.roll = e.roll, this.recenter = e.recenter, this._callback = null;
  }
  init(e) {
    this.tiles = e, this._callback = () => {
      const { up: t, lat: s, lon: n, height: i, azimuth: r, elevation: o, roll: l, recenter: c } = this;
      if (s !== null && n !== null)
        this.transformLatLonHeightToOrigin(s, n, i, r, o, l);
      else {
        const { ellipsoid: u } = e, h = Math.min(...u.radius);
        if (e.getBoundingSphere(qe), qe.center.length() > h * 0.5) {
          const d = {};
          u.getPositionToCartographic(qe.center, d), this.transformLatLonHeightToOrigin(d.lat, d.lon, d.height);
        } else {
          const d = e.group;
          switch (d.rotation.set(0, 0, 0), t) {
            case "x":
            case "+x":
              d.rotation.z = Math.PI / 2;
              break;
            case "-x":
              d.rotation.z = -Math.PI / 2;
              break;
            case "y":
            case "+y":
              break;
            case "-y":
              d.rotation.z = Math.PI;
              break;
            case "z":
            case "+z":
              d.rotation.x = -Math.PI / 2;
              break;
            case "-z":
              d.rotation.x = Math.PI / 2;
              break;
          }
          e.group.position.copy(qe.center).applyEuler(d.rotation).multiplyScalar(-1);
        }
      }
      c || e.group.position.setScalar(0), e.removeEventListener("load-root-tileset", this._callback);
    }, e.addEventListener("load-root-tileset", this._callback), e.root && this._callback();
  }
  transformLatLonHeightToOrigin(e, t, s = 0, n = 0, i = 0, r = 0) {
    const { group: o, ellipsoid: l } = this.tiles;
    l.getObjectFrame(e, t, s, n, i, r, o.matrix, ci), o.matrix.invert().decompose(o.position, o.quaternion, o.scale), o.updateMatrixWorld();
  }
  dispose() {
    const { group: e } = this.tiles;
    e.position.setScalar(0), e.quaternion.identity(), e.scale.set(1, 1, 1), this.tiles.removeEventListener("load-root-tileset", this._callback);
  }
}
class po {
  set delay(e) {
    this.deferCallbacks.delay = e;
  }
  get delay() {
    return this.deferCallbacks.delay;
  }
  set bytesTarget(e) {
    this.lruCache.minBytesSize = e;
  }
  get bytesTarget() {
    return this.lruCache.minBytesSize;
  }
  get estimatedGpuBytes() {
    return this.lruCache.cachedBytes;
  }
  constructor(e = {}) {
    const {
      delay: t = 0,
      bytesTarget: s = 0
    } = e;
    this.name = "UNLOAD_TILES_PLUGIN", this.tiles = null, this.lruCache = new mi(), this.deferCallbacks = new sr(), this.delay = t, this.bytesTarget = s;
  }
  init(e) {
    this.tiles = e;
    const { lruCache: t, deferCallbacks: s } = this;
    s.callback = (i) => {
      t.markUnused(i), t.scheduleUnload(!1);
    };
    const n = (i) => {
      const r = i.cached.scene;
      e.visibleTiles.has(i) || e.invokeOnePlugin((l) => l.unloadTileFromGPU && l.unloadTileFromGPU(r, i));
    };
    this._onUpdateBefore = () => {
      t.unloadPriorityCallback = e.lruCache.unloadPriorityCallback, t.computeMemoryUsageCallback = e.lruCache.computeMemoryUsageCallback, t.minSize = 1 / 0, t.maxSize = 1 / 0, t.maxBytesSize = 1 / 0, t.unloadPercent = 1, t.autoMarkUnused = !1;
    }, this._onVisibilityChangeCallback = ({ tile: i, visible: r }) => {
      r ? (t.add(i, n), e.markTileUsed(i), s.cancel(i)) : s.run(i);
    }, e.forEachLoadedModel((i, r) => {
      const o = e.visibleTiles.has(r);
      this._onVisibilityChangeCallback({ scene: i, visible: o });
    }), e.addEventListener("tile-visibility-change", this._onVisibilityChangeCallback), e.addEventListener("update-before", this._onUpdateBefore);
  }
  unloadTileFromGPU(e, t) {
    e && e.traverse((s) => {
      if (s.material) {
        const n = s.material;
        n.dispose();
        for (const i in n) {
          const r = n[i];
          r && r.isTexture && r.dispose();
        }
      }
      s.geometry && s.geometry.dispose();
    });
  }
  dispose() {
    this.tiles.removeEventListener("tile-visibility-change", this._onVisibilityChangeCallback), this.tiles.removeEventListener("update-before", this._onUpdateBefore), this.deferCallbacks.cancelAll();
  }
}
class sr {
  constructor(e = () => {
  }) {
    this.map = /* @__PURE__ */ new Map(), this.callback = e, this.delay = 0;
  }
  run(e) {
    const { map: t, delay: s } = this;
    if (t.has(e))
      throw new Error("DeferCallbackManager: Callback already initialized.");
    s === 0 ? this.callback(e) : t.set(e, setTimeout(() => this.callback(e), s));
  }
  cancel(e) {
    const { map: t } = this;
    t.has(e) && (clearTimeout(t.get(e)), t.delete(e));
  }
  cancelAll() {
    this.map.forEach((e, t) => {
      this.cancel(t);
    });
  }
}
const { clamp: bt } = M;
class nr {
  constructor() {
    this.duration = 250, this.fadeCount = 0, this._lastTick = -1, this._fadeState = /* @__PURE__ */ new Map(), this.onFadeComplete = null, this.onFadeStart = null, this.onFadeSetComplete = null, this.onFadeSetStart = null;
  }
  // delete the object from the fade, reset the material data
  deleteObject(e) {
    e && this.completeFade(e);
  }
  // Ensure we're storing a fade timer for the provided object
  // Returns whether a new state had to be added
  guaranteeState(e) {
    const t = this._fadeState;
    if (t.has(e))
      return !1;
    const s = {
      fadeInTarget: 0,
      fadeOutTarget: 0,
      fadeIn: 0,
      fadeOut: 0
    };
    return t.set(e, s), !0;
  }
  // Force the fade to complete in the direction it is already trending
  completeFade(e) {
    const t = this._fadeState;
    if (!t.has(e))
      return;
    const s = t.get(e).fadeOutTarget === 0;
    t.delete(e), this.fadeCount--, this.onFadeComplete && this.onFadeComplete(e, s), this.fadeCount === 0 && this.onFadeSetComplete && this.onFadeSetComplete();
  }
  completeAllFades() {
    this._fadeState.forEach((e, t) => {
      this.completeFade(t);
    });
  }
  forEachObject(e) {
    this._fadeState.forEach((t, s) => {
      e(s, t);
    });
  }
  // Fade the object in
  fadeIn(e) {
    const t = this.guaranteeState(e), s = this._fadeState.get(e);
    s.fadeInTarget = 1, s.fadeOutTarget = 0, s.fadeOut = 0, t && (this.fadeCount++, this.fadeCount === 1 && this.onFadeSetStart && this.onFadeSetStart(), this.onFadeStart && this.onFadeStart(e));
  }
  // Fade the object out
  fadeOut(e) {
    const t = this.guaranteeState(e), s = this._fadeState.get(e);
    s.fadeOutTarget = 1, t && (s.fadeInTarget = 1, s.fadeIn = 1, this.fadeCount++, this.fadeCount === 1 && this.onFadeSetStart && this.onFadeSetStart(), this.onFadeStart && this.onFadeStart(e));
  }
  isFading(e) {
    return this._fadeState.has(e);
  }
  isFadingOut(e) {
    const t = this._fadeState.get(e);
    return t && t.fadeOutTarget === 1;
  }
  // Tick the fade timer for each actively fading object
  update() {
    const e = window.performance.now();
    this._lastTick === -1 && (this._lastTick = e);
    const t = bt((e - this._lastTick) / this.duration, 0, 1);
    this._lastTick = e, this._fadeState.forEach((n, i) => {
      const {
        fadeOutTarget: r,
        fadeInTarget: o
      } = n;
      let {
        fadeOut: l,
        fadeIn: c
      } = n;
      const u = Math.sign(o - c);
      c = bt(c + u * t, 0, 1);
      const h = Math.sign(r - l);
      l = bt(l + h * t, 0, 1), n.fadeIn = c, n.fadeOut = l, ((l === 1 || l === 0) && (c === 1 || c === 0) || l >= c) && this.completeFade(i);
    });
  }
}
const _t = Symbol("FADE_PARAMS");
function An(a, e) {
  if (a[_t])
    return a[_t];
  const t = {
    fadeIn: { value: 0 },
    fadeOut: { value: 0 },
    fadeTexture: { value: null }
  };
  return a[_t] = t, a.defines = {
    ...a.defines || {},
    FEATURE_FADE: 0
  }, a.onBeforeCompile = (s) => {
    e && e(s), s.uniforms = {
      ...s.uniforms,
      ...t
    }, s.vertexShader = s.vertexShader.replace(
      /void\s+main\(\)\s+{/,
      (n) => (
        /* glsl */
        `
					#ifdef USE_BATCHING_FRAG

					varying float vBatchId;

					#endif

					${n}

						#ifdef USE_BATCHING_FRAG

						// add 0.5 to the value to avoid floating error that may cause flickering
						vBatchId = getIndirectIndex( gl_DrawID ) + 0.5;

						#endif
				`
      )
    ), s.fragmentShader = s.fragmentShader.replace(/void main\(/, (n) => (
      /* glsl */
      `
				#if FEATURE_FADE

				// adapted from https://www.shadertoy.com/view/Mlt3z8
				float bayerDither2x2( vec2 v ) {

					return mod( 3.0 * v.y + 2.0 * v.x, 4.0 );

				}

				float bayerDither4x4( vec2 v ) {

					vec2 P1 = mod( v, 2.0 );
					vec2 P2 = floor( 0.5 * mod( v, 4.0 ) );
					return 4.0 * bayerDither2x2( P1 ) + bayerDither2x2( P2 );

				}

				// the USE_BATCHING define is not available in fragment shaders
				#ifdef USE_BATCHING_FRAG

				// functions for reading the fade state of a given batch id
				uniform sampler2D fadeTexture;
				varying float vBatchId;
				vec2 getFadeValues( const in float i ) {

					int size = textureSize( fadeTexture, 0 ).x;
					int j = int( i );
					int x = j % size;
					int y = j / size;
					return texelFetch( fadeTexture, ivec2( x, y ), 0 ).rg;

				}

				#else

				uniform float fadeIn;
				uniform float fadeOut;

				#endif

				#endif

				${n}
			`
    )).replace(/#include <dithering_fragment>/, (n) => (
      /* glsl */
      `

				${n}

				#if FEATURE_FADE

				#ifdef USE_BATCHING_FRAG

				vec2 fadeValues = getFadeValues( vBatchId );
				float fadeIn = fadeValues.r;
				float fadeOut = fadeValues.g;

				#endif

				float bayerValue = bayerDither4x4( floor( mod( gl_FragCoord.xy, 4.0 ) ) );
				float bayerBins = 16.0;
				float dither = ( 0.5 + bayerValue ) / bayerBins;
				if ( dither >= fadeIn ) {

					discard;

				}

				if ( dither < fadeOut ) {

					discard;

				}

				#endif

			`
    ));
  }, t;
}
class ir {
  constructor() {
    this._fadeParams = /* @__PURE__ */ new WeakMap(), this.fading = 0;
  }
  // Set the fade parameters for the given scene
  setFade(e, t, s) {
    if (!e)
      return;
    const n = this._fadeParams;
    e.traverse((i) => {
      const r = i.material;
      if (r && n.has(r)) {
        const o = n.get(r);
        o.fadeIn.value = t, o.fadeOut.value = s;
        const u = +(!(t === 0 || t === 1) || !(s === 0 || s === 1));
        r.defines.FEATURE_FADE !== u && (this.fading += u === 1 ? 1 : -1, r.defines.FEATURE_FADE = u, r.needsUpdate = !0);
      }
    });
  }
  // initialize materials in the object
  prepareScene(e) {
    e.traverse((t) => {
      t.material && this.prepareMaterial(t.material);
    });
  }
  // delete the object from the fade, reset the material data
  deleteScene(e) {
    if (!e)
      return;
    this.setFade(e, 1, 0);
    const t = this._fadeParams;
    e.traverse((s) => {
      const n = s.material;
      n && t.delete(n);
    });
  }
  // initialize the material
  prepareMaterial(e) {
    const t = this._fadeParams;
    t.has(e) || t.set(e, An(e, e.onBeforeCompile));
  }
}
class rr {
  constructor(e, t = new Ue()) {
    this.other = e, this.material = t, this.visible = !0, this.parent = null, this._instanceInfo = [], this._visibilityChanged = !0;
    const s = new Proxy(this, {
      get(n, i) {
        if (i in n)
          return n[i];
        {
          const r = e[i];
          return r instanceof Function ? (...o) => (n.syncInstances(), r.call(s, ...o)) : e[i];
        }
      },
      set(n, i, r) {
        return i in n ? n[i] = r : e[i] = r, !0;
      },
      deleteProperty(n, i) {
        return i in n ? delete n[i] : delete e[i];
      }
      // ownKeys() {},
      // has(target, key) {},
      // defineProperty(target, key, descriptor) {},
      // getOwnPropertyDescriptor(target, key) {},
    });
    return s;
  }
  syncInstances() {
    const e = this._instanceInfo, t = this.other._instanceInfo;
    for (; t.length > e.length; ) {
      const s = e.length;
      e.push(new Proxy({ visible: !1 }, {
        get(n, i) {
          return i in n ? n[i] : t[s][i];
        },
        set(n, i, r) {
          return i in n ? n[i] = r : t[s][i] = r, !0;
        }
      }));
    }
  }
}
class or extends rr {
  constructor(...e) {
    super(...e);
    const t = this.material, s = An(t, t.onBeforeCompile);
    t.defines.FEATURE_FADE = 1, t.defines.USE_BATCHING_FRAG = 1, t.needsUpdate = !0, this.fadeTexture = null, this._fadeParams = s;
  }
  // Set the fade state
  setFadeAt(e, t, s) {
    this._initFadeTexture(), this.fadeTexture.setValueAt(e, t * 255, s * 255);
  }
  // initialize the texture and resize it if needed
  _initFadeTexture() {
    let e = Math.sqrt(this._maxInstanceCount);
    e = Math.ceil(e);
    const t = e * e * 2, s = this.fadeTexture;
    if (!s || s.image.data.length !== t) {
      const n = new Uint8Array(t), i = new ar(n, e, e, tn, sn);
      if (s) {
        s.dispose();
        const r = s.image.data, o = this.fadeTexture.image.data, l = Math.min(r.length, o.length);
        o.set(new r.constructor(r.buffer, 0, l));
      }
      this.fadeTexture = i, this._fadeParams.fadeTexture.value = i, i.needsUpdate = !0;
    }
  }
  // dispose the fade texture. Super cannot be used here due to proxy
  dispose() {
    this.fadeTexture && this.fadeTexture.dispose();
  }
}
class ar extends Wt {
  setValueAt(e, ...t) {
    const { data: s, width: n, height: i } = this.image, r = Math.floor(s.length / (n * i));
    let o = !1;
    for (let l = 0; l < r; l++) {
      const c = e * r + l, u = s[c], h = t[l] || 0;
      u !== h && (s[c] = h, o = !0);
    }
    o && (this.needsUpdate = !0);
  }
}
const Ps = Symbol("HAS_POPPED_IN"), Rs = /* @__PURE__ */ new E(), Bs = /* @__PURE__ */ new E(), Ds = /* @__PURE__ */ new on(), Os = /* @__PURE__ */ new on(), Us = /* @__PURE__ */ new E();
function lr() {
  const a = this._fadeManager, e = this.tiles;
  this._fadingBefore = a.fadeCount, this._displayActiveTiles = e.displayActiveTiles, e.displayActiveTiles = !0;
}
function cr() {
  const a = this._fadeManager, e = this._fadeMaterialManager, t = this._displayActiveTiles, s = this._fadingBefore, n = this._prevCameraTransforms, { tiles: i, maximumFadeOutTiles: r, batchedMesh: o } = this, { cameras: l } = i;
  i.displayActiveTiles = t, a.update();
  const c = a.fadeCount;
  if (s !== 0 && c !== 0 && (i.dispatchEvent({ type: "fade-change" }), i.dispatchEvent({ type: "needs-render" })), t || i.visibleTiles.forEach((u) => {
    const h = u.cached.scene;
    h && (h.visible = u.__inFrustum), this.forEachBatchIds(u, (d, m, f) => {
      m.setVisibleAt(d, u.__inFrustum), f.batchedMesh.setVisibleAt(d, u.__inFrustum);
    });
  }), r < this._fadingOutCount) {
    let u = !0;
    l.forEach((h) => {
      if (!n.has(h))
        return;
      const d = h.matrixWorld, m = n.get(h);
      d.decompose(Bs, Os, Us), m.decompose(Rs, Ds, Us);
      const f = Os.angleTo(Ds), p = Bs.distanceTo(Rs);
      u = u && (f > 0.25 || p > 0.1);
    }), u && a.completeAllFades();
  }
  if (l.forEach((u) => {
    n.get(u).copy(u.matrixWorld);
  }), a.forEachObject((u, { fadeIn: h, fadeOut: d }) => {
    const m = u.cached.scene, f = a.isFadingOut(u);
    i.markTileUsed(u), m && (e.setFade(m, h, d), f && (m.visible = !0)), this.forEachBatchIds(u, (p, g, y) => {
      g.setFadeAt(p, h, d), g.setVisibleAt(p, !0), y.batchedMesh.setVisibleAt(p, !1);
    });
  }), o) {
    const u = i.getPluginByName("BATCHED_TILES_PLUGIN").batchedMesh.material;
    o.material.map = u.map;
  }
}
class fo {
  get fadeDuration() {
    return this._fadeManager.duration;
  }
  set fadeDuration(e) {
    this._fadeManager.duration = Number(e);
  }
  get fadingTiles() {
    return this._fadeManager.fadeCount;
  }
  constructor(e) {
    e = {
      maximumFadeOutTiles: 50,
      fadeRootTiles: !1,
      fadeDuration: 250,
      ...e
    }, this.name = "FADE_TILES_PLUGIN", this.priority = -2, this.tiles = null, this.batchedMesh = null, this._quickFadeTiles = /* @__PURE__ */ new Set(), this._fadeManager = new nr(), this._fadeMaterialManager = new ir(), this._prevCameraTransforms = null, this._fadingOutCount = 0, this.maximumFadeOutTiles = e.maximumFadeOutTiles, this.fadeRootTiles = e.fadeRootTiles, this.fadeDuration = e.fadeDuration;
  }
  init(e) {
    this._onLoadModel = ({ scene: n }) => {
      this._fadeMaterialManager.prepareScene(n);
    }, this._onDisposeModel = ({ tile: n, scene: i }) => {
      this.tiles.visibleTiles.has(n) && this._quickFadeTiles.add(n.parent), this._fadeManager.deleteObject(n), this._fadeMaterialManager.deleteScene(i);
    }, this._onAddCamera = ({ camera: n }) => {
      this._prevCameraTransforms.set(n, new K());
    }, this._onDeleteCamera = ({ camera: n }) => {
      this._prevCameraTransforms.delete(n);
    }, this._onTileVisibilityChange = ({ tile: n, visible: i }) => {
      const r = n.cached.scene;
      r && (r.visible = !0), this.forEachBatchIds(n, (o, l, c) => {
        l.setFadeAt(o, 0, 0), l.setVisibleAt(o, !1), c.batchedMesh.setVisibleAt(o, !1);
      });
    }, this._onUpdateBefore = () => {
      lr.call(this);
    }, this._onUpdateAfter = () => {
      cr.call(this);
    }, e.addEventListener("load-model", this._onLoadModel), e.addEventListener("dispose-model", this._onDisposeModel), e.addEventListener("add-camera", this._onAddCamera), e.addEventListener("delete-camera", this._onDeleteCamera), e.addEventListener("update-before", this._onUpdateBefore), e.addEventListener("update-after", this._onUpdateAfter), e.addEventListener("tile-visibility-change", this._onTileVisibilityChange);
    const t = this._fadeManager;
    t.onFadeSetStart = () => {
      e.dispatchEvent({ type: "fade-start" }), e.dispatchEvent({ type: "needs-render" });
    }, t.onFadeSetComplete = () => {
      e.dispatchEvent({ type: "fade-end" }), e.dispatchEvent({ type: "needs-render" });
    }, t.onFadeComplete = (n, i) => {
      this._fadeMaterialManager.setFade(n.cached.scene, 0, 0), this.forEachBatchIds(n, (r, o, l) => {
        o.setFadeAt(r, 0, 0), o.setVisibleAt(r, !1), l.batchedMesh.setVisibleAt(r, i);
      }), i || (e.invokeOnePlugin((r) => r !== this && r.setTileVisible && r.setTileVisible(n, !1)), this._fadingOutCount--);
    };
    const s = /* @__PURE__ */ new Map();
    e.cameras.forEach((n) => {
      s.set(n, new K());
    }), e.forEachLoadedModel((n, i) => {
      this._onLoadModel({ scene: n });
    }), this.tiles = e, this._fadeManager = t, this._prevCameraTransforms = s;
  }
  // initializes the batched mesh if it needs to be, dispose if it it's no longer needed
  initBatchedMesh() {
    var t;
    const e = (t = this.tiles.getPluginByName("BATCHED_TILES_PLUGIN")) == null ? void 0 : t.batchedMesh;
    if (e) {
      if (this.batchedMesh === null) {
        this._onBatchedMeshDispose = () => {
          this.batchedMesh.dispose(), this.batchedMesh.removeFromParent(), this.batchedMesh = null, e.removeEventListener("dispose", this._onBatchedMeshDispose);
        };
        const s = e.material.clone();
        s.onBeforeCompile = e.material.onBeforeCompile, this.batchedMesh = new or(e, s), this.tiles.group.add(this.batchedMesh);
      }
    } else
      this.batchedMesh !== null && (this._onBatchedMeshDispose(), this._onBatchedMeshDispose = null);
  }
  // callback for fading to prevent tiles from being removed until the fade effect has completed
  setTileVisible(e, t) {
    const s = this._fadeManager, n = s.isFading(e);
    if (s.isFadingOut(e) && this._fadingOutCount--, t ? e.__depthFromRenderedParent === 1 ? ((e[Ps] || this.fadeRootTiles) && this._fadeManager.fadeIn(e), e[Ps] = !0) : this._fadeManager.fadeIn(e) : (this._fadingOutCount++, s.fadeOut(e)), this._quickFadeTiles.has(e) && (this._fadeManager.completeFade(e), this._quickFadeTiles.delete(e)), n)
      return !0;
    const i = this._fadeManager.isFading(e);
    return !!(!t && i);
  }
  dispose() {
    const e = this.tiles;
    this._fadeManager.completeAllFades(), this.batchedMesh !== null && this._onBatchedMeshDispose(), e.removeEventListener("load-model", this._onLoadModel), e.removeEventListener("dispose-model", this._onDisposeModel), e.removeEventListener("add-camera", this._onAddCamera), e.removeEventListener("delete-camera", this._onDeleteCamera), e.removeEventListener("update-before", this._onUpdateBefore), e.removeEventListener("update-after", this._onUpdateAfter), e.removeEventListener("tile-visibility-change", this._onTileVisibilityChange), e.forEachLoadedModel((t, s) => {
      this._fadeManager.deleteObject(s), t && (t.visible = !0);
    });
  }
  // helper for iterating over the batch ids for a given tile
  forEachBatchIds(e, t) {
    if (this.initBatchedMesh(), this.batchedMesh) {
      const s = this.tiles.getPluginByName("BATCHED_TILES_PLUGIN"), n = s.getTileBatchIds(e);
      n && n.forEach((i) => {
        t(i, this.batchedMesh, s);
      });
    }
  }
}
const Mt = /* @__PURE__ */ new K(), Vs = /* @__PURE__ */ new E(), Fs = /* @__PURE__ */ new E();
class ur extends Jn {
  constructor(...e) {
    super(...e), this.resetDistance = 1e4, this._matricesTextureHandle = null, this._lastCameraPos = new K(), this._forceUpdate = !0, this._matrices = [];
  }
  setMatrixAt(e, t) {
    super.setMatrixAt(e, t), this._forceUpdate = !0;
    const s = this._matrices;
    for (; s.length <= e; )
      s.push(new K());
    s[e].copy(t);
  }
  setInstanceCount(...e) {
    super.setInstanceCount(...e);
    const t = this._matrices;
    for (; t.length > this.instanceCount; )
      t.pop();
  }
  onBeforeRender(e, t, s, n, i, r) {
    super.onBeforeRender(e, t, s, n, i, r), Vs.setFromMatrixPosition(s.matrixWorld), Fs.setFromMatrixPosition(this._lastCameraPos);
    const o = this._matricesTexture;
    let l = this._modelViewMatricesTexture;
    if ((!l || l.image.width !== o.image.width || l.image.height !== o.image.height) && (l && l.dispose(), l = o.clone(), l.source = new Kn({
      ...l.image,
      data: l.image.data.slice()
    }), this._modelViewMatricesTexture = l), this._forceUpdate || Vs.distanceTo(Fs) > this.resetDistance) {
      const c = this._matrices, u = l.image.data;
      for (let h = 0; h < this.maxInstanceCount; h++) {
        const d = c[h];
        d ? Mt.copy(d) : Mt.identity(), Mt.premultiply(this.matrixWorld).premultiply(s.matrixWorldInverse).toArray(u, h * 16);
      }
      l.needsUpdate = !0, this._lastCameraPos.copy(s.matrixWorld), this._forceUpdate = !1;
    }
    this._matricesTextureHandle = this._matricesTexture, this._matricesTexture = this._modelViewMatricesTexture, this.matrixWorld.copy(this._lastCameraPos);
  }
  onAfterRender() {
    this.updateMatrixWorld(), this._matricesTexture = this._matricesTextureHandle, this._matricesTextureHandle = null;
  }
  onAfterShadow(e, t, s, n, i, r) {
    this.onAfterRender(e, null, n, i, r);
  }
  dispose() {
    super.dispose(), this._modelViewMatricesTexture && this._modelViewMatricesTexture.dispose();
  }
}
const ee = /* @__PURE__ */ new Oe(), We = [];
class hr extends ur {
  constructor(...e) {
    super(...e), this.expandPercent = 0.25, this.maxInstanceExpansionSize = 1 / 0, this._freeGeometryIds = [];
  }
  // Finds a free id that can fit the geometry with the requested ranges. Returns -1 if it could not be found.
  findFreeId(e, t, s) {
    const n = !!this.geometry.index, i = Math.max(n ? e.index.count : -1, s), r = Math.max(e.attributes.position.count, t);
    let o = -1, l = 1 / 0;
    const c = this._freeGeometryIds;
    if (c.forEach((u, h) => {
      const d = this.getGeometryRangeAt(u), { reservedIndexCount: m, reservedVertexCount: f } = d;
      if (m >= i && f >= r) {
        const p = i - m + (r - f);
        p < l && (o = h, l = p);
      }
    }), o !== -1) {
      const u = c[o];
      return c.splice(o, 1), u;
    } else
      return -1;
  }
  // Overrides addGeometry to find an option geometry slot, expand, or optimized if needed
  addGeometry(e, t, s) {
    const n = !!this.geometry.index;
    s = Math.max(n ? e.index.count : -1, s), t = Math.max(e.attributes.position.count, t);
    const { expandPercent: i, _freeGeometryIds: r } = this;
    let o = this.findFreeId(e, t, s);
    if (o !== -1)
      this.setGeometryAt(o, e);
    else {
      const l = () => {
        const h = this.unusedVertexCount < t, d = this.unusedIndexCount < s;
        return h || d;
      }, c = e.index, u = e.attributes.position;
      if (t = Math.max(t, u.count), s = Math.max(s, c ? c.count : 0), l() && (r.forEach((h) => this.deleteGeometry(h)), r.length = 0, this.optimize(), l())) {
        const h = this.geometry.index, d = this.geometry.attributes.position;
        let m, f;
        if (h) {
          const p = Math.ceil(i * h.count);
          m = Math.max(p, s, c.count) + h.count;
        } else
          m = Math.max(this.unusedIndexCount, s);
        if (d) {
          const p = Math.ceil(i * d.count);
          f = Math.max(p, t, u.count) + d.count;
        } else
          f = Math.max(this.unusedVertexCount, t);
        this.setGeometrySize(f, m);
      }
      o = super.addGeometry(e, t, s);
    }
    return o;
  }
  // add an instance and automatically expand the number of instances if necessary
  addInstance(e) {
    if (this.maxInstanceCount === this.instanceCount) {
      const t = Math.ceil(this.maxInstanceCount * (1 + this.expandPercent));
      this.setInstanceCount(Math.min(t, this.maxInstanceExpansionSize));
    }
    return super.addInstance(e);
  }
  // delete an instance, keeping note that the geometry id is now unused
  deleteInstance(e) {
    const t = this.getGeometryIdAt(e);
    return t !== -1 && this._freeGeometryIds.push(t), super.deleteInstance(e);
  }
  // add a function for raycasting per tile
  raycastInstance(e, t, s) {
    const n = this.geometry, i = this.getGeometryIdAt(e);
    ee.material = this.material, ee.geometry.index = n.index, ee.geometry.attributes = n.attributes;
    const r = this.getGeometryRangeAt(i);
    ee.geometry.setDrawRange(r.start, r.count), ee.geometry.boundingBox === null && (ee.geometry.boundingBox = new lt()), ee.geometry.boundingSphere === null && (ee.geometry.boundingSphere = new he()), this.getMatrixAt(e, ee.matrixWorld).premultiply(this.matrixWorld), this.getBoundingBoxAt(i, ee.geometry.boundingBox), this.getBoundingSphereAt(i, ee.geometry.boundingSphere), ee.raycast(t, We);
    for (let o = 0, l = We.length; o < l; o++) {
      const c = We[o];
      c.object = this, c.batchId = e, s.push(c);
    }
    We.length = 0;
  }
}
function dr(a) {
  return a.r === 1 && a.g === 1 && a.b === 1;
}
function pr(a) {
  a.needsUpdate = !0, a.onBeforeCompile = (e) => {
    e.vertexShader = e.vertexShader.replace(
      "#include <common>",
      /* glsl */
      `
				#include <common>
				varying float texture_index;
				`
    ).replace(
      "#include <uv_vertex>",
      /* glsl */
      `
				#include <uv_vertex>
				texture_index = getIndirectIndex( gl_DrawID );
				`
    ), e.fragmentShader = e.fragmentShader.replace(
      "#include <map_pars_fragment>",
      /* glsl */
      `
				#ifdef USE_MAP
				precision highp sampler2DArray;
				uniform sampler2DArray map;
				varying float texture_index;
				#endif
				`
    ).replace(
      "#include <map_fragment>",
      /* glsl */
      `
				#ifdef USE_MAP
					diffuseColor *= texture( map, vec3( vMapUv, texture_index ) );
				#endif
				`
    );
  };
}
const St = new hn(new Ue()), kt = new Wt(new Uint8Array([255, 255, 255, 255]), 1, 1);
kt.needsUpdate = !0;
class mo {
  constructor(e = {}) {
    if (parseInt(ei) < 170)
      throw new Error("BatchedTilesPlugin: Three.js revision 170 or higher required.");
    e = {
      instanceCount: 500,
      vertexCount: 750,
      indexCount: 2e3,
      expandPercent: 0.25,
      maxInstanceCount: 1 / 0,
      discardOriginalContent: !0,
      textureSize: null,
      material: null,
      renderer: null,
      ...e
    }, this.name = "BATCHED_TILES_PLUGIN", this.priority = -1;
    const t = e.renderer.getContext();
    this.instanceCount = e.instanceCount, this.vertexCount = e.vertexCount, this.indexCount = e.indexCount, this.material = e.material ? e.material.clone() : null, this.expandPercent = e.expandPercent, this.maxInstanceCount = Math.min(e.maxInstanceCount, t.getParameter(t.MAX_3D_TEXTURE_SIZE)), this.renderer = e.renderer, this.discardOriginalContent = e.discardOriginalContent, this.textureSize = e.textureSize, this.batchedMesh = null, this.arrayTarget = null, this.tiles = null, this._onLoadModel = null, this._onDisposeModel = null, this._onVisibilityChange = null, this._tileToInstanceId = /* @__PURE__ */ new Map();
  }
  init(e) {
    this._onDisposeModel = ({ scene: t, tile: s }) => {
      this.removeSceneFromBatchedMesh(t, s);
    }, e.addEventListener("dispose-model", this._onDisposeModel), this.tiles = e;
  }
  initTextureArray(e) {
    if (this.arrayTarget !== null || e.material.map === null)
      return;
    const { instanceCount: t, renderer: s, textureSize: n, batchedMesh: i } = this, r = e.material.map, o = {
      colorSpace: r.colorSpace,
      wrapS: r.wrapS,
      wrapT: r.wrapT,
      wrapR: r.wrapS,
      // TODO: Generating mipmaps for the volume every time a new texture is added is extremely slow
      // generateMipmaps: map.generateMipmaps,
      // minFilter: map.minFilter,
      magFilter: r.magFilter
    }, l = new ss(n || r.image.width, n || r.image.height, t);
    Object.assign(l.texture, o), s.initRenderTarget(l), i.material.map = l.texture, this.arrayTarget = l, this._tileToInstanceId.forEach((c) => {
      c.forEach((u) => {
        this.assignTextureToLayer(kt, u);
      });
    });
  }
  // init the batched mesh if it's not ready
  initBatchedMesh(e) {
    if (this.batchedMesh !== null)
      return;
    const { instanceCount: t, vertexCount: s, indexCount: n, tiles: i } = this, r = this.material ? this.material : new e.material.constructor(), o = new hr(t, t * s, t * n, r);
    o.name = "BatchTilesPlugin", o.frustumCulled = !1, i.group.add(o), o.updateMatrixWorld(), pr(o.material), this.batchedMesh = o;
  }
  setTileVisible(e, t) {
    const s = e.cached.scene;
    if (t && this.addSceneToBatchedMesh(s, e), this._tileToInstanceId.has(e)) {
      this._tileToInstanceId.get(e).forEach((r) => {
        this.batchedMesh.setVisibleAt(r, t);
      });
      const i = this.tiles;
      return t ? i.visibleTiles.add(e) : i.visibleTiles.delete(e), i.dispatchEvent({
        type: "tile-visibility-change",
        scene: s,
        tile: e,
        visible: t
      }), !0;
    }
    return !1;
  }
  unloadTileFromGPU(e, t) {
    return !this.discardOriginalContent && this._tileToInstanceId.has(t) ? (this.removeSceneFromBatchedMesh(e, t), !0) : !1;
  }
  // render the given into the given layer
  assignTextureToLayer(e, t) {
    if (!this.arrayTarget)
      return;
    this.expandArrayTargetIfNeeded();
    const { renderer: s } = this, n = s.getRenderTarget();
    s.setRenderTarget(this.arrayTarget, t), St.material.map = e, St.render(s), s.setRenderTarget(n), St.material.map = null, e.dispose();
  }
  // check if the array texture target needs to be expanded
  expandArrayTargetIfNeeded() {
    const { batchedMesh: e, arrayTarget: t, renderer: s } = this, n = Math.min(e.maxInstanceCount, this.maxInstanceCount);
    if (n > t.depth) {
      const i = {
        colorSpace: t.texture.colorSpace,
        wrapS: t.texture.wrapS,
        wrapT: t.texture.wrapT,
        generateMipmaps: t.texture.generateMipmaps,
        minFilter: t.texture.minFilter,
        magFilter: t.texture.magFilter
      }, r = new ss(t.width, t.height, n);
      Object.assign(r.texture, i), s.initRenderTarget(r), s.copyTextureToTexture(t.texture, r.texture), t.dispose(), e.material.map = r.texture, this.arrayTarget = r;
    }
  }
  removeSceneFromBatchedMesh(e, t) {
    if (this._tileToInstanceId.has(t)) {
      const s = this._tileToInstanceId.get(t);
      this._tileToInstanceId.delete(t), s.forEach((n) => {
        this.batchedMesh.deleteInstance(n);
      });
    }
  }
  addSceneToBatchedMesh(e, t) {
    if (this._tileToInstanceId.has(t))
      return;
    const s = [];
    e.traverse((r) => {
      r.isMesh && s.push(r);
    });
    let n = !0;
    s.forEach((r) => {
      if (this.batchedMesh && n) {
        const o = r.geometry.attributes, l = this.batchedMesh.geometry.attributes;
        for (const c in l)
          if (!(c in o)) {
            n = !1;
            return;
          }
      }
    });
    const i = !this.batchedMesh || this.batchedMesh.instanceCount + s.length <= this.maxInstanceCount;
    if (n && i) {
      e.updateMatrixWorld();
      const r = [];
      this._tileToInstanceId.set(t, r), s.forEach((o) => {
        this.initBatchedMesh(o), this.initTextureArray(o);
        const { geometry: l, material: c } = o, { batchedMesh: u, expandPercent: h } = this;
        u.expandPercent = h;
        const d = u.addGeometry(l, this.vertexCount, this.indexCount), m = u.addInstance(d);
        r.push(m), u.setMatrixAt(m, o.matrixWorld), u.setVisibleAt(m, !1), dr(c.color) || (c.color.setHSL(Math.random(), 0.5, 0.5), u.setColorAt(m, c.color));
        const f = c.map;
        f ? this.assignTextureToLayer(f, m) : this.assignTextureToLayer(kt, m);
      }), this.discardOriginalContent && (t.cached.textures.forEach((o) => {
        o.image instanceof ImageBitmap && o.image.close();
      }), t.cached.scene = null, t.cached.materials = [], t.cached.geometries = [], t.cached.textures = []);
    }
  }
  // Override raycasting per tile to defer to the batched mesh
  raycastTile(e, t, s, n) {
    return this._tileToInstanceId.has(e) ? (this._tileToInstanceId.get(e).forEach((r) => {
      this.batchedMesh.raycastInstance(r, s, n);
    }), !0) : !1;
  }
  dispose() {
    const { arrayTarget: e, tiles: t, batchedMesh: s } = this;
    e && e.dispose(), s && (s.material.dispose(), s.geometry.dispose(), s.dispose(), s.removeFromParent()), t.removeEventListener("dispose-model", this._onDisposeModel);
  }
  getTileBatchIds(e) {
    return this._tileToInstanceId.get(e);
  }
}
const Ct = /* @__PURE__ */ new he(), Xe = /* @__PURE__ */ new E(), we = /* @__PURE__ */ new K(), Ns = /* @__PURE__ */ new K(), At = /* @__PURE__ */ new ti(), fr = /* @__PURE__ */ new Ue({ side: an }), ks = /* @__PURE__ */ new lt(), vt = 1e5;
function Gs(a, e) {
  return a.isBufferGeometry ? (a.boundingSphere === null && a.computeBoundingSphere(), e.copy(a.boundingSphere)) : (ks.setFromObject(a), ks.getBoundingSphere(e), e);
}
class go {
  constructor() {
    this.name = "TILE_FLATTENING_PLUGIN", this.priority = -100, this.tiles = null, this.shapes = /* @__PURE__ */ new Map(), this.positionsMap = /* @__PURE__ */ new Map(), this.positionsUpdated = /* @__PURE__ */ new Set(), this.needsUpdate = !1;
  }
  init(e) {
    this.tiles = e, this.needsUpdate = !0, this._updateBeforeCallback = () => {
      this.needsUpdate && (this._updateTiles(), this.needsUpdate = !1);
    }, this._disposeModelCallback = ({ tile: t }) => {
      this.positionsMap.delete(t), this.positionsUpdated.delete(t);
    }, e.addEventListener("update-before", this._updateBeforeCallback), e.addEventListener("dispose-model", this._disposeModelCallback);
  }
  // update tile flattening state if it has not been made visible, yet
  setTileActive(e, t) {
    t && !this.positionsUpdated.has(e) && this._updateTile(e);
  }
  _updateTile(e) {
    const { positionsUpdated: t, positionsMap: s, shapes: n, tiles: i } = this;
    t.add(e);
    const r = e.cached.scene;
    if (s.has(e)) {
      const o = s.get(e);
      r.traverse((l) => {
        if (l.geometry) {
          const c = o.get(l.geometry);
          c && (l.geometry.attributes.position.array.set(c), l.geometry.attributes.position.needsUpdate = !0);
        }
      });
    } else {
      const o = /* @__PURE__ */ new Map();
      s.set(e, o), r.traverse((l) => {
        l.geometry && o.set(l.geometry, l.geometry.attributes.position.array.slice());
      });
    }
    r.updateMatrixWorld(!0), r.traverse((o) => {
      const { geometry: l } = o;
      l && (we.copy(o.matrixWorld), r.parent !== null && we.premultiply(i.group.matrixWorldInverse), Ns.copy(we).invert(), Gs(l, Ct).applyMatrix4(we), n.forEach(({
        shape: c,
        direction: u,
        sphere: h,
        thresholdMode: d,
        threshold: m,
        flattenRange: f
      }) => {
        Xe.subVectors(Ct.center, h.center), Xe.addScaledVector(u, -u.dot(Xe));
        const p = (Ct.radius + h.radius) ** 2;
        if (Xe.lengthSq() > p)
          return;
        const { position: g } = l.attributes, { ray: y } = At;
        y.direction.copy(u).multiplyScalar(-1);
        for (let x = 0, T = g.count; x < T; x++) {
          y.origin.fromBufferAttribute(g, x).applyMatrix4(we).addScaledVector(u, vt), At.far = vt;
          const _ = At.intersectObject(c)[0];
          if (_) {
            let S = (vt - _.distance) / m;
            const b = S >= 1;
            (!b || b && d === "flatten") && (S = Math.min(S, 1), _.point.addScaledVector(y.direction, M.mapLinear(S, 0, 1, -f, 0)), _.point.applyMatrix4(Ns), g.setXYZ(x, ..._.point));
          }
        }
      }));
    }), this.tiles.dispatchEvent({ type: "needs-render" });
  }
  _updateTiles() {
    this.positionsUpdated.clear(), this.tiles.activeTiles.forEach((e) => this._updateTile(e));
  }
  // API for updating and shapes to flatten the vertices
  hasShape(e) {
    return this.shapes.has(e);
  }
  addShape(e, t = new E(0, 0, -1), s = {}) {
    if (this.hasShape(e))
      throw new Error("TileFlatteningPlugin: Shape is already used.");
    typeof s == "number" && (console.warn('TileFlatteningPlugin: "addShape" function signature has changed. Please use an options object, instead.'), s = {
      threshold: s
    }), this.needsUpdate = !0;
    const n = e.clone();
    n.updateMatrixWorld(!0), n.traverse((r) => {
      r.material && (r.material = fr);
    });
    const i = Gs(n, new he());
    this.shapes.set(e, {
      shape: n,
      direction: t.clone(),
      sphere: i,
      // "flatten": Flattens the vertices above the shape
      // "none": leaves the vertices above the shape as they are
      thresholdMode: "none",
      // only flatten within this range above the object
      threshold: 1 / 0,
      // the range to flatten vertices in to. 0 is completely flat
      // while 0.1 means a 10cm range.
      flattenRange: 0,
      ...s
    });
  }
  updateShape(e) {
    if (!this.hasShape(e))
      throw new Error("TileFlatteningPlugin: Shape is not present.");
    const { direction: t, threshold: s, thresholdMode: n, flattenRange: i } = this.shapes.get(e);
    this.deleteShape(e), this.addShape(e, t, {
      threshold: s,
      thresholdMode: n,
      flattenRange: i
    });
  }
  deleteShape(e) {
    return this.needsUpdate = !0, this.shapes.delete(e);
  }
  clearShapes() {
    this.shapes.size !== 0 && (this.needsUpdate = !0, this.shapes.clear());
  }
  // reset the vertex positions and remove the update callback
  dispose() {
    this.tiles.removeEventListener("before-update", this._updateBeforeCallback), this.tiles.removeEventListener("dispose-model", this._disposeModelCallback), this.positionsMap.forEach((e) => {
      e.forEach((t, s) => {
        const { position: n } = s.attributes;
        n.array.set(t), n.needsUpdate = !0;
      });
    });
  }
}
const mr = /* @__PURE__ */ new si(), gr = /* @__PURE__ */ new Yt();
class yr {
  constructor(e) {
    this.renderer = e, this.renderTarget = null, this.range = [0, 0, 1, 1], this.quad = new Oe(new qt(), new xr());
  }
  // set the target render texture and the range that represents the full span
  setRenderTarget(e, t) {
    this.renderTarget = e, this.range = [...t];
  }
  // draw the given texture at the given span with the provided projection
  draw(e, t) {
    const { range: s, renderer: n, quad: i, renderTarget: r } = this, o = i.material;
    o.map = e, o.minRange.x = M.mapLinear(t[0], s[0], s[2], -1, 1), o.minRange.y = M.mapLinear(t[1], s[1], s[3], -1, 1), o.maxRange.x = M.mapLinear(t[2], s[0], s[2], -1, 1), o.maxRange.y = M.mapLinear(t[3], s[1], s[3], -1, 1);
    const l = n.getRenderTarget(), c = n.autoClear;
    n.autoClear = !1, n.setRenderTarget(r), n.render(i, mr), n.setRenderTarget(l), n.autoClear = c, o.map = null;
  }
  // clear the set target
  clear(e, t = 1) {
    const { renderer: s, renderTarget: n } = this, i = s.getRenderTarget(), r = s.getClearColor(gr), o = s.getClearAlpha();
    s.setClearColor(e, t), s.setRenderTarget(n), s.clear(), s.setRenderTarget(i), s.setClearColor(r, o);
  }
  dispose() {
    this.quad.material.dispose(), this.quad.geometry.dispose();
  }
}
class xr extends rn {
  // the [ - 1, 1 ] NDC ranges to draw the texture at
  get minRange() {
    return this.uniforms.minRange.value;
  }
  get maxRange() {
    return this.uniforms.maxRange.value;
  }
  // access the map being drawn
  get map() {
    return this.uniforms.map.value;
  }
  set map(e) {
    this.uniforms.map.value = e;
  }
  constructor() {
    super({
      depthWrite: !1,
      depthTest: !1,
      transparent: !1,
      side: an,
      premultipliedAlpha: !0,
      uniforms: {
        map: { value: null },
        // the normalized [0, 1] range of the target to draw to
        minRange: { value: new q() },
        maxRange: { value: new q() }
      },
      vertexShader: (
        /* glsl */
        `

				uniform vec2 minRange;
				uniform vec2 maxRange;
				varying vec2 vUv;

				void main() {

					vUv = uv;
					gl_Position = vec4( mix( minRange, maxRange, uv ), 0, 1 );

				}

			`
      ),
      fragmentShader: (
        /* glsl */
        `

				uniform sampler2D map;
				uniform vec2 minRange;
				uniform vec2 maxRange;
				varying vec2 vUv;

				void main() {

					// sample the texture
					gl_FragColor = texture( map, vUv );
					#include <premultiplied_alpha_fragment>

				}

			`
      )
    });
  }
}
class Tr extends Fe {
  constructor(e = {}) {
    const {
      subdomains: t = ["t0"],
      ...s
    } = e;
    super(s), this.subdomains = t, this.subDomainIndex = 0;
  }
  getUrl(e, t, s) {
    return this.url.replace(/{\s*subdomain\s*}/gi, this._getSubdomain()).replace(/{\s*quadkey\s*}/gi, this._tileToQuadKey(e, t, s));
  }
  _tileToQuadKey(e, t, s) {
    let n = "";
    for (let i = s; i > 0; i--) {
      let r = 0;
      const o = 1 << i - 1;
      (e & o) !== 0 && (r += 1), (t & o) !== 0 && (r += 2), n += r.toString();
    }
    return n;
  }
  _getSubdomain() {
    return this.subDomainIndex = (this.subDomainIndex + 1) % this.subdomains.length, this.subdomains[this.subDomainIndex];
  }
}
function it(a, e, t, s) {
  let [n, i, r, o] = a;
  i += 1e-8, n += 1e-8, o -= 1e-8, r -= 1e-8;
  const l = Math.max(Math.min(e, t.maxLevel), t.minLevel), [c, u, h, d] = t.getTilesInRange(n, i, r, o, l, !0);
  for (let m = c; m <= h; m++)
    for (let f = u; f <= d; f++)
      s(m, f, l);
}
function br(a, e, t) {
  const s = new E(), n = {}, i = [], r = a.getAttribute("position");
  a.computeBoundingBox(), a.boundingBox.getCenter(s).applyMatrix4(e), t.getPositionToCartographic(s, n);
  const o = n.lat, l = n.lon;
  let c = 1 / 0, u = 1 / 0, h = 1 / 0, d = -1 / 0, m = -1 / 0, f = -1 / 0;
  for (let y = 0; y < r.count; y++)
    s.fromBufferAttribute(r, y).applyMatrix4(e), t.getPositionToCartographic(s, n), Math.abs(Math.abs(n.lat) - Math.PI / 2) < 1e-5 && (n.lon = l), Math.abs(l - n.lon) > Math.PI && (n.lon += Math.sign(l - n.lon) * Math.PI * 2), Math.abs(o - n.lat) > Math.PI && (n.lat += Math.sign(o - n.lat) * Math.PI * 2), i.push(n.lon, n.lat, n.height), c = Math.min(c, n.lat), d = Math.max(d, n.lat), u = Math.min(u, n.lon), m = Math.max(m, n.lon), h = Math.min(h, n.height), f = Math.max(f, n.height);
  const p = [u, c, m, d], g = [...p, h, f];
  return {
    uv: i,
    range: p,
    region: g
  };
}
function js(a, e, t = null, s = null) {
  let n = 1 / 0, i = 1 / 0, r = 1 / 0, o = -1 / 0, l = -1 / 0, c = -1 / 0;
  const u = [], h = new K();
  a.forEach((m) => {
    h.copy(m.matrixWorld), t && h.premultiply(t);
    const { uv: f, region: p } = br(m.geometry, h, e);
    u.push(f), n = Math.min(n, p[1]), o = Math.max(o, p[3]), i = Math.min(i, p[0]), l = Math.max(l, p[2]), r = Math.min(r, p[4]), c = Math.max(c, p[5]);
  });
  let d = [i, n, l, o];
  if (s !== null) {
    d = s.clampToProjectionBounds([i, n, l, o]);
    const [m, f, p, g] = s.toNormalizedRange(d);
    u.forEach((y) => {
      for (let x = 0, T = y.length; x < T; x += 3) {
        const _ = y[x + 0], S = y[x + 1], b = y[x + 2], [C, A] = s.toNormalizedPoint(_, S);
        y[x + 0] = M.mapLinear(C, m, p, 0, 1), y[x + 1] = M.mapLinear(A, f, g, 0, 1), y[x + 2] = M.mapLinear(b, r, c, 0, 1);
      }
    });
  }
  return {
    uvs: u,
    range: d,
    region: [i, n, l, o, r, c]
  };
}
function _r(a, e, t) {
  const s = new E(), n = [], i = a.getAttribute("position");
  let r = 1 / 0, o = 1 / 0, l = 1 / 0, c = -1 / 0, u = -1 / 0, h = -1 / 0;
  for (let m = 0; m < i.count; m++)
    s.fromBufferAttribute(i, m).applyMatrix4(e), s.x /= t, n.push(s.x, s.y, s.z), r = Math.min(r, s.x), c = Math.max(c, s.x), o = Math.min(o, s.y), u = Math.max(u, s.y), l = Math.min(l, s.z), h = Math.max(h, s.z);
  return {
    uv: n,
    range: [r, o, c, u],
    heightRange: [l, h]
  };
}
function Mr(a, e, t) {
  let s = 1 / 0, n = 1 / 0, i = 1 / 0, r = -1 / 0, o = -1 / 0, l = -1 / 0;
  const c = [], u = new K();
  return a.forEach((h) => {
    u.copy(h.matrixWorld), e && u.premultiply(e);
    const { uv: d, range: m, heightRange: f } = _r(h.geometry, u, t.aspectRatio);
    c.push(d), s = Math.min(s, m[0]), r = Math.max(r, m[2]), n = Math.min(n, m[1]), o = Math.max(o, m[3]), i = Math.min(i, f[0]), l = Math.max(l, f[1]);
  }), c.forEach((h) => {
    for (let d = 0, m = h.length; d < m; d += 3) {
      const f = h[d + 0], p = h[d + 1];
      h[d + 0] = M.mapLinear(f, s, r, 0, 1), h[d + 1] = M.mapLinear(p, n, o, 0, 1);
    }
  }), {
    uvs: c,
    range: [s, n, r, o],
    heightRange: [i, l]
  };
}
const Lt = Symbol("OVERLAY_PARAMS");
function Sr(a, e) {
  if (a[Lt])
    return a[Lt];
  const t = {
    layerMaps: { value: [] },
    layerInfo: { value: [] }
  };
  return a[Lt] = t, a.defines = {
    ...a.defines || {},
    LAYER_COUNT: 0
  }, a.onBeforeCompile = (s) => {
    e && e(s), s.uniforms = {
      ...s.uniforms,
      ...t
    }, s.vertexShader = s.vertexShader.replace(/void main\(\s*\)\s*{/, (n) => (
      /* glsl */
      `

				#pragma unroll_loop_start
					for ( int i = 0; i < 10; i ++ ) {

						#if UNROLLED_LOOP_INDEX < LAYER_COUNT

							attribute vec3 layer_uv_UNROLLED_LOOP_INDEX;
							varying vec3 v_layer_uv_UNROLLED_LOOP_INDEX;

						#endif


					}
				#pragma unroll_loop_end

				${n}

				#pragma unroll_loop_start
					for ( int i = 0; i < 10; i ++ ) {

						#if UNROLLED_LOOP_INDEX < LAYER_COUNT

							v_layer_uv_UNROLLED_LOOP_INDEX = layer_uv_UNROLLED_LOOP_INDEX;

						#endif

					}
				#pragma unroll_loop_end

			`
    )), s.fragmentShader = s.fragmentShader.replace(/void main\(/, (n) => (
      /* glsl */
      `

				#if LAYER_COUNT != 0
					struct LayerInfo {
						vec3 color;
						float opacity;

						int alphaMask;
						int alphaInvert;
					};

					uniform sampler2D layerMaps[ LAYER_COUNT ];
					uniform LayerInfo layerInfo[ LAYER_COUNT ];
				#endif

				#pragma unroll_loop_start
					for ( int i = 0; i < 10; i ++ ) {

						#if UNROLLED_LOOP_INDEX < LAYER_COUNT

							varying vec3 v_layer_uv_UNROLLED_LOOP_INDEX;

						#endif

					}
				#pragma unroll_loop_end

				${n}

			`
    )).replace(/#include <color_fragment>/, (n) => (
      /* glsl */
      `

				${n}

				#if LAYER_COUNT != 0
				{
					vec4 tint;
					vec3 layerUV;
					float layerOpacity;
					float wOpacity;
					float wDelta;
					#pragma unroll_loop_start
						for ( int i = 0; i < 10; i ++ ) {

							#if UNROLLED_LOOP_INDEX < LAYER_COUNT

								layerUV = v_layer_uv_UNROLLED_LOOP_INDEX;
								tint = texture( layerMaps[ i ], layerUV.xy );

								// discard texture outside 0, 1 on w - offset the stepped value by an epsilon to avoid cases
								// where wDelta is near 0 (eg a flat surface) at the w boundary, resulting in artifacts on some
								// hardware.
								wDelta = max( fwidth( layerUV.z ), 1e-7 );
								wOpacity =
									smoothstep( - wDelta, 0.0, layerUV.z ) *
									smoothstep( 1.0 + wDelta, 1.0, layerUV.z );

								// apply tint & opacity
								tint.rgb *= layerInfo[ i ].color;
								tint.rgba *= layerInfo[ i ].opacity * wOpacity;

								// invert the alpha
								if ( layerInfo[ i ].alphaInvert > 0 ) {

									tint.a = 1.0 - tint.a;

								}

								// apply the alpha across all existing layers if alpha mask is true
								if ( layerInfo[ i ].alphaMask > 0 ) {

									diffuseColor.a *= tint.a;

								} else {

									// premultiplied alpha equation
									diffuseColor = tint + diffuseColor * ( 1.0 - tint.a );

								}

							#endif

						}
					#pragma unroll_loop_end
				}
				#endif
			`
    ));
  }, t;
}
const It = /* @__PURE__ */ new E(), Ye = /* @__PURE__ */ new E();
function Cr(a, e, t) {
  a.getCartographicToPosition(e, t, 0, It), a.getCartographicToPosition(e + 0.01, t, 0, Ye);
  const n = It.distanceTo(Ye);
  return a.getCartographicToPosition(e, t + 0.01, 0, Ye), It.distanceTo(Ye) / n;
}
class Ar extends Ae {
  constructor({
    geojson: e = null,
    url: t = null,
    // URL or GeoJson object can be provided
    tileDimension: s = 256,
    levels: n = 20,
    pointRadius: i = 6,
    strokeStyle: r = "white",
    strokeWidth: o = 2,
    fillStyle: l = "rgba( 255, 255, 255, 0.5 )",
    ...c
  } = {}) {
    super(c), this.geojson = e, this.url = t, this.tileDimension = s, this.levels = n, this.pointRadius = i, this.strokeStyle = r, this.strokeWidth = o, this.fillStyle = l;
  }
  async init() {
    const { tiling: e, levels: t, tileDimension: s, geojson: n, url: i } = this, r = new de();
    if (e.setProjection(r), e.setContentBounds(...r.getBounds()), e.generateLevels(
      t,
      r.tileCountX,
      r.tileCountY,
      {
        tilePixelWidth: s,
        tilePixelHeight: s
      }
    ), !n && i) {
      const l = await this.fetchData(i);
      this.geojson = await l.json();
    }
    const o = this._geoJSONBounds(50).map((l) => l * M.DEG2RAD);
    this.tiling.setContentBounds(...o);
  }
  // main fetch per tile - > returns .Texture
  async fetchItem(e, t) {
    return this.drawCanvasImage(e);
  }
  drawCanvasImage(e) {
    const { tiling: t, tileDimension: s, geojson: n } = this, [i, r, o] = e, l = t.getTileBounds(i, r, o, !1, !1).map((m) => M.RAD2DEG * m), c = document.createElement("canvas");
    c.width = s, c.height = s;
    const u = c.getContext("2d"), h = this._featuresFromGeoJSON(n);
    for (let m = 0; m < h.length; m++) {
      const f = h[m];
      this._featureIntersectsTile(f, l) && this._drawFeatureOnCanvas(u, f, l, c.width, c.height);
    }
    const d = new ln(c);
    return d.needsUpdate = !0, d;
  }
  // bbox quick test in projected units
  _featureIntersectsTile(e, t) {
    const s = this._getFeatureBounds(e);
    if (!s)
      return !1;
    const [n, i, r, o] = s, [l, c, u, h] = t;
    return !(r < l || n > u || o < c || i > h);
  }
  _getFeatureBounds(e) {
    const { geometry: t } = e;
    if (!t)
      return null;
    const { type: s, coordinates: n } = t;
    let i = 1 / 0, r = 1 / 0, o = -1 / 0, l = -1 / 0;
    const c = (u, h) => {
      i = Math.min(i, u), o = Math.max(o, u), r = Math.min(r, h), l = Math.max(l, h);
    };
    return s === "Point" ? c(n[0], n[1]) : s === "MultiPoint" || s === "LineString" ? n.forEach((u) => c(u[0], u[1])) : s === "MultiLineString" || s === "Polygon" ? n.forEach((u) => u.forEach((h) => c(h[0], h[1]))) : s === "MultiPolygon" && n.forEach(
      (u) => u.forEach((h) => h.forEach((d) => c(d[0], d[1])))
    ), [i, r, o, l];
  }
  // Normalize top-level geojson into an array of Feature objects
  _featuresFromGeoJSON(e) {
    const t = e.type, s = /* @__PURE__ */ new Set(["Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon"]);
    return t === "FeatureCollection" ? e.features : t === "Feature" ? [e] : t === "GeometryCollection" ? e.geometries.map((n) => ({ type: "Feature", geometry: n, properties: {} })) : s.has(t) ? [{ type: "Feature", geometry: e, properties: {} }] : [];
  }
  // draw feature on canvas ( assumes intersects already )
  _drawFeatureOnCanvas(e, t, s, n, i) {
    const { geometry: r = null, properties: o = {} } = t;
    if (!r)
      return;
    const [l, c, u, h] = s, d = o.strokeStyle || this.strokeStyle, m = o.fillStyle || this.fillStyle, f = o.pointRadius || this.pointRadius, p = o.strokeWidth || this.strokeWidth;
    e.save(), e.strokeStyle = d, e.fillStyle = m, e.lineWidth = p;
    const g = new Array(2), y = (_, S, b = g) => {
      const C = M.mapLinear(_, l, u, 0, n), A = i - M.mapLinear(S, c, h, 0, i);
      return b[0] = Math.round(C), b[1] = Math.round(A), b;
    }, x = (_, S) => {
      const b = S * M.DEG2RAD, C = _ * M.DEG2RAD, A = (h - c) / i;
      return (u - l) / n / A * Cr(ui, b, C);
    }, T = r.type;
    if (T === "Point") {
      const [_, S] = r.coordinates, [b, C] = y(_, S), A = x(_, S);
      e.beginPath(), e.ellipse(b, C, f / A, f, 0, 0, Math.PI * 2), e.fill(), e.stroke();
    } else T === "MultiPoint" ? r.coordinates.forEach(([_, S]) => {
      const [b, C] = y(_, S), A = x(_, S);
      e.beginPath(), e.ellipse(b, C, f / A, f, 0, 0, Math.PI * 2), e.fill(), e.stroke();
    }) : T === "LineString" ? (e.beginPath(), r.coordinates.forEach(([_, S], b) => {
      const [C, A] = y(_, S);
      b === 0 ? e.moveTo(C, A) : e.lineTo(C, A);
    }), e.stroke()) : T === "MultiLineString" ? (e.beginPath(), r.coordinates.forEach((_) => {
      _.forEach(([S, b], C) => {
        const [A, w] = y(S, b);
        C === 0 ? e.moveTo(A, w) : e.lineTo(A, w);
      });
    }), e.stroke()) : T === "Polygon" ? (e.beginPath(), r.coordinates.forEach((_, S) => {
      _.forEach(([b, C], A) => {
        const [w, P] = y(b, C);
        A === 0 ? e.moveTo(w, P) : e.lineTo(w, P);
      }), e.closePath();
    }), e.fill("evenodd"), e.stroke()) : T === "MultiPolygon" && r.coordinates.forEach((_) => {
      e.beginPath(), _.forEach((S, b) => {
        S.forEach(([C, A], w) => {
          const [P, U] = y(C, A);
          w === 0 ? e.moveTo(P, U) : e.lineTo(P, U);
        }), e.closePath();
      }), e.fill("evenodd"), e.stroke();
    });
    e.restore();
  }
  // Compute geographic bounds in degrees from current geojson.
  _geoJSONBounds() {
    const e = this._featuresFromGeoJSON(this.geojson);
    let t = 1 / 0, s = 1 / 0, n = -1 / 0, i = -1 / 0;
    return e.forEach((r) => {
      const [o, l, c, u] = this._getFeatureBounds(r);
      t = Math.min(t, o), s = Math.min(s, l), n = Math.max(n, c), i = Math.max(i, u);
    }), [t, s, n, i];
  }
}
const Se = /* @__PURE__ */ new K(), $e = /* @__PURE__ */ new E(), Et = /* @__PURE__ */ new E(), wt = /* @__PURE__ */ new E(), se = /* @__PURE__ */ new E(), vr = /* @__PURE__ */ new lt(), zs = Symbol("SPLIT_TILE_DATA"), Qe = Symbol("SPLIT_HASH");
function ye(a, e, t, s) {
  if (Array.isArray(t)) {
    const i = t.map((r) => ye(a, e, r, s)).filter((r) => r !== null);
    return i.length === 0 ? null : Promise.all(i);
  }
  if (t.isReady)
    return n();
  return t.whenReady().then(n);
  function n() {
    const i = [], { imageSource: r, tiling: o } = t;
    it(a, e, o, (c, u, h) => {
      s ? r.release(c, u, h) : i.push(r.lock(c, u, h));
    });
    const l = i.filter((c) => c instanceof Promise);
    return l.length !== 0 ? Promise.all(l) : null;
  }
}
function Lr(a, e, t) {
  let s = 0;
  return it(a, e, t.tiling, (n, i, r) => {
    s++;
  }), s;
}
class yo {
  get enableTileSplitting() {
    return this._enableTileSplitting;
  }
  set enableTileSplitting(e) {
    this._enableTileSplitting !== e && (this._enableTileSplitting = e, this._markNeedsUpdate());
  }
  constructor(e = {}) {
    const {
      overlays: t = [],
      resolution: s = 256,
      renderer: n = null,
      enableTileSplitting: i = !0
    } = e;
    this.name = "IMAGE_OVERLAY_PLUGIN", this.priority = -15, this.renderer = n, this.resolution = s, this._enableTileSplitting = i, this.overlays = [], this.needsUpdate = !1, this.tiles = null, this.tileComposer = null, this.tileControllers = /* @__PURE__ */ new Map(), this.overlayInfo = /* @__PURE__ */ new Map(), this.usedTextures = /* @__PURE__ */ new Set(), this.meshParams = /* @__PURE__ */ new WeakMap(), this.pendingTiles = /* @__PURE__ */ new Map(), this.processedTiles = /* @__PURE__ */ new Set(), this.processQueue = null, this._onUpdateAfter = null, this._onTileDownloadStart = null, this._cleanupScheduled = !1, this._virtualChildResetId = 0, this._bytesUsed = /* @__PURE__ */ new WeakMap(), t.forEach((r) => {
      this.addOverlay(r);
    });
  }
  // plugin functions
  init(e) {
    if (!this.renderer)
      throw new Error('ImageOverlayPlugin: "renderer" instance must be provided.');
    const t = new yr(this.renderer), s = new gi();
    s.maxJobs = 10, s.priorityCallback = (n, i) => {
      const r = n.tile, o = i.tile, l = e.visibleTiles.has(r), c = e.visibleTiles.has(o);
      return l !== c ? l ? 1 : -1 : e.downloadQueue.priorityCallback(r, o);
    }, this.tiles = e, this.tileComposer = t, this.processQueue = s, e.forEachLoadedModel((n, i) => {
      this._processTileModel(n, i, !0);
    }), this._onUpdateAfter = async () => {
      let n = !1;
      if (this.overlayInfo.forEach((i, r) => {
        if (!!r.frame != !!i.frame || r.frame && i.frame && !i.frame.equals(r.frame)) {
          const o = i.order;
          this.deleteOverlay(r), this.addOverlay(r, o), n = !0;
        }
      }), n) {
        const i = s.maxJobs;
        let r = 0;
        s.items.forEach((o) => {
          e.visibleTiles.has(o.tile) && r++;
        }), s.maxJobs = r + s.currJobs, s.tryRunJobs(), s.maxJobs = i, this.needsUpdate = !0;
      }
      if (this.needsUpdate) {
        this.needsUpdate = !1;
        const { overlays: i, overlayInfo: r } = this;
        i.sort((o, l) => r.get(o).order - r.get(l).order), e.forEachLoadedModel((o, l) => {
          this._updateLayers(l);
        }), this.resetVirtualChildren(!this.enableTileSplitting), e.recalculateBytesUsed(), e.dispatchEvent({ type: "needs-rerender" });
      }
    }, this._onTileDownloadStart = ({ tile: n, url: i }) => {
      !/\.json$/i.test(i) && !/\.subtree/i.test(i) && (this.processedTiles.add(n), this._initTileOverlayInfo(n));
    }, e.addEventListener("update-after", this._onUpdateAfter), e.addEventListener("tile-download-start", this._onTileDownloadStart), this.overlays.forEach((n) => {
      this._initOverlay(n);
    });
  }
  disposeTile(e) {
    const { overlayInfo: t, tileControllers: s, processQueue: n, pendingTiles: i, processedTiles: r } = this;
    r.delete(e), s.has(e) && (s.get(e).abort(), s.delete(e), i.delete(e)), t.forEach((({ tileInfo: o }, l) => {
      if (o.has(e)) {
        const { meshInfo: c, range: u, meshRange: h, level: d, target: m, meshRangeMarked: f, rangeMarked: p } = o.get(e);
        h !== null && f && ye(h, d, l, !0), u !== null && p && ye(u, d, l, !0), m !== null && m.dispose(), o.delete(e), c.clear();
      }
    })), n.removeByFilter((o) => o.tile === e);
  }
  calculateBytesUsed(e) {
    const { overlayInfo: t } = this, s = this._bytesUsed;
    let n = null;
    return t.forEach(({ tileInfo: i }, r) => {
      if (i.has(e)) {
        const { target: o } = i.get(e);
        n = n || 0, n += hi(o == null ? void 0 : o.texture);
      }
    }), n !== null ? (s.set(e, n), n) : s.has(e) ? s.get(e) : 0;
  }
  processTileModel(e, t) {
    return this._processTileModel(e, t);
  }
  async _processTileModel(e, t, s = !1) {
    const { tileControllers: n, processedTiles: i, pendingTiles: r } = this;
    n.set(t, new AbortController()), s || r.set(t, e), i.add(t), this._wrapMaterials(e), this._initTileOverlayInfo(t), await this._initTileSceneOverlayInfo(e, t), this.expandVirtualChildren(e, t), this._updateLayers(t), r.delete(t);
  }
  dispose() {
    const { tileComposer: e, tiles: t } = this;
    e.dispose(), [...this.overlays].forEach((n) => {
      this.deleteOverlay(n);
    }), t.forEachLoadedModel((n, i) => {
      this._updateLayers(i), this.disposeTile(i), delete i[Qe];
    }), t.removeEventListener("update-after", this._onUpdateAfter), this.resetVirtualChildren(!0);
  }
  getAttributions(e) {
    this.overlays.forEach((t) => {
      t.opacity > 0 && t.getAttributions(e);
    });
  }
  parseToMesh(e, t, s, n) {
    if (s === "image_overlay_tile_split")
      return t[zs];
  }
  async resetVirtualChildren(e = !1) {
    this._virtualChildResetId++;
    const t = this._virtualChildResetId;
    if (await Promise.all(this.overlays.map((r) => r.whenReady())), t !== this._virtualChildResetId)
      return;
    const { tiles: s } = this, n = /* @__PURE__ */ new Set();
    s.forEachLoadedModel((r, o) => {
      Qe in o && n.add(o);
    }), n.forEach((r) => {
      if (r.parent === null)
        return;
      const o = r.cached.scene.clone();
      o.updateMatrixWorld();
      const { hash: l } = this._getSplitVectors(o, r);
      if (r[Qe] !== l || e) {
        const c = i(r);
        c.sort((u, h) => (h.__depth || 0) - (u.__depth || 0)), c.forEach((u) => {
          s.processNodeQueue.remove(u), s.lruCache.remove(u), u.parent = null;
        }), r.children.length = 0, r.__childrenProcessed = 0;
      }
    }), e || s.forEachLoadedModel((r, o) => {
      this.expandVirtualChildren(r, o);
    });
    function i(r, o = []) {
      return r.children.forEach((l) => {
        o.push(l), i(l, o);
      }), o;
    }
  }
  _getSplitVectors(e, t, s = Et) {
    const { tiles: n, overlayInfo: i } = this, r = new lt();
    r.setFromObject(e), r.getCenter(s);
    const o = [], l = [];
    i.forEach(({ tileInfo: u }, h) => {
      const d = u.get(t);
      if (d && d.target && h.tiling.maxLevel > d.level) {
        h.frame ? se.set(0, 0, 1).transformDirection(h.frame) : (n.ellipsoid.getPositionToNormal(s, se), se.length() < 1e-6 && se.set(1, 0, 0));
        const m = `${se.x.toFixed(3)},${se.y.toFixed(3)},${se.z.toFixed(3)}_`;
        l.includes(m) || l.push(m);
        const f = $e.set(0, 0, 1);
        Math.abs(se.dot(f)) > 1 - 1e-4 && f.set(1, 0, 0);
        const p = new E().crossVectors(se, f).normalize(), g = new E().crossVectors(se, p).normalize();
        o.push(p, g);
      }
    });
    const c = [];
    for (; o.length !== 0; ) {
      const u = o.pop().clone(), h = u.clone();
      for (let d = 0; d < o.length; d++) {
        const m = o[d], f = u.dot(m);
        Math.abs(f) > Math.cos(Math.PI / 8) && (h.addScaledVector(m, Math.sign(f)), u.copy(h).normalize(), o.splice(d, 1), d--);
      }
      c.push(h.normalize());
    }
    return { directions: c, hash: l.join("") };
  }
  async expandVirtualChildren(e, t) {
    if (t.children.length !== 0 || this.enableTileSplitting === !1)
      return;
    const s = e.clone();
    s.updateMatrixWorld();
    const { directions: n, hash: i } = this._getSplitVectors(s, t, Et);
    if (t[Qe] = i, n.length === 0)
      return;
    const r = new xn();
    r.attributeList = (l) => !/^layer_uv_\d+/.test(l), n.map((l) => {
      r.addSplitOperation((c, u, h, d, m, f) => (Xt.getInterpolatedAttribute(c.attributes.position, u, h, d, m, $e), $e.applyMatrix4(f).sub(Et).dot(l)));
    });
    const o = [];
    r.forEachSplitPermutation(() => {
      const l = r.clipObject(s);
      l.matrix.premultiply(t.cached.transformInverse).decompose(l.position, l.quaternion, l.scale);
      const c = [];
      if (l.traverse((h) => {
        if (h.isMesh) {
          const d = h.material.clone();
          h.material = d;
          for (const m in d) {
            const f = d[m];
            if (f && f.isTexture && f.source.data instanceof ImageBitmap) {
              const p = document.createElement("canvas");
              p.width = f.image.width, p.height = f.image.height;
              const g = p.getContext("2d");
              g.scale(1, -1), g.drawImage(f.source.data, 0, 0, p.width, -p.height);
              const y = new ln(p);
              y.mapping = f.mapping, y.wrapS = f.wrapS, y.wrapT = f.wrapT, y.minFilter = f.minFilter, y.magFilter = f.magFilter, y.format = f.format, y.type = f.type, y.anisotropy = f.anisotropy, y.colorSpace = f.colorSpace, y.generateMipmaps = f.generateMipmaps, d[m] = y;
            }
          }
          c.push(h);
        }
      }), c.length === 0)
        return;
      const u = {};
      if (t.boundingVolume.region && (u.region = js(c, this.tiles.ellipsoid).region), t.boundingVolume.box || t.boundingVolume.sphere) {
        vr.setFromObject(l, !0).getCenter(wt);
        let h = 0;
        l.traverse((d) => {
          const m = d.geometry;
          if (m) {
            const f = m.attributes.position;
            for (let p = 0, g = f.count; p < g; p++) {
              const y = $e.fromBufferAttribute(f, p).applyMatrix4(d.matrixWorld).distanceToSquared(wt);
              h = Math.max(h, y);
            }
          }
        }), u.sphere = [...wt, Math.sqrt(h)];
      }
      o.push({
        refine: "REPLACE",
        geometricError: t.geometricError * 0.5,
        boundingVolume: u,
        content: { uri: "./child.image_overlay_tile_split" },
        children: [],
        [zs]: l
      });
    }), t.refine = "REPLACE", t.children.push(...o);
  }
  fetchData(e, t) {
    if (/image_overlay_tile_split/.test(e))
      return new ArrayBuffer();
  }
  // public
  addOverlay(e, t = null) {
    const { tiles: s, overlays: n, overlayInfo: i } = this;
    t === null && (t = n.reduce((o, l) => Math.max(o, l.order + 1), 0));
    const r = new AbortController();
    n.push(e), i.set(e, {
      order: t,
      uniforms: {},
      tileInfo: /* @__PURE__ */ new Map(),
      controller: r,
      frame: e.frame ? e.frame.clone() : null
    }), s !== null && this._initOverlay(e);
  }
  setOverlayOrder(e, t) {
    this.overlays.indexOf(e) !== -1 && (this.overlayInfo.get(e).order = t, this._markNeedsUpdate());
  }
  deleteOverlay(e) {
    const { overlays: t, overlayInfo: s, processQueue: n, processedTiles: i } = this, r = t.indexOf(e);
    if (r !== -1) {
      const { tileInfo: o, controller: l } = s.get(e);
      i.forEach((c) => {
        if (!o.has(c))
          return;
        const {
          meshInfo: u,
          range: h,
          meshRange: d,
          level: m,
          target: f,
          meshRangeMarked: p,
          rangeMarked: g
        } = o.get(c);
        d !== null && p && ye(d, m, e, !0), h !== null && g && ye(h, m, e, !0), f !== null && f.dispose(), o.delete(c), u.clear();
      }), o.clear(), s.delete(e), l.abort(), n.removeByFilter((c) => c.overlay === e), t.splice(r, 1), this._markNeedsUpdate();
    }
  }
  // internal
  _calculateLevelFromOverlay(e, t, s) {
    if (e.isPlanarProjection) {
      const { resolution: n } = this, { tiling: i } = e, [r, o, l, c] = t, u = l - r, h = c - o;
      let d = 0;
      const { maxLevel: m } = i;
      for (; d < m; d++) {
        const f = n / u, p = n / h, { pixelWidth: g, pixelHeight: y } = i.getLevel(d);
        if (g >= f || y >= p)
          break;
      }
      return d;
    } else
      return s.__depthFromRenderedParent - 1;
  }
  // initialize the overlay to use the right fetch options, load all data for existing tiles
  _initOverlay(e) {
    const { tiles: t } = this;
    e.isInitialized || (e.init(), e.whenReady().then(() => {
      e.imageSource.fetchData = (...i) => t.downloadQueue.add({ priority: -performance.now() }, () => e.fetch(...i));
    }));
    const s = [], n = async (i, r) => {
      this._initTileOverlayInfo(r, e);
      const o = this._initTileSceneOverlayInfo(i, r, e);
      s.push(o), await o, this._updateLayers(r);
    };
    t.forEachLoadedModel(n), this.pendingTiles.forEach((i, r) => {
      n(i, r);
    }), Promise.all(s).then(() => {
      this._markNeedsUpdate();
    });
  }
  // wrap all materials in the given scene wit the overlay material shader
  _wrapMaterials(e) {
    e.traverse((t) => {
      if (t.material) {
        const s = Sr(t.material, t.material.onBeforeCompile);
        this.meshParams.set(t, s);
      }
    });
  }
  // Initialize per-tile overlay information. This function triggers an async function but
  // does not need to be awaited for use since it's just locking textures which are awaited later.
  _initTileOverlayInfo(e, t = this.overlays) {
    if (Array.isArray(t)) {
      t.forEach((r) => this._initTileOverlayInfo(e, r));
      return;
    }
    const { overlayInfo: s, processQueue: n } = this;
    if (s.get(t).tileInfo.has(e))
      return;
    const i = {
      range: null,
      meshRange: null,
      level: null,
      target: null,
      meshInfo: /* @__PURE__ */ new Map(),
      rangeMarked: !1,
      meshRangeMarked: !1
    };
    if (s.get(t).tileInfo.set(e, i), t.isReady && !t.isPlanarProjection) {
      if (e.boundingVolume.region) {
        const [r, o, l, c] = e.boundingVolume.region, u = t.tiling.toNormalizedRange([r, o, l, c]);
        i.range = u, i.level = this._calculateLevelFromOverlay(t, u, e), n.add({ tile: e, overlay: t }, () => (i.rangeMarked = !0, ye(u, i.level, t, !1))).catch((h) => {
          if (!(h instanceof ns))
            throw h;
        });
      }
    }
  }
  // initialize the scene meshes
  async _initTileSceneOverlayInfo(e, t, s = this.overlays) {
    if (Array.isArray(s))
      return Promise.all(s.map((C) => this._initTileSceneOverlayInfo(e, t, C)));
    const { tiles: n, overlayInfo: i, resolution: r, tileComposer: o, tileControllers: l, usedTextures: c, processQueue: u } = this, { ellipsoid: h } = n, { controller: d, tileInfo: m } = i.get(s), f = l.get(t);
    if (s.isReady || await s.whenReady(), d.signal.aborted || f.signal.aborted)
      return;
    const p = [];
    e.updateMatrixWorld(), e.traverse((C) => {
      C.isMesh && p.push(C);
    });
    const { tiling: g, imageSource: y } = s, x = m.get(t);
    let T, _, S;
    if (s.isPlanarProjection) {
      Se.copy(s.frame), e.parent !== null && Se.multiply(n.group.matrixWorldInverse);
      let C;
      ({ range: T, uvs: _, heightRange: C } = Mr(p, Se, g)), S = !(C[0] > 1 || C[1] < 0);
    } else
      Se.identity(), e.parent !== null && Se.copy(n.group.matrixWorldInverse), { range: T, uvs: _ } = js(p, h, Se, g), T = g.toNormalizedRange(T), S = !0;
    x.level === null && (x.level = this._calculateLevelFromOverlay(s, T, t));
    let b = null;
    S && Lr(T, x.level, s) !== 0 && (b = new Ft(r, r, {
      depthBuffer: !1,
      stencilBuffer: !1,
      generateMipmaps: !1,
      colorSpace: Ks
    })), x.meshRange = T, x.target = b, p.forEach((C, A) => {
      const w = new Float32Array(_[A]), P = new J(w, 3);
      x.meshInfo.set(C, { attribute: P });
    }), b !== null && await u.add({ tile: t, overlay: s }, async () => {
      x.meshRangeMarked = !0;
      const C = ye(T, x.level, s, !1);
      if (C) {
        o.setRenderTarget(b, T), o.clear(16777215, 0), it(T, x.level - 1, g, (A, w, P) => {
          const U = g.getTileBounds(A, w, P, !0, !1), B = y.get(A, w, P);
          B && !(B instanceof Promise) && (o.draw(B, U), c.add(B), this._scheduleCleanup());
        });
        try {
          await C;
        } catch {
          return;
        }
      }
      d.signal.aborted || f.signal.aborted || (o.setRenderTarget(b, T), o.clear(16777215, 0), it(T, x.level, g, (A, w, P) => {
        const U = g.getTileBounds(A, w, P, !0, !1), B = y.get(A, w, P);
        o.draw(B, U), c.add(B), this._scheduleCleanup();
      }));
    }).catch((C) => {
      if (!(C instanceof ns))
        throw C;
    });
  }
  _updateLayers(e) {
    const { overlayInfo: t, overlays: s, tileControllers: n } = this, i = n.get(e);
    this.tiles.recalculateBytesUsed(e), !(!i || i.signal.aborted) && s.forEach((r, o) => {
      const { tileInfo: l } = t.get(r), { meshInfo: c, target: u } = l.get(e);
      c.forEach(({ attribute: h }, d) => {
        const { geometry: m, material: f } = d, p = this.meshParams.get(d), g = `layer_uv_${o}`;
        m.getAttribute(g) !== h && (m.setAttribute(g, h), m.dispose()), p.layerMaps.length = s.length, p.layerInfo.length = s.length, p.layerMaps.value[o] = u !== null ? u.texture : null, p.layerInfo.value[o] = r, f.defines[`LAYER_${o}_EXISTS`] = +(u !== null), f.defines[`LAYER_${o}_ALPHA_INVERT`] = Number(r.alphaInvert), f.defines[`LAYER_${o}_ALPHA_MASK`] = Number(r.alphaMask), f.defines.LAYER_COUNT = s.length, f.needsUpdate = !0;
      });
    });
  }
  _scheduleCleanup() {
    this._cleanupScheduled || (this._cleanupScheduled = !0, requestAnimationFrame(() => {
      const { usedTextures: e } = this;
      e.forEach((t) => {
        t.dispose();
      }), e.clear(), this._cleanupScheduled = !1;
    }));
  }
  _markNeedsUpdate() {
    this.needsUpdate === !1 && (this.needsUpdate = !0, this.tiles !== null && this.tiles.dispatchEvent({ type: "needs-update" }));
  }
}
class be {
  get tiling() {
    return this.imageSource.tiling;
  }
  get projection() {
    return this.tiling.projection;
  }
  get isPlanarProjection() {
    return !!this.frame;
  }
  get aspectRatio() {
    return this.tiling && this.isReady ? this.tiling.aspectRatio : 1;
  }
  get fetchOptions() {
    return this.imageSource.fetchOptions;
  }
  set fetchOptions(e) {
    this.imageSource.fetchOptions = e;
  }
  constructor(e = {}) {
    const {
      opacity: t = 1,
      color: s = 16777215,
      frame: n = null,
      preprocessURL: i = null,
      alphaMask: r = !1,
      alphaInvert: o = !1
    } = e;
    this.imageSource = null, this.preprocessURL = i, this.opacity = t, this.color = new Yt(s), this.frame = n !== null ? n.clone() : null, this.alphaMask = r, this.alphaInvert = o, this.isReady = !1, this.isInitialized = !1;
  }
  init() {
    this.isInitialized = !0, this.whenReady().then(() => {
      this.isReady = !0;
    });
  }
  fetch(e, t = {}) {
    return this.preprocessURL && (e = this.preprocessURL(e)), fetch(e, t);
  }
  whenReady() {
  }
  getAttributions(e) {
  }
  dispose() {
    this.imageSource.dispose();
  }
}
class xo extends be {
  constructor(e = {}) {
    super(e), this.imageSource = new Fe(e), this.imageSource.fetchData = (...t) => this.fetch(...t);
  }
  init() {
    this._whenReady = this.imageSource.init(), super.init();
  }
  whenReady() {
    return this._whenReady;
  }
}
class To extends be {
  constructor(e = {}) {
    super(e), this.imageSource = new Ar(e), this.imageSource.fetchData = (...t) => this.fetch(...t);
  }
  init() {
    this._whenReady = this.imageSource.init(), super.init();
  }
  whenReady() {
    return this._whenReady;
  }
}
class bo extends be {
  constructor(e = {}) {
    super(e), this.imageSource = new yn(e), this.imageSource.fetchData = (...t) => this.fetch(...t);
  }
  init() {
    this._whenReady = this.imageSource.init(), super.init();
  }
  whenReady() {
    return this._whenReady;
  }
}
class _o extends be {
  constructor(e = {}) {
    super(e), this.imageSource = new gn(e), this.imageSource.fetchData = (...t) => this.fetch(...t);
  }
  init() {
    this._whenReady = this.imageSource.init(), super.init();
  }
  whenReady() {
    return this._whenReady;
  }
}
class Mo extends be {
  constructor(e = {}) {
    super(e), this.imageSource = new $t(e), this.imageSource.fetchData = (...t) => this.fetch(...t), this.url = e.url;
  }
  init() {
    this._whenReady = this.imageSource.init(), super.init();
  }
  whenReady() {
    return this._whenReady;
  }
}
class So extends be {
  constructor(e = {}) {
    super(e);
    const { apiToken: t, autoRefreshToken: s, assetId: n } = e;
    this.options = e, this.assetId = n, this.auth = new Fn({ apiToken: t, autoRefreshToken: s }), this.auth.authURL = `https://api.cesium.com/v1/assets/${n}/endpoint`, this._attributions = [], this.externalType = !1;
  }
  init() {
    this._whenReady = this.auth.refreshToken().then(async (e) => {
      if (this._attributions = e.attributions.map((t) => ({
        value: t.html,
        type: "html",
        collapsible: t.collapsible
      })), e.type !== "IMAGERY")
        throw new Error("CesiumIonOverlay: Only IMAGERY is supported as overlay type.");
      switch (this.externalType = !!e.externalType, e.externalType) {
        case "GOOGLE_2D_MAPS": {
          const { url: t, session: s, key: n, tileWidth: i } = e.options, r = `${t}/v1/2dtiles/{z}/{x}/{y}?session=${s}&key=${n}`;
          this.imageSource = new Fe({
            ...this.options,
            url: r,
            tileDimension: i,
            // Google maps tiles have a fixed depth of 22
            // https://developers.google.com/maps/documentation/tile/2d-tiles-overview
            levels: 22
          });
          break;
        }
        case "BING": {
          const { url: t, mapStyle: s, key: n } = e.options, i = `${t}/REST/v1/Imagery/Metadata/${s}?incl=ImageryProviders&key=${n}&uriScheme=https`, o = (await fetch(i).then((l) => l.json())).resourceSets[0].resources[0];
          this.imageSource = new Tr({
            ...this.options,
            url: o.imageUrl,
            subdomains: o.imageUrlSubdomains,
            tileDimension: o.tileWidth,
            levels: o.zoomMax
          });
          break;
        }
        default:
          this.imageSource = new $t({
            ...this.options,
            url: e.url
          });
      }
      return this.imageSource.fetchData = (...t) => this.fetch(...t), this.imageSource.init();
    }), super.init();
  }
  fetch(...e) {
    return this.externalType ? super.fetch(...e) : this.auth.fetch(...e);
  }
  whenReady() {
    return this._whenReady;
  }
  getAttributions(e) {
    e.push(...this._attributions);
  }
}
class Co extends be {
  constructor(e = {}) {
    super(e);
    const { apiToken: t, sessionOptions: s, autoRefreshToken: n, logoUrl: i } = e;
    this.logoUrl = i, this.auth = new Nn({ apiToken: t, sessionOptions: s, autoRefreshToken: n }), this.imageSource = new Fe(), this.imageSource.fetchData = (...r) => this.fetch(...r), this._logoAttribution = {
      value: "",
      type: "image",
      collapsible: !1
    };
  }
  init() {
    this._whenReady = this.auth.refreshToken().then((e) => (this.imageSource.tileDimension = e.tileWidth, this.imageSource.url = "https://tile.googleapis.com/v1/2dtiles/{z}/{x}/{y}", this.imageSource.init())), super.init();
  }
  fetch(...e) {
    return this.auth.fetch(...e);
  }
  whenReady() {
    return this._whenReady;
  }
  getAttributions(e) {
    this.logoUrl && (this._logoAttribution.value = this.logoUrl, e.push(this._logoAttribution));
  }
}
class Ao {
  constructor() {
    this.name = "LOAD_REGION_PLUGIN", this.regions = [], this.tiles = null;
  }
  init(e) {
    this.tiles = e;
  }
  addRegion(e) {
    this.regions.indexOf(e) === -1 && this.regions.push(e);
  }
  removeRegion(e) {
    const t = this.regions.indexOf(e);
    t !== -1 && this.regions.splice(t, 1);
  }
  hasRegion(e) {
    return this.regions.indexOf(e) !== -1;
  }
  clearRegions() {
    this.regions = [];
  }
  // Calculates shape intersections and associated error values to use. If "mask" shapes are present then
  // tiles are only loaded if they are within those shapes.
  calculateTileViewError(e, t) {
    const s = e.cached.boundingVolume, { regions: n, tiles: i } = this;
    let r = !1, o = null, l = -1 / 0;
    for (const c of n) {
      const u = c.intersectsTile(s, e, i);
      r = r || u, l = Math.max(c.calculateError(e, i), l), c.mask && (o = o || u);
    }
    return t.inView = r && o !== !1, t.error = l, t.inView || o !== null;
  }
  dispose() {
    this.regions = [];
  }
}
class Jt {
  constructor(e = {}) {
    typeof e == "number" && (console.warn("LoadRegionPlugin: Region constructor has been changed to take options as an object."), e = { errorTarget: e });
    const {
      errorTarget: t = 10,
      mask: s = !1
    } = e;
    this.errorTarget = t, this.mask = s;
  }
  intersectsTile() {
  }
  calculateError(e, t) {
    return e.geometricError - this.errorTarget + t.errorTarget;
  }
}
class vo extends Jt {
  constructor(e = {}) {
    typeof e == "number" && (console.warn("SphereRegion: Region constructor has been changed to take options as an object."), e = {
      errorTarget: arguments[0],
      sphere: arguments[1]
    });
    const { sphere: t = new he() } = e;
    super(e), this.sphere = t.clone();
  }
  intersectsTile(e) {
    return e.intersectsSphere(this.sphere);
  }
}
class Lo extends Jt {
  constructor(e = {}) {
    typeof e == "number" && (console.warn("RayRegion: Region constructor has been changed to take options as an object."), e = {
      errorTarget: arguments[0],
      ray: arguments[1]
    });
    const { ray: t = new ni() } = e;
    super(e), this.ray = t.clone();
  }
  intersectsTile(e) {
    return e.intersectsRay(this.ray);
  }
}
class Io extends Jt {
  constructor(e = {}) {
    typeof e == "number" && (console.warn("RayRegion: Region constructor has been changed to take options as an object."), e = {
      errorTarget: arguments[0],
      obb: arguments[1]
    });
    const { obb: t = new di() } = e;
    super(e), this.obb = t.clone(), this.obb.update();
  }
  intersectsTile(e) {
    return e.intersectsOBB(this.obb);
  }
}
const te = /* @__PURE__ */ new E(), Hs = ["x", "y", "z"];
class Ir extends cn {
  constructor(e, t = 16776960, s = 40) {
    const n = new et(), i = [];
    for (let r = 0; r < 3; r++) {
      const o = Hs[r], l = Hs[(r + 1) % 3];
      te.set(0, 0, 0);
      for (let c = 0; c < s; c++) {
        let u;
        u = 2 * Math.PI * c / (s - 1), te[o] = Math.sin(u), te[l] = Math.cos(u), i.push(te.x, te.y, te.z), u = 2 * Math.PI * (c + 1) / (s - 1), te[o] = Math.sin(u), te[l] = Math.cos(u), i.push(te.x, te.y, te.z);
      }
    }
    n.setAttribute("position", new J(new Float32Array(i), 3)), n.computeBoundingSphere(), super(n, new ii({ color: t, toneMapped: !1 })), this.sphere = e, this.type = "SphereHelper";
  }
  updateMatrixWorld(e) {
    const t = this.sphere;
    this.position.copy(t.center), this.scale.setScalar(t.radius), super.updateMatrixWorld(e);
  }
}
const Pt = /* @__PURE__ */ new E(), Ze = /* @__PURE__ */ new E(), ne = /* @__PURE__ */ new E();
function Er(a, { computeNormals: e = !1 } = {}) {
  const {
    latStart: t = -Math.PI / 2,
    latEnd: s = Math.PI / 2,
    lonStart: n = 0,
    lonEnd: i = 2 * Math.PI,
    heightStart: r = 0,
    heightEnd: o = 0
  } = a, l = new oi(1, 1, 1, 32, 32), { normal: c, position: u } = l.attributes, h = u.clone();
  for (let d = 0, m = u.count; d < m; d++) {
    ne.fromBufferAttribute(u, d);
    const f = M.mapLinear(ne.x, -0.5, 0.5, t, s), p = M.mapLinear(ne.y, -0.5, 0.5, n, i);
    let g = r;
    a.getCartographicToNormal(f, p, Pt), ne.z < 0 && (g = o), a.getCartographicToPosition(f, p, g, ne), u.setXYZ(d, ...ne);
  }
  e && l.computeVertexNormals();
  for (let d = 0, m = h.count; d < m; d++) {
    ne.fromBufferAttribute(h, d);
    const f = M.mapLinear(ne.x, -0.5, 0.5, t, s), p = M.mapLinear(ne.y, -0.5, 0.5, n, i);
    Pt.fromBufferAttribute(c, d), a.getCartographicToNormal(f, p, Ze), Math.abs(Pt.dot(Ze)) > 0.1 && (ne.z > 0 && Ze.multiplyScalar(-1), c.setXYZ(d, ...Ze));
  }
  return l;
}
class wr extends cn {
  constructor(e = new pi(), t = 16776960) {
    super(), this.ellipsoidRegion = e, this.material.color.set(t), this.update();
  }
  update() {
    const e = Er(this.ellipsoidRegion);
    this.geometry.dispose(), this.geometry = new ri(e, 80);
  }
  dispose() {
    this.geometry.dispose(), this.material.dispose();
  }
}
const qs = Symbol("ORIGINAL_MATERIAL"), Rt = Symbol("HAS_RANDOM_COLOR"), Bt = Symbol("HAS_RANDOM_NODE_COLOR"), Dt = Symbol("LOAD_TIME"), ge = Symbol("PARENT_BOUND_REF_COUNT"), Ws = /* @__PURE__ */ new he(), Ot = () => {
}, Ut = {};
function Vt(a) {
  if (!Ut[a]) {
    const e = Math.random(), t = 0.5 + Math.random() * 0.5, s = 0.375 + Math.random() * 0.25;
    Ut[a] = new Yt().setHSL(e, t, s);
  }
  return Ut[a];
}
const Be = 0, vn = 1, Ln = 2, In = 3, En = 4, wn = 5, Pn = 6, Je = 7, Ke = 8, Rn = 9, Gt = 10, Pr = Object.freeze({
  NONE: Be,
  SCREEN_ERROR: vn,
  GEOMETRIC_ERROR: Ln,
  DISTANCE: In,
  DEPTH: En,
  RELATIVE_DEPTH: wn,
  IS_LEAF: Pn,
  RANDOM_COLOR: Je,
  RANDOM_NODE_COLOR: Ke,
  CUSTOM_COLOR: Rn,
  LOAD_ORDER: Gt
});
class Eo {
  static get ColorModes() {
    return Pr;
  }
  get unlit() {
    return this._unlit;
  }
  set unlit(e) {
    e !== this._unlit && (this._unlit = e, this.materialsNeedUpdate = !0);
  }
  get colorMode() {
    return this._colorMode;
  }
  set colorMode(e) {
    e !== this._colorMode && (this._colorMode = e, this.materialsNeedUpdate = !0);
  }
  get enabled() {
    return this._enabled;
  }
  set enabled(e) {
    e !== this._enabled && this.tiles !== null && (e ? this.init(this.tiles) : this.dispose()), this._enabled = e;
  }
  get displayParentBounds() {
    return this._displayParentBounds;
  }
  set displayParentBounds(e) {
    this._displayParentBounds !== e && (this._displayParentBounds = e, e ? this.tiles.traverse((t) => {
      t.__visible && this._onTileVisibilityChange(t, !0);
    }) : this.tiles.traverse((t) => {
      t[ge] = null, this._onTileVisibilityChange(t, t.__visible);
    }));
  }
  constructor(e) {
    e = {
      displayParentBounds: !1,
      displayBoxBounds: !1,
      displaySphereBounds: !1,
      displayRegionBounds: !1,
      colorMode: Be,
      maxDebugDepth: -1,
      maxDebugDistance: -1,
      maxDebugError: -1,
      customColorCallback: null,
      unlit: !1,
      enabled: !0,
      ...e
    }, this.name = "DEBUG_TILES_PLUGIN", this.tiles = null, this._colorMode = null, this._unlit = null, this.materialsNeedUpdate = !1, this.extremeDebugDepth = -1, this.extremeDebugError = -1, this.boxGroup = null, this.sphereGroup = null, this.regionGroup = null, this._enabled = e.enabled, this._displayParentBounds = e.displayParentBounds, this.displayBoxBounds = e.displayBoxBounds, this.displaySphereBounds = e.displaySphereBounds, this.displayRegionBounds = e.displayRegionBounds, this.colorMode = e.colorMode, this.maxDebugDepth = e.maxDebugDepth, this.maxDebugDistance = e.maxDebugDistance, this.maxDebugError = e.maxDebugError, this.customColorCallback = e.customColorCallback, this.unlit = e.unlit, this.getDebugColor = (t, s) => {
      s.setRGB(t, t, t);
    };
  }
  // initialize the groups for displaying helpers, register events, and initialize existing tiles
  init(e) {
    this.tiles = e;
    const t = e.group;
    this.boxGroup = new Ge(), this.boxGroup.name = "DebugTilesRenderer.boxGroup", t.add(this.boxGroup), this.boxGroup.updateMatrixWorld(), this.sphereGroup = new Ge(), this.sphereGroup.name = "DebugTilesRenderer.sphereGroup", t.add(this.sphereGroup), this.sphereGroup.updateMatrixWorld(), this.regionGroup = new Ge(), this.regionGroup.name = "DebugTilesRenderer.regionGroup", t.add(this.regionGroup), this.regionGroup.updateMatrixWorld(), this._onLoadTilesetCB = () => {
      this._initExtremes();
    }, this._onLoadModelCB = ({ scene: s, tile: n }) => {
      this._onLoadModel(s, n);
    }, this._onDisposeModelCB = ({ tile: s }) => {
      this._onDisposeModel(s);
    }, this._onUpdateAfterCB = () => {
      this._onUpdateAfter();
    }, this._onTileVisibilityChangeCB = ({ scene: s, tile: n, visible: i }) => {
      this._onTileVisibilityChange(n, i);
    }, e.addEventListener("load-tileset", this._onLoadTilesetCB), e.addEventListener("load-model", this._onLoadModelCB), e.addEventListener("dispose-model", this._onDisposeModelCB), e.addEventListener("update-after", this._onUpdateAfterCB), e.addEventListener("tile-visibility-change", this._onTileVisibilityChangeCB), this._initExtremes(), e.traverse((s) => {
      s.cached.scene && this._onLoadModel(s.cached.scene, s);
    }), e.visibleTiles.forEach((s) => {
      this._onTileVisibilityChange(s, !0);
    });
  }
  getTileInformationFromActiveObject(e) {
    let t = null;
    return this.tiles.activeTiles.forEach((n) => {
      if (t)
        return !0;
      const i = n.cached.scene;
      i && i.traverse((r) => {
        r === e && (t = n);
      });
    }), t ? {
      distanceToCamera: t.__distanceFromCamera,
      geometricError: t.geometricError,
      screenSpaceError: t.__error,
      depth: t.__depth,
      isLeaf: t.__isLeaf
    } : null;
  }
  _initExtremes() {
    if (!(this.tiles && this.tiles.root))
      return;
    let e = -1, t = -1;
    this.tiles.traverse(null, (s, n, i) => {
      e = Math.max(e, i), t = Math.max(t, s.geometricError);
    }, !1), this.extremeDebugDepth = e, this.extremeDebugError = t;
  }
  _onUpdateAfter() {
    const { tiles: e, colorMode: t } = this;
    if (!e.root)
      return;
    this.materialsNeedUpdate && (e.forEachLoadedModel((c) => {
      this._updateMaterial(c);
    }), this.materialsNeedUpdate = !1), this.boxGroup.visible = this.displayBoxBounds, this.sphereGroup.visible = this.displaySphereBounds, this.regionGroup.visible = this.displayRegionBounds;
    let s = -1;
    this.maxDebugDepth === -1 ? s = this.extremeDebugDepth : s = this.maxDebugDepth;
    let n = -1;
    this.maxDebugError === -1 ? n = this.extremeDebugError : n = this.maxDebugError;
    let i = -1;
    this.maxDebugDistance === -1 ? (e.getBoundingSphere(Ws), i = Ws.radius) : i = this.maxDebugDistance;
    const { errorTarget: r, visibleTiles: o } = e;
    let l;
    t === Gt && (l = Array.from(o).sort((c, u) => c[Dt] - u[Dt])), o.forEach((c) => {
      const u = c.cached.scene;
      let h, d, m;
      t === Je && (h = Math.random(), d = 0.5 + Math.random() * 0.5, m = 0.375 + Math.random() * 0.25), u.traverse((f) => {
        if (t === Ke && (h = Math.random(), d = 0.5 + Math.random() * 0.5, m = 0.375 + Math.random() * 0.25), f.material)
          switch (t !== Je && delete f.material[Rt], t !== Ke && delete f.material[Bt], t) {
            case En: {
              const p = c.__depth / s;
              this.getDebugColor(p, f.material.color);
              break;
            }
            case wn: {
              const p = c.__depthFromRenderedParent / s;
              this.getDebugColor(p, f.material.color);
              break;
            }
            case vn: {
              const p = c.__error / r;
              p > 1 ? f.material.color.setRGB(1, 0, 0) : this.getDebugColor(p, f.material.color);
              break;
            }
            case Ln: {
              const p = Math.min(c.geometricError / n, 1);
              this.getDebugColor(p, f.material.color);
              break;
            }
            case In: {
              const p = Math.min(c.__distanceFromCamera / i, 1);
              this.getDebugColor(p, f.material.color);
              break;
            }
            case Pn: {
              !c.children || c.children.length === 0 ? this.getDebugColor(1, f.material.color) : this.getDebugColor(0, f.material.color);
              break;
            }
            case Ke: {
              f.material[Bt] || (f.material.color.setHSL(h, d, m), f.material[Bt] = !0);
              break;
            }
            case Je: {
              f.material[Rt] || (f.material.color.setHSL(h, d, m), f.material[Rt] = !0);
              break;
            }
            case Rn: {
              this.customColorCallback ? this.customColorCallback(c, f) : console.warn("DebugTilesRenderer: customColorCallback not defined");
              break;
            }
            case Gt: {
              const p = l.indexOf(c);
              this.getDebugColor(p / (l.length - 1), f.material.color);
              break;
            }
          }
      });
    });
  }
  _onTileVisibilityChange(e, t) {
    this.displayParentBounds ? yi(e, (s) => {
      s[ge] == null && (s[ge] = 0), t ? s[ge]++ : s[ge] > 0 && s[ge]--;
      const n = s === e && t || this.displayParentBounds && s[ge] > 0;
      this._updateBoundHelper(s, n);
    }) : this._updateBoundHelper(e, t);
  }
  _createBoundHelper(e) {
    const t = this.tiles, s = e.cached, { sphere: n, obb: i, region: r } = s.boundingVolume;
    if (i) {
      const o = new Ge();
      o.name = "DebugTilesRenderer.boxHelperGroup", o.matrix.copy(i.transform), o.matrixAutoUpdate = !1;
      const l = new ai(i.box, Vt(e.__depth));
      l.raycast = Ot, o.add(l), s.boxHelperGroup = o, t.visibleTiles.has(e) && this.displayBoxBounds && (this.boxGroup.add(o), o.updateMatrixWorld(!0));
    }
    if (n) {
      const o = new Ir(n, Vt(e.__depth));
      o.raycast = Ot, s.sphereHelper = o, t.visibleTiles.has(e) && this.displaySphereBounds && (this.sphereGroup.add(o), o.updateMatrixWorld(!0));
    }
    if (r) {
      const o = new wr(r, Vt(e.__depth));
      o.raycast = Ot;
      const l = new he();
      r.getBoundingSphere(l), o.position.copy(l.center), l.center.multiplyScalar(-1), o.geometry.translate(...l.center), s.regionHelper = o, t.visibleTiles.has(e) && this.displayRegionBounds && (this.regionGroup.add(o), o.updateMatrixWorld(!0));
    }
  }
  _updateHelperMaterial(e, t) {
    e.__visible || !this.displayParentBounds ? t.opacity = 1 : t.opacity = 0.2;
    const s = t.transparent;
    t.transparent = t.opacity < 1, t.transparent !== s && (t.needsUpdate = !0);
  }
  _updateBoundHelper(e, t) {
    const s = e.cached;
    if (!s)
      return;
    const n = this.sphereGroup, i = this.boxGroup, r = this.regionGroup;
    t && s.boxHelperGroup == null && s.sphereHelper == null && s.regionHelper == null && this._createBoundHelper(e);
    const o = s.boxHelperGroup, l = s.sphereHelper, c = s.regionHelper;
    t ? (o && (i.add(o), o.updateMatrixWorld(!0), this._updateHelperMaterial(e, o.children[0].material)), l && (n.add(l), l.updateMatrixWorld(!0), this._updateHelperMaterial(e, l.material)), c && (r.add(c), c.updateMatrixWorld(!0), this._updateHelperMaterial(e, c.material))) : (o && i.remove(o), l && n.remove(l), c && r.remove(c));
  }
  _updateMaterial(e) {
    const { colorMode: t, unlit: s } = this;
    e.traverse((n) => {
      if (!n.material)
        return;
      const i = n.material, r = n[qs];
      if (i !== r && i.dispose(), t !== Be || s) {
        if (n.isPoints) {
          const o = new li();
          o.size = r.size, o.sizeAttenuation = r.sizeAttenuation, n.material = o;
        } else s ? n.material = new Ue() : (n.material = new en(), n.material.flatShading = !0);
        t === Be && (n.material.map = r.map, n.material.color.set(r.color));
      } else
        n.material = r;
    });
  }
  _onLoadModel(e, t) {
    t[Dt] = performance.now(), e.traverse((s) => {
      const n = s.material;
      n && (s[qs] = n);
    }), this._updateMaterial(e);
  }
  _onDisposeModel(e) {
    const t = e.cached;
    t.boxHelperGroup && (t.boxHelperGroup.children[0].geometry.dispose(), delete t.boxHelperGroup), t.sphereHelper && (t.sphereHelper.geometry.dispose(), delete t.sphereHelper), t.regionHelper && (t.regionHelper.geometry.dispose(), delete t.regionHelper);
  }
  dispose() {
    var t, s, n;
    const e = this.tiles;
    e.removeEventListener("load-tileset", this._onLoadTilesetCB), e.removeEventListener("load-model", this._onLoadModelCB), e.removeEventListener("dispose-model", this._onDisposeModelCB), e.removeEventListener("update-after", this._onUpdateAfterCB), e.removeEventListener("tile-visibility-change", this._onTileVisibilityChangeCB), this.colorMode = Be, this.unlit = !1, e.forEachLoadedModel((i) => {
      this._updateMaterial(i);
    }), e.traverse((i) => {
      this._onDisposeModel(i);
    }), (t = this.boxGroup) == null || t.removeFromParent(), (s = this.sphereGroup) == null || s.removeFromParent(), (n = this.regionGroup) == null || n.removeFromParent();
  }
}
class Rr extends Ae {
  constructor(e = {}) {
    const { url: t = null, ...s } = e;
    super(s), this.url = t, this.format = null, this.stem = null;
  }
  getUrl(e, t, s) {
    return `${this.stem}_files/${s}/${e}_${t}.${this.format}`;
  }
  init() {
    const { url: e } = this;
    return this.fetchData(e, this.fetchOptions).then((t) => t.text()).then((t) => {
      const s = new DOMParser().parseFromString(t, "text/xml");
      if (s.querySelector("DisplayRects") || s.querySelector("Collection"))
        throw new Error("DeepZoomImagesPlugin: DisplayRect and Collection DZI files not supported.");
      const n = s.querySelector("Image"), i = n.querySelector("Size"), r = parseInt(i.getAttribute("Width")), o = parseInt(i.getAttribute("Height")), l = parseInt(n.getAttribute("TileSize")), c = parseInt(n.getAttribute("Overlap")), u = n.getAttribute("Format");
      this.format = u, this.stem = e.split(/\.[^.]+$/g)[0];
      const { tiling: h } = this, d = Math.ceil(Math.log2(Math.max(r, o))) + 1;
      h.flipY = !0, h.pixelOverlap = c, h.generateLevels(d, 1, 1, {
        tilePixelWidth: l,
        tilePixelHeight: l,
        pixelWidth: r,
        pixelHeight: o
      });
    });
  }
}
class wo extends fn {
  constructor(e = {}) {
    const { url: t, ...s } = e;
    super(s), this.name = "DZI_TILES_PLUGIN", this.imageSource = new Rr({ url: t });
  }
}
const rt = dn * Math.PI * 2, Xs = /* @__PURE__ */ new de("EPSG:3857");
function Br(a) {
  return /:4326$/i.test(a);
}
function Bn(a) {
  return /:3857$/i.test(a);
}
function jt(a) {
  return a.trim().split(/\s+/).map((e) => parseFloat(e));
}
function zt(a, e) {
  Br(e) && ([a[1], a[0]] = [a[0], a[1]]);
}
function ot(a, e) {
  if (Bn(e))
    return a[0] = Xs.convertProjectionToLongitude(0.5 + a[0] / rt), a[1] = Xs.convertProjectionToLatitude(0.5 + a[1] / rt), a[0] *= M.RAD2DEG, a[1] *= M.RAD2DEG, a;
}
function at(a) {
  a[0] *= M.DEG2RAD, a[1] *= M.DEG2RAD;
}
class Po extends pn {
  parse(e) {
    const t = new TextDecoder("utf-8").decode(new Uint8Array(e)), s = new DOMParser().parseFromString(t, "text/xml"), n = s.querySelector("Contents"), i = ce(n, "TileMatrixSet").map((l) => Nr(l)), r = ce(n, "Layer").map((l) => Or(l)), o = Dr(s.querySelector("ServiceIdentification"));
    return r.forEach((l) => {
      l.tileMatrixSets = l.tileMatrixSetLinks.map((c) => i.find((u) => u.identifier === c));
    }), {
      serviceIdentification: o,
      tileMatrixSets: i,
      layers: r
    };
  }
}
function Dr(a) {
  var i;
  const e = a.querySelector("Title").textContent, t = ((i = a.querySelector("Abstract")) == null ? void 0 : i.textContent) || "", s = a.querySelector("ServiceType").textContent, n = a.querySelector("ServiceTypeVersion").textContent;
  return {
    title: e,
    abstract: t,
    serviceType: s,
    serviceTypeVersion: n
  };
}
function Or(a) {
  const e = a.querySelector("Title").textContent, t = a.querySelector("Identifier").textContent, s = a.querySelector("Format").textContent, n = ce(a, "ResourceURL").map((c) => Ur(c)), i = ce(a, "TileMatrixSetLink").map((c) => ce(c, "TileMatrixSet")[0].textContent), r = ce(a, "Style").map((c) => Fr(c)), o = ce(a, "Dimension").map((c) => Vr(c));
  let l = Ys(a.querySelector("WGS84BoundingBox"));
  return l || (l = Ys(a.querySelector("BoundingBox"))), {
    title: e,
    identifier: t,
    format: s,
    dimensions: o,
    tileMatrixSetLinks: i,
    styles: r,
    boundingBox: l,
    resourceUrls: n
  };
}
function Ur(a) {
  const e = a.getAttribute("template"), t = a.getAttribute("format"), s = a.getAttribute("resourceType");
  return {
    template: e,
    format: t,
    resourceType: s
  };
}
function Vr(a) {
  var r, o;
  const e = a.querySelector("Identifier").textContent, t = ((r = a.querySelector("UOM")) == null ? void 0 : r.textContent) || "", s = a.querySelector("Default").textContent, n = ((o = a.querySelector("Current")) == null ? void 0 : o.textContent) === "true", i = ce(a, "Value").map((l) => l.textContent);
  return {
    identifier: e,
    uom: t,
    defaultValue: s,
    current: n,
    values: i
  };
}
function Ys(a) {
  if (!a)
    return null;
  const e = a.nodeName.endsWith("WGS84BoundingBox") ? "urn:ogc:def:crs:CRS::84" : a.getAttribute("crs"), t = jt(a.querySelector("LowerCorner").textContent), s = jt(a.querySelector("UpperCorner").textContent);
  return zt(t, e), zt(s, e), ot(t, e), ot(s, e), at(t), at(s), {
    crs: e,
    lowerCorner: t,
    upperCorner: s,
    bounds: [...t, ...s]
  };
}
function Fr(a) {
  var n;
  const e = ((n = a.querySelector("Title")) == null ? void 0 : n.textContent) || null, t = a.querySelector("Identifier").textContent, s = a.getAttribute("isDefault") === "true";
  return {
    title: e,
    identifier: t,
    isDefault: s
  };
}
function Nr(a) {
  var r, o;
  const e = a.querySelector("SupportedCRS").textContent, t = ((r = a.querySelector("Title")) == null ? void 0 : r.textContent) || "", s = a.querySelector("Identifier").textContent, n = ((o = a.querySelector("Abstract")) == null ? void 0 : o.textContent) || "", i = [];
  return a.querySelectorAll("TileMatrix").forEach((l, c) => {
    const u = kr(l), h = 28e-5 * u.scaleDenominator, d = u.tileWidth * u.matrixWidth * h, m = u.tileHeight * u.matrixHeight * h;
    let f;
    zt(u.topLeftCorner, e), Bn(e) ? f = [
      u.topLeftCorner[0] + d,
      u.topLeftCorner[1] - m
    ] : f = [
      u.topLeftCorner[0] + 360 * d / rt,
      u.topLeftCorner[1] - 360 * m / rt
    ], ot(f, e), ot(u.topLeftCorner, e), at(f), at(u.topLeftCorner), u.bounds = [...u.topLeftCorner, ...f], [u.bounds[1], u.bounds[3]] = [u.bounds[3], u.bounds[1]], i.push(u);
  }), {
    title: t,
    identifier: s,
    abstract: n,
    supportedCRS: e,
    tileMatrices: i
  };
}
function kr(a) {
  const e = a.querySelector("Identifier").textContent, t = parseFloat(a.querySelector("TileWidth").textContent), s = parseFloat(a.querySelector("TileHeight").textContent), n = parseFloat(a.querySelector("MatrixWidth").textContent), i = parseFloat(a.querySelector("MatrixHeight").textContent), r = parseFloat(a.querySelector("ScaleDenominator").textContent), o = jt(a.querySelector("TopLeftCorner").textContent);
  return {
    identifier: e,
    tileWidth: t,
    tileHeight: s,
    matrixWidth: n,
    matrixHeight: i,
    scaleDenominator: r,
    topLeftCorner: o,
    bounds: null
  };
}
function ce(a, e) {
  return [...a.children].filter((t) => t.tagName === e);
}
const $s = dn * Math.PI * 2, Qs = /* @__PURE__ */ new de("EPSG:3857");
function Gr(a) {
  return /:4326$/i.test(a);
}
function jr(a) {
  return /:3857$/i.test(a);
}
function Zs(a, e) {
  return jr(e) && (a[0] = Qs.convertProjectionToLongitude(0.5 + a[0] / (Math.PI * 2 * $s)), a[1] = Qs.convertProjectionToLatitude(0.5 + a[1] / (Math.PI * 2 * $s)), a[0] *= M.RAD2DEG, a[1] *= M.RAD2DEG), a;
}
function Js(a, e, t) {
  const [s, n] = t.split(".").map((r) => parseInt(r)), i = s === 1 && n < 3 || s < 1;
  Gr(e) && i && ([a[0], a[1]] = [a[1], a[0]]);
}
function Ce(a) {
  a[0] *= M.DEG2RAD, a[1] *= M.DEG2RAD;
}
function zr(a, e) {
  if (!a)
    return null;
  const t = a.getAttribute("CRS") || a.getAttribute("crs") || a.getAttribute("SRS") || "", s = parseFloat(a.getAttribute("minx")), n = parseFloat(a.getAttribute("miny")), i = parseFloat(a.getAttribute("maxx")), r = parseFloat(a.getAttribute("maxy")), o = [s, n], l = [i, r];
  return Js(o, t, e), Js(l, t, e), Zs(o, t), Zs(l, t), Ce(o), Ce(l), { crs: t, bounds: [...o, ...l] };
}
function Hr(a) {
  const e = parseFloat(a.querySelector("westBoundLongitude").textContent), t = parseFloat(a.querySelector("eastBoundLongitude").textContent), s = parseFloat(a.querySelector("southBoundLatitude").textContent), n = parseFloat(a.querySelector("northBoundLatitude").textContent), i = [e, s], r = [t, n];
  return Ce(i), Ce(r), [...i, ...r];
}
function qr(a) {
  const e = parseFloat(a.getAttribute("minx").textContent), t = parseFloat(a.getAttribute("maxx").textContent), s = parseFloat(a.getAttribute("miny").textContent), n = parseFloat(a.getAttribute("maxy").textContent), i = [e, s], r = [t, n];
  return Ce(i), Ce(r), [...i, ...r];
}
function Wr(a) {
  const e = a.querySelector("Name").textContent, t = a.querySelector("Title").textContent, s = [...a.querySelectorAll("LegendURL")].map((n) => {
    const i = parseInt(n.getAttribute("width")), r = parseInt(n.getAttribute("height")), o = n.querySelector("Format").textContent, l = n.querySelector("OnlineResource"), c = Ht(l);
    return {
      width: i,
      height: r,
      format: o,
      url: c
    };
  });
  return {
    name: e,
    title: t,
    legends: s
  };
}
function Dn(a, e, t = {}) {
  var p, g, y;
  let {
    styles: s = [],
    crs: n = [],
    contentBoundingBox: i = null,
    queryable: r = !1,
    opaque: o = !1
  } = t;
  const l = ((p = a.querySelector(":scope > Name")) == null ? void 0 : p.textContent) || null, c = ((g = a.querySelector(":scope > Title")) == null ? void 0 : g.textContent) || "", u = ((y = a.querySelector(":scope > Abstract")) == null ? void 0 : y.textContent) || "", h = [...a.querySelectorAll(":scope > Keyword")].map((x) => x.textContent), m = [...a.querySelectorAll(":scope > BoundingBox")].map((x) => zr(x, e));
  n = [
    ...n,
    ...Array.from(a.querySelectorAll("CRS")).map((x) => x.textContent)
  ], s = [
    ...s,
    ...Array.from(a.querySelectorAll(":scope > Style")).map((x) => Wr(x))
  ], a.hasAttribute("queryable") && (r = a.getAttribute("queryable") === "1"), a.hasAttribute("opaque") && (o = a.getAttribute("opaque") === "1"), a.querySelector("EX_GeographicBoundingBox") ? i = Hr(a.querySelector("EX_GeographicBoundingBox")) : a.querySelector("LatLonBoundingBox") && (i = qr(a.querySelector("LatLonBoundingBox")));
  const f = Array.from(a.querySelectorAll(":scope > Layer")).map((x) => Dn(x, e, {
    // add
    styles: s,
    crs: n,
    // replace
    contentBoundingBox: i,
    queryable: r,
    opaque: o
  }));
  return {
    name: l,
    title: c,
    abstract: u,
    queryable: r,
    opaque: o,
    keywords: h,
    crs: n,
    boundingBoxes: m,
    contentBoundingBox: i,
    styles: s,
    subLayers: f
  };
}
function Xr(a) {
  var e, t, s;
  return {
    name: ((e = a.querySelector("Name")) == null ? void 0 : e.textContent) || "",
    title: ((t = a.querySelector("Title")) == null ? void 0 : t.textContent) || "",
    abstract: ((s = a.querySelector("Abstract")) == null ? void 0 : s.textContent) || "",
    keywords: Array.from(a.querySelectorAll("Keyword")).map((n) => n.textContent),
    maxWidth: parseFloat(a.querySelector("MaxWidth")) || null,
    maxHeight: parseFloat(a.querySelector("MaxHeight")) || null,
    layerLimit: parseFloat(a.querySelector("LayerLimit")) || null
  };
}
function Ht(a) {
  return a ? (a.getAttribute("xlink:href") || a.getAttributeNS("http://www.w3.org/1999/xlink", "href") || "").trim() : "";
}
function Yr(a) {
  const e = Array.from(a.querySelectorAll("Format")).map((s) => s.textContent.trim()), t = Array.from(a.querySelectorAll("DCPType")).map((s) => {
    const n = s.querySelector("HTTP"), i = n.querySelector("Get OnlineResource") || n.querySelector("Get > OnlineResource") || n.querySelector("Get"), r = n.querySelector("Post OnlineResource") || n.querySelector("Post > OnlineResource") || n.querySelector("Post"), o = Ht(i), l = Ht(r);
    return { type: "HTTP", get: o, post: l };
  });
  return { formats: e, dcp: t, href: t[0].get };
}
function $r(a) {
  const e = {};
  return Array.from(a.querySelectorAll(":scope > *")).forEach((t) => {
    const s = t.localName;
    e[s] = Yr(t);
  }), e;
}
function On(a, e = []) {
  return a.forEach((t) => {
    t.name !== null && e.push(t), On(t.subLayers, e);
  }), e;
}
class Ro extends pn {
  parse(e) {
    const t = new TextDecoder("utf-8").decode(new Uint8Array(e)), s = new DOMParser().parseFromString(t, "text/xml"), i = (s.querySelector("WMS_Capabilities") || s.querySelector("WMT_MS_Capabilities")).getAttribute("version"), r = s.querySelector("Capability"), o = Xr(s.querySelector(":scope > Service")), l = $r(r.querySelector(":scope > Request")), c = Array.from(r.querySelectorAll(":scope > Layer")).map((h) => Dn(h, i)), u = On(c);
    return { version: i, service: o, layers: u, request: l };
  }
}
export {
  mo as B,
  oo as C,
  Eo as D,
  uo as G,
  yo as I,
  Ao as L,
  Io as O,
  Di as Q,
  ho as R,
  vo as S,
  co as T,
  lo as U,
  bo as W,
  xo as X,
  po as a,
  fo as b,
  go as c,
  To as d,
  _o as e,
  Mo as f,
  So as g,
  Co as h,
  Jt as i,
  Lo as j,
  wo as k,
  no as l,
  Si as m,
  io as n,
  ro as o,
  tr as p,
  Zi as q,
  er as r,
  Po as s,
  Ro as t
};
//# sourceMappingURL=WMSCapabilitiesLoader-DgQmEDMc.js.map