var __defProp = Object.defineProperty;
var __typeError = (msg) => {
  throw TypeError(msg);
};
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
var _styleSheet, _renderer, _scene, _camera, _cameraControls, _observer, _shadow, _objectDragging, _exposure, _ready, _readyResolve, _readyReject, _isReadySettled, _MirisScene_instances, initReadyPromise_fn, _viewerKey, _needsRender, adjustCameraClipPlanes_fn, onSceneLoaded_fn, updateStreamBounds_fn, checkForDefaultCamera_fn;
import { Vector3, Euler, PerspectiveCamera, Group, Controls, MOUSE, TOUCH, Quaternion, Spherical, Vector2, Ray, Plane, MathUtils, WebGLRenderer, Matrix4 } from "three";
import { MirisControls, MirisScene as MirisScene$1, Miris, MirisStream as MirisStream$1 } from "@miris-inc/three";
class Bus {
  static #subscriptions = /* @__PURE__ */ new Map();
  // Generic subscribe: accepts callbacks with specific parameter types.
  // The `& ((...args: unknown[]) => void)` intersection ensures storage compatibility.
  static subscribe(key, name, callback) {
    if (!this.#subscriptions.has(key)) {
      this.#subscriptions.set(key, /* @__PURE__ */ new Map());
    }
    this.#subscriptions.get(key).set(name, callback);
  }
  static unsubscribe(key, name) {
    if (!this.#subscriptions.has(key)) return;
    this.#subscriptions.get(key).delete(name);
    if (!this.#subscriptions.get(key).size) {
      this.#subscriptions.delete(key);
    }
  }
  static publish(key, name, ...args) {
    const callback = this.#subscriptions.get(key)?.get(name);
    if (callback) callback(...args);
  }
}
class MirisPrimitive extends HTMLElement {
  static observedAttributes = ["position", "rotation", "scale", "zoom"];
  #position = new Vector3();
  #rotation = new Euler();
  #scale = new Vector3(1, 1, 1);
  /**
   * Tracks whether position was explicitly set by the user (via HTML attribute or JS).
   * Used to determine if asset's default camera should override the position.
   */
  _positionExplicitlySet = false;
  /**
   * Tracks whether rotation was explicitly set by the user (via HTML attribute or JS).
   * Used to determine if asset's default camera should override the rotation.
   */
  _rotationExplicitlySet = false;
  #zoom = 1;
  // prettier-ignore
  get zoom() {
    return this.#zoom;
  }
  set zoom(zoom) {
    this.#zoom = zoom;
    const { x, y, z } = this.scale;
    this.threeObject?.scale.set(zoom * x, zoom * y, zoom * z);
  }
  get _parent() {
    const selector = "miris-group, miris-scene";
    return this.parentElement?.closest(selector) ?? null;
  }
  threeObject = null;
  #setZoomFromAttributeValue(value) {
    const zoom = parseFloat(value ?? `${this.#zoom}`);
    if (isNaN(zoom))
      console.warn("Failed parsing zoom attribute since it is NaN");
    this.zoom = zoom;
  }
  #parseVectorAttribute(name, value, defaultValue) {
    value ??= defaultValue;
    const splitComponents = value.split(" ");
    if (3 !== splitComponents.length) {
      console.warn(
        `Failed parsing ${name} attribute since it does not have three components.`
      );
    }
    const parsedComponents = splitComponents.map(parseFloat);
    if (parsedComponents.some(isNaN)) {
      console.warn(
        `Failed parsing ${name} attribute since one or more of its components are NaN`
      );
    }
    return parsedComponents;
  }
  #setPositionFromAttributeValue(value) {
    this.position.set(
      ...this.#parseVectorAttribute("position", value, "0 0 0")
    );
  }
  #initPosition() {
    const self = this;
    const hadPositionAttr = this.hasAttribute("position");
    Object.defineProperty(this, "position", {
      value: {
        get x() {
          return self.#position.x;
        },
        set x(x) {
          self._positionExplicitlySet = true;
          self.#position.x = x;
          if (self.threeObject) self.threeObject.position.x = x;
        },
        get y() {
          return self.#position.y;
        },
        set y(y) {
          self._positionExplicitlySet = true;
          self.#position.y = y;
          if (self.threeObject) self.threeObject.position.y = y;
        },
        get z() {
          return self.#position.z;
        },
        set z(z) {
          self._positionExplicitlySet = true;
          self.#position.z = z;
          if (self.threeObject) self.threeObject.position.z = z;
        },
        set(x, y, z) {
          self._positionExplicitlySet = true;
          self.#position.x = x;
          self.#position.y = y;
          self.#position.z = z;
          self.threeObject?.position.set(x, y, z);
        }
      }
    });
    Object.freeze(this.position);
    const position = this.#parseVectorAttribute(
      "position",
      this.getAttribute("position"),
      "0 0 0"
    );
    this.#position.x = position[0];
    this.#position.y = position[1];
    this.#position.z = position[2];
    this._positionExplicitlySet = hadPositionAttr;
  }
  #setRotationFromAttributeValue(value) {
    const rotation = this.#parseVectorAttribute("rotation", value, "0 0 0");
    this.rotation.set(...rotation);
  }
  #initRotation() {
    const self = this;
    const hadRotationAttr = this.hasAttribute("rotation");
    Object.defineProperty(this, "rotation", {
      value: {
        get x() {
          return self.#rotation.x;
        },
        set x(x) {
          self._rotationExplicitlySet = true;
          self.#rotation.x = x;
          if (self.threeObject) self.threeObject.rotation.x = x;
        },
        get y() {
          return self.#rotation.y;
        },
        set y(y) {
          self._rotationExplicitlySet = true;
          self.#rotation.y = y;
          if (self.threeObject) self.threeObject.rotation.y = y;
        },
        get z() {
          return self.#rotation.z;
        },
        set z(z) {
          self._rotationExplicitlySet = true;
          self.#rotation.z = z;
          if (self.threeObject) self.threeObject.rotation.z = z;
        },
        set(x, y, z) {
          self._rotationExplicitlySet = true;
          self.#rotation.x = x;
          self.#rotation.y = y;
          self.#rotation.z = z;
          self.threeObject?.rotation.set(x, y, z);
        }
      }
    });
    Object.freeze(this.rotation);
    const rotation = this.#parseVectorAttribute(
      "rotation",
      this.getAttribute("rotation"),
      "0 0 0"
    );
    this.#rotation.x = rotation[0];
    this.#rotation.y = rotation[1];
    this.#rotation.z = rotation[2];
    this._rotationExplicitlySet = hadRotationAttr;
  }
  #setScaleFromAttributeValue(value) {
    this.scale.set(...this.#parseVectorAttribute("scale", value, "1 1 1"));
  }
  #initScale() {
    const self = this;
    Object.defineProperty(this, "scale", {
      value: {
        get x() {
          return self.#scale.x;
        },
        set x(x) {
          self.#scale.x = x;
          if (self.threeObject) self.threeObject.scale.x = self.zoom * x;
        },
        get y() {
          return self.#scale.y;
        },
        set y(y) {
          self.#scale.y = y;
          if (self.threeObject) self.threeObject.scale.y = self.zoom * y;
        },
        get z() {
          return self.#scale.z;
        },
        set z(z) {
          self.#scale.z = z;
          if (self.threeObject) self.threeObject.scale.z = self.zoom * z;
        },
        set(x, y, z) {
          const { zoom } = self;
          self.#scale.x = x;
          self.#scale.y = y;
          self.#scale.z = z;
          self.threeObject?.scale.set(zoom * x, zoom * y, zoom * z);
        }
      }
    });
    Object.freeze(this.scale);
    this.#setZoomFromAttributeValue(this.getAttribute("zoom"));
    this.#setScaleFromAttributeValue(this.getAttribute("scale"));
  }
  constructor() {
    super();
    this.#initPosition();
    this.#initRotation();
    this.#initScale();
  }
  _enable() {
    if (!this.getRootNode().contains(this) || !this.threeObject) {
      return;
    }
    const { position, rotation, scale, zoom } = this;
    const { x: pX, y: pY, z: pZ } = position;
    const { x: rX, y: rY, z: rZ } = rotation;
    const { x: sX, y: sY, z: sZ } = scale;
    this.threeObject.position.set(pX, pY, pZ);
    this.threeObject.rotation.set(rX, rY, rZ);
    this.threeObject.scale.set(zoom * sX, zoom * sY, zoom * sZ);
    if (this._parent) {
      Bus.publish(this._parent, "add", this.threeObject);
    }
  }
  _disable() {
    if (this._parent) Bus.publish(this._parent, "remove", this.threeObject);
    this.threeObject = null;
  }
  connectedCallback() {
    this._enable();
    Bus.subscribe(this, "add", (object) => {
      if (this.threeObject?.children.includes(object)) return;
      this.threeObject?.add(object);
    });
    Bus.subscribe(this, "remove", (object) => {
      this.threeObject?.remove(object);
    });
  }
  disconnectedCallback() {
    Bus.unsubscribe(this, "add");
    Bus.unsubscribe(this, "remove");
  }
  attributeChangedCallback(name, oldValue, newValue) {
    if (oldValue === newValue) return;
    switch (name) {
      case "position":
        this.#setPositionFromAttributeValue(newValue);
        break;
      case "rotation":
        this.#setRotationFromAttributeValue(newValue);
        break;
      case "scale":
        this.#setScaleFromAttributeValue(newValue);
        break;
      case "zoom":
        this.#setZoomFromAttributeValue(newValue);
        break;
    }
  }
}
class MirisCamera extends MirisPrimitive {
  static observedAttributes = [
    "position",
    "rotation",
    "scale",
    "zoom",
    "controls"
  ];
  #fov = 50;
  // prettier-ignore
  get fov() {
    return this.#fov;
  }
  set fov(fov) {
    if (this.threeObject) {
      this.threeObject.fov = fov;
      this.threeObject.updateProjectionMatrix();
    }
    this.#fov = fov;
  }
  #aspect = 1;
  // prettier-ignore
  get aspect() {
    return this.#aspect;
  }
  set aspect(aspect) {
    if (this.threeObject) {
      this.threeObject.aspect = aspect;
      this.threeObject.updateProjectionMatrix();
    }
    this.#aspect = aspect;
  }
  #near = 0.01;
  // prettier-ignore
  get near() {
    return this.#near;
  }
  set near(near) {
    if (this.threeObject) {
      this.threeObject.near = near;
      this.threeObject.updateProjectionMatrix();
    }
    this.#near = near;
  }
  #far = 300;
  // prettier-ignore
  get far() {
    return this.#far;
  }
  set far(far) {
    if (this.threeObject) {
      this.threeObject.far = far;
      this.threeObject.updateProjectionMatrix();
    }
    this.#far = far;
  }
  #controls = false;
  // prettier-ignore
  get controls() {
    return this.#controls;
  }
  // prettier-ignore
  /** Whether the user explicitly set the camera position (via HTML attribute or JS). */
  get positionExplicitlySet() {
    return this._positionExplicitlySet;
  }
  // prettier-ignore
  /** Whether the user explicitly set the camera rotation (via HTML attribute or JS). */
  get rotationExplicitlySet() {
    return this._rotationExplicitlySet;
  }
  set controls(controls) {
    if (controls === this.#controls) return;
    this.#controls = controls;
    if (controls) {
      this.setAttribute("controls", "");
      this.#control();
    } else {
      this.removeAttribute("controls");
      this.#uncontrol();
    }
  }
  threeObject = null;
  _enable() {
    this.threeObject = new PerspectiveCamera(
      this.fov,
      this.aspect,
      this.near,
      this.far
    );
    super._enable();
    if (this.controls) this.#control();
  }
  #control() {
    if (!this.controls || !this.threeObject) return;
    const scene = this.closest("miris-scene");
    if (scene) Bus.publish(scene, "control", this.threeObject);
  }
  #uncontrol() {
    if (this.controls || !this.threeObject) return;
    const scene = this.closest("miris-scene");
    if (scene) Bus.publish(scene, "uncontrol", this.threeObject);
  }
  connectedCallback() {
    this.closest("miris-scene")?.querySelectorAll("miris-camera");
    super.connectedCallback();
  }
  attributeChangedCallback(name, oldValue, newValue) {
    super.attributeChangedCallback(name, oldValue, newValue);
    switch (name) {
      case "controls":
        this.controls = newValue !== null;
        break;
    }
  }
}
class MirisGroup extends MirisPrimitive {
  threeObject = null;
  _enable() {
    this.threeObject = new Group();
    super._enable();
  }
}
const _changeEvent = { type: "change" };
const _startEvent = { type: "start" };
const _endEvent = { type: "end" };
const _ray = new Ray();
const _plane = new Plane();
const _TILT_LIMIT = Math.cos(70 * MathUtils.DEG2RAD);
const _v = new Vector3();
const _twoPI = 2 * Math.PI;
const _STATE = {
  NONE: -1,
  ROTATE: 0,
  DOLLY: 1,
  PAN: 2,
  TOUCH_ROTATE: 3,
  TOUCH_PAN: 4,
  TOUCH_DOLLY_PAN: 5,
  TOUCH_DOLLY_ROTATE: 6
};
const _EPS = 1e-6;
class OrbitControls extends Controls {
  /**
   * Constructs a new controls instance.
   *
   * @param {Object3D} object - The object that is managed by the controls.
   * @param {?HTMLElement} domElement - The HTML element used for event listeners.
   */
  constructor(object, domElement = null) {
    super(object, domElement);
    this.state = _STATE.NONE;
    this.target = new Vector3();
    this.cursor = new Vector3();
    this.minDistance = 0;
    this.maxDistance = Infinity;
    this.minZoom = 0;
    this.maxZoom = Infinity;
    this.minTargetRadius = 0;
    this.maxTargetRadius = Infinity;
    this.minPolarAngle = 0;
    this.maxPolarAngle = Math.PI;
    this.minAzimuthAngle = -Infinity;
    this.maxAzimuthAngle = Infinity;
    this.enableDamping = false;
    this.dampingFactor = 0.05;
    this.enableZoom = true;
    this.zoomSpeed = 1;
    this.enableRotate = true;
    this.rotateSpeed = 1;
    this.keyRotateSpeed = 1;
    this.enablePan = true;
    this.panSpeed = 1;
    this.screenSpacePanning = true;
    this.keyPanSpeed = 7;
    this.zoomToCursor = false;
    this.autoRotate = false;
    this.autoRotateSpeed = 2;
    this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
    this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
    this.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };
    this.target0 = this.target.clone();
    this.position0 = this.object.position.clone();
    this.zoom0 = this.object.zoom;
    this._domElementKeyEvents = null;
    this._lastPosition = new Vector3();
    this._lastQuaternion = new Quaternion();
    this._lastTargetPosition = new Vector3();
    this._quat = new Quaternion().setFromUnitVectors(object.up, new Vector3(0, 1, 0));
    this._quatInverse = this._quat.clone().invert();
    this._spherical = new Spherical();
    this._sphericalDelta = new Spherical();
    this._scale = 1;
    this._panOffset = new Vector3();
    this._rotateStart = new Vector2();
    this._rotateEnd = new Vector2();
    this._rotateDelta = new Vector2();
    this._panStart = new Vector2();
    this._panEnd = new Vector2();
    this._panDelta = new Vector2();
    this._dollyStart = new Vector2();
    this._dollyEnd = new Vector2();
    this._dollyDelta = new Vector2();
    this._dollyDirection = new Vector3();
    this._mouse = new Vector2();
    this._performCursorZoom = false;
    this._pointers = [];
    this._pointerPositions = {};
    this._controlActive = false;
    this._onPointerMove = onPointerMove.bind(this);
    this._onPointerDown = onPointerDown.bind(this);
    this._onPointerUp = onPointerUp.bind(this);
    this._onContextMenu = onContextMenu.bind(this);
    this._onMouseWheel = onMouseWheel.bind(this);
    this._onKeyDown = onKeyDown.bind(this);
    this._onTouchStart = onTouchStart.bind(this);
    this._onTouchMove = onTouchMove.bind(this);
    this._onMouseDown = onMouseDown.bind(this);
    this._onMouseMove = onMouseMove.bind(this);
    this._interceptControlDown = interceptControlDown.bind(this);
    this._interceptControlUp = interceptControlUp.bind(this);
    if (this.domElement !== null) {
      this.connect(this.domElement);
    }
    this.update();
  }
  connect(element) {
    super.connect(element);
    this.domElement.addEventListener("pointerdown", this._onPointerDown);
    this.domElement.addEventListener("pointercancel", this._onPointerUp);
    this.domElement.addEventListener("contextmenu", this._onContextMenu);
    this.domElement.addEventListener("wheel", this._onMouseWheel, { passive: false });
    const document = this.domElement.getRootNode();
    document.addEventListener("keydown", this._interceptControlDown, { passive: true, capture: true });
    this.domElement.style.touchAction = "none";
  }
  disconnect() {
    this.domElement.removeEventListener("pointerdown", this._onPointerDown);
    this.domElement.ownerDocument.removeEventListener("pointermove", this._onPointerMove);
    this.domElement.ownerDocument.removeEventListener("pointerup", this._onPointerUp);
    this.domElement.removeEventListener("pointercancel", this._onPointerUp);
    this.domElement.removeEventListener("wheel", this._onMouseWheel);
    this.domElement.removeEventListener("contextmenu", this._onContextMenu);
    this.stopListenToKeyEvents();
    const document = this.domElement.getRootNode();
    document.removeEventListener("keydown", this._interceptControlDown, { capture: true });
    this.domElement.style.touchAction = "auto";
  }
  dispose() {
    this.disconnect();
  }
  /**
   * Get the current vertical rotation, in radians.
   *
   * @return {number} The current vertical rotation, in radians.
   */
  getPolarAngle() {
    return this._spherical.phi;
  }
  /**
   * Get the current horizontal rotation, in radians.
   *
   * @return {number} The current horizontal rotation, in radians.
   */
  getAzimuthalAngle() {
    return this._spherical.theta;
  }
  /**
   * Returns the distance from the camera to the target.
   *
   * @return {number} The distance from the camera to the target.
   */
  getDistance() {
    return this.object.position.distanceTo(this.target);
  }
  /**
   * Adds key event listeners to the given DOM element.
   * `window` is a recommended argument for using this method.
   *
   * @param {HTMLElement} domElement - The DOM element
   */
  listenToKeyEvents(domElement) {
    domElement.addEventListener("keydown", this._onKeyDown);
    this._domElementKeyEvents = domElement;
  }
  /**
   * Removes the key event listener previously defined with `listenToKeyEvents()`.
   */
  stopListenToKeyEvents() {
    if (this._domElementKeyEvents !== null) {
      this._domElementKeyEvents.removeEventListener("keydown", this._onKeyDown);
      this._domElementKeyEvents = null;
    }
  }
  /**
   * Save the current state of the controls. This can later be recovered with `reset()`.
   */
  saveState() {
    this.target0.copy(this.target);
    this.position0.copy(this.object.position);
    this.zoom0 = this.object.zoom;
  }
  /**
   * Reset the controls to their state from either the last time the `saveState()`
   * was called, or the initial state.
   */
  reset() {
    this.target.copy(this.target0);
    this.object.position.copy(this.position0);
    this.object.zoom = this.zoom0;
    this.object.updateProjectionMatrix();
    this.dispatchEvent(_changeEvent);
    this.update();
    this.state = _STATE.NONE;
  }
  update(deltaTime = null) {
    const position = this.object.position;
    _v.copy(position).sub(this.target);
    _v.applyQuaternion(this._quat);
    this._spherical.setFromVector3(_v);
    if (this.autoRotate && this.state === _STATE.NONE) {
      this._rotateLeft(this._getAutoRotationAngle(deltaTime));
    }
    if (this.enableDamping) {
      this._spherical.theta += this._sphericalDelta.theta * this.dampingFactor;
      this._spherical.phi += this._sphericalDelta.phi * this.dampingFactor;
    } else {
      this._spherical.theta += this._sphericalDelta.theta;
      this._spherical.phi += this._sphericalDelta.phi;
    }
    let min = this.minAzimuthAngle;
    let max = this.maxAzimuthAngle;
    if (isFinite(min) && isFinite(max)) {
      if (min < -Math.PI) min += _twoPI;
      else if (min > Math.PI) min -= _twoPI;
      if (max < -Math.PI) max += _twoPI;
      else if (max > Math.PI) max -= _twoPI;
      if (min <= max) {
        this._spherical.theta = Math.max(min, Math.min(max, this._spherical.theta));
      } else {
        this._spherical.theta = this._spherical.theta > (min + max) / 2 ? Math.max(min, this._spherical.theta) : Math.min(max, this._spherical.theta);
      }
    }
    this._spherical.phi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this._spherical.phi));
    this._spherical.makeSafe();
    if (this.enableDamping === true) {
      this.target.addScaledVector(this._panOffset, this.dampingFactor);
    } else {
      this.target.add(this._panOffset);
    }
    this.target.sub(this.cursor);
    this.target.clampLength(this.minTargetRadius, this.maxTargetRadius);
    this.target.add(this.cursor);
    let zoomChanged = false;
    if (this.zoomToCursor && this._performCursorZoom || this.object.isOrthographicCamera) {
      this._spherical.radius = this._clampDistance(this._spherical.radius);
    } else {
      const prevRadius = this._spherical.radius;
      this._spherical.radius = this._clampDistance(this._spherical.radius * this._scale);
      zoomChanged = prevRadius != this._spherical.radius;
    }
    _v.setFromSpherical(this._spherical);
    _v.applyQuaternion(this._quatInverse);
    position.copy(this.target).add(_v);
    this.object.lookAt(this.target);
    if (this.enableDamping === true) {
      this._sphericalDelta.theta *= 1 - this.dampingFactor;
      this._sphericalDelta.phi *= 1 - this.dampingFactor;
      this._panOffset.multiplyScalar(1 - this.dampingFactor);
    } else {
      this._sphericalDelta.set(0, 0, 0);
      this._panOffset.set(0, 0, 0);
    }
    if (this.zoomToCursor && this._performCursorZoom) {
      let newRadius = null;
      if (this.object.isPerspectiveCamera) {
        const prevRadius = _v.length();
        newRadius = this._clampDistance(prevRadius * this._scale);
        const radiusDelta = prevRadius - newRadius;
        this.object.position.addScaledVector(this._dollyDirection, radiusDelta);
        this.object.updateMatrixWorld();
        zoomChanged = !!radiusDelta;
      } else if (this.object.isOrthographicCamera) {
        const mouseBefore = new Vector3(this._mouse.x, this._mouse.y, 0);
        mouseBefore.unproject(this.object);
        const prevZoom = this.object.zoom;
        this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / this._scale));
        this.object.updateProjectionMatrix();
        zoomChanged = prevZoom !== this.object.zoom;
        const mouseAfter = new Vector3(this._mouse.x, this._mouse.y, 0);
        mouseAfter.unproject(this.object);
        this.object.position.sub(mouseAfter).add(mouseBefore);
        this.object.updateMatrixWorld();
        newRadius = _v.length();
      } else {
        console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled.");
        this.zoomToCursor = false;
      }
      if (newRadius !== null) {
        if (this.screenSpacePanning) {
          this.target.set(0, 0, -1).transformDirection(this.object.matrix).multiplyScalar(newRadius).add(this.object.position);
        } else {
          _ray.origin.copy(this.object.position);
          _ray.direction.set(0, 0, -1).transformDirection(this.object.matrix);
          if (Math.abs(this.object.up.dot(_ray.direction)) < _TILT_LIMIT) {
            this.object.lookAt(this.target);
          } else {
            _plane.setFromNormalAndCoplanarPoint(this.object.up, this.target);
            _ray.intersectPlane(_plane, this.target);
          }
        }
      }
    } else if (this.object.isOrthographicCamera) {
      const prevZoom = this.object.zoom;
      this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / this._scale));
      if (prevZoom !== this.object.zoom) {
        this.object.updateProjectionMatrix();
        zoomChanged = true;
      }
    }
    this._scale = 1;
    this._performCursorZoom = false;
    if (zoomChanged || this._lastPosition.distanceToSquared(this.object.position) > _EPS || 8 * (1 - this._lastQuaternion.dot(this.object.quaternion)) > _EPS || this._lastTargetPosition.distanceToSquared(this.target) > _EPS) {
      this.dispatchEvent(_changeEvent);
      this._lastPosition.copy(this.object.position);
      this._lastQuaternion.copy(this.object.quaternion);
      this._lastTargetPosition.copy(this.target);
      return true;
    }
    return false;
  }
  _getAutoRotationAngle(deltaTime) {
    if (deltaTime !== null) {
      return _twoPI / 60 * this.autoRotateSpeed * deltaTime;
    } else {
      return _twoPI / 60 / 60 * this.autoRotateSpeed;
    }
  }
  _getZoomScale(delta) {
    const normalizedDelta = Math.abs(delta * 0.01);
    return Math.pow(0.95, this.zoomSpeed * normalizedDelta);
  }
  _rotateLeft(angle) {
    this._sphericalDelta.theta -= angle;
  }
  _rotateUp(angle) {
    this._sphericalDelta.phi -= angle;
  }
  _panLeft(distance, objectMatrix) {
    _v.setFromMatrixColumn(objectMatrix, 0);
    _v.multiplyScalar(-distance);
    this._panOffset.add(_v);
  }
  _panUp(distance, objectMatrix) {
    if (this.screenSpacePanning === true) {
      _v.setFromMatrixColumn(objectMatrix, 1);
    } else {
      _v.setFromMatrixColumn(objectMatrix, 0);
      _v.crossVectors(this.object.up, _v);
    }
    _v.multiplyScalar(distance);
    this._panOffset.add(_v);
  }
  // deltaX and deltaY are in pixels; right and down are positive
  _pan(deltaX, deltaY) {
    const element = this.domElement;
    if (this.object.isPerspectiveCamera) {
      const position = this.object.position;
      _v.copy(position).sub(this.target);
      let targetDistance = _v.length();
      targetDistance *= Math.tan(this.object.fov / 2 * Math.PI / 180);
      this._panLeft(2 * deltaX * targetDistance / element.clientHeight, this.object.matrix);
      this._panUp(2 * deltaY * targetDistance / element.clientHeight, this.object.matrix);
    } else if (this.object.isOrthographicCamera) {
      this._panLeft(deltaX * (this.object.right - this.object.left) / this.object.zoom / element.clientWidth, this.object.matrix);
      this._panUp(deltaY * (this.object.top - this.object.bottom) / this.object.zoom / element.clientHeight, this.object.matrix);
    } else {
      console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.");
      this.enablePan = false;
    }
  }
  _dollyOut(dollyScale) {
    if (this.object.isPerspectiveCamera || this.object.isOrthographicCamera) {
      this._scale /= dollyScale;
    } else {
      console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
      this.enableZoom = false;
    }
  }
  _dollyIn(dollyScale) {
    if (this.object.isPerspectiveCamera || this.object.isOrthographicCamera) {
      this._scale *= dollyScale;
    } else {
      console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
      this.enableZoom = false;
    }
  }
  _updateZoomParameters(x, y) {
    if (!this.zoomToCursor) {
      return;
    }
    this._performCursorZoom = true;
    const rect = this.domElement.getBoundingClientRect();
    const dx = x - rect.left;
    const dy = y - rect.top;
    const w = rect.width;
    const h = rect.height;
    this._mouse.x = dx / w * 2 - 1;
    this._mouse.y = -(dy / h) * 2 + 1;
    this._dollyDirection.set(this._mouse.x, this._mouse.y, 1).unproject(this.object).sub(this.object.position).normalize();
  }
  _clampDistance(dist) {
    return Math.max(this.minDistance, Math.min(this.maxDistance, dist));
  }
  //
  // event callbacks - update the object state
  //
  _handleMouseDownRotate(event) {
    this._rotateStart.set(event.clientX, event.clientY);
  }
  _handleMouseDownDolly(event) {
    this._updateZoomParameters(event.clientX, event.clientX);
    this._dollyStart.set(event.clientX, event.clientY);
  }
  _handleMouseDownPan(event) {
    this._panStart.set(event.clientX, event.clientY);
  }
  _handleMouseMoveRotate(event) {
    this._rotateEnd.set(event.clientX, event.clientY);
    this._rotateDelta.subVectors(this._rotateEnd, this._rotateStart).multiplyScalar(this.rotateSpeed);
    const element = this.domElement;
    this._rotateLeft(_twoPI * this._rotateDelta.x / element.clientHeight);
    this._rotateUp(_twoPI * this._rotateDelta.y / element.clientHeight);
    this._rotateStart.copy(this._rotateEnd);
    this.update();
  }
  _handleMouseMoveDolly(event) {
    this._dollyEnd.set(event.clientX, event.clientY);
    this._dollyDelta.subVectors(this._dollyEnd, this._dollyStart);
    if (this._dollyDelta.y > 0) {
      this._dollyOut(this._getZoomScale(this._dollyDelta.y));
    } else if (this._dollyDelta.y < 0) {
      this._dollyIn(this._getZoomScale(this._dollyDelta.y));
    }
    this._dollyStart.copy(this._dollyEnd);
    this.update();
  }
  _handleMouseMovePan(event) {
    this._panEnd.set(event.clientX, event.clientY);
    this._panDelta.subVectors(this._panEnd, this._panStart).multiplyScalar(this.panSpeed);
    this._pan(this._panDelta.x, this._panDelta.y);
    this._panStart.copy(this._panEnd);
    this.update();
  }
  _handleMouseWheel(event) {
    this._updateZoomParameters(event.clientX, event.clientY);
    if (event.deltaY < 0) {
      this._dollyIn(this._getZoomScale(event.deltaY));
    } else if (event.deltaY > 0) {
      this._dollyOut(this._getZoomScale(event.deltaY));
    }
    this.update();
  }
  _handleKeyDown(event) {
    let needsUpdate = false;
    switch (event.code) {
      case this.keys.UP:
        if (event.ctrlKey || event.metaKey || event.shiftKey) {
          if (this.enableRotate) {
            this._rotateUp(_twoPI * this.keyRotateSpeed / this.domElement.clientHeight);
          }
        } else {
          if (this.enablePan) {
            this._pan(0, this.keyPanSpeed);
          }
        }
        needsUpdate = true;
        break;
      case this.keys.BOTTOM:
        if (event.ctrlKey || event.metaKey || event.shiftKey) {
          if (this.enableRotate) {
            this._rotateUp(-_twoPI * this.keyRotateSpeed / this.domElement.clientHeight);
          }
        } else {
          if (this.enablePan) {
            this._pan(0, -this.keyPanSpeed);
          }
        }
        needsUpdate = true;
        break;
      case this.keys.LEFT:
        if (event.ctrlKey || event.metaKey || event.shiftKey) {
          if (this.enableRotate) {
            this._rotateLeft(_twoPI * this.keyRotateSpeed / this.domElement.clientHeight);
          }
        } else {
          if (this.enablePan) {
            this._pan(this.keyPanSpeed, 0);
          }
        }
        needsUpdate = true;
        break;
      case this.keys.RIGHT:
        if (event.ctrlKey || event.metaKey || event.shiftKey) {
          if (this.enableRotate) {
            this._rotateLeft(-_twoPI * this.keyRotateSpeed / this.domElement.clientHeight);
          }
        } else {
          if (this.enablePan) {
            this._pan(-this.keyPanSpeed, 0);
          }
        }
        needsUpdate = true;
        break;
    }
    if (needsUpdate) {
      event.preventDefault();
      this.update();
    }
  }
  _handleTouchStartRotate(event) {
    if (this._pointers.length === 1) {
      this._rotateStart.set(event.pageX, event.pageY);
    } else {
      const position = this._getSecondPointerPosition(event);
      const x = 0.5 * (event.pageX + position.x);
      const y = 0.5 * (event.pageY + position.y);
      this._rotateStart.set(x, y);
    }
  }
  _handleTouchStartPan(event) {
    if (this._pointers.length === 1) {
      this._panStart.set(event.pageX, event.pageY);
    } else {
      const position = this._getSecondPointerPosition(event);
      const x = 0.5 * (event.pageX + position.x);
      const y = 0.5 * (event.pageY + position.y);
      this._panStart.set(x, y);
    }
  }
  _handleTouchStartDolly(event) {
    const position = this._getSecondPointerPosition(event);
    const dx = event.pageX - position.x;
    const dy = event.pageY - position.y;
    const distance = Math.sqrt(dx * dx + dy * dy);
    this._dollyStart.set(0, distance);
  }
  _handleTouchStartDollyPan(event) {
    if (this.enableZoom) this._handleTouchStartDolly(event);
    if (this.enablePan) this._handleTouchStartPan(event);
  }
  _handleTouchStartDollyRotate(event) {
    if (this.enableZoom) this._handleTouchStartDolly(event);
    if (this.enableRotate) this._handleTouchStartRotate(event);
  }
  _handleTouchMoveRotate(event) {
    if (this._pointers.length == 1) {
      this._rotateEnd.set(event.pageX, event.pageY);
    } else {
      const position = this._getSecondPointerPosition(event);
      const x = 0.5 * (event.pageX + position.x);
      const y = 0.5 * (event.pageY + position.y);
      this._rotateEnd.set(x, y);
    }
    this._rotateDelta.subVectors(this._rotateEnd, this._rotateStart).multiplyScalar(this.rotateSpeed);
    const element = this.domElement;
    this._rotateLeft(_twoPI * this._rotateDelta.x / element.clientHeight);
    this._rotateUp(_twoPI * this._rotateDelta.y / element.clientHeight);
    this._rotateStart.copy(this._rotateEnd);
  }
  _handleTouchMovePan(event) {
    if (this._pointers.length === 1) {
      this._panEnd.set(event.pageX, event.pageY);
    } else {
      const position = this._getSecondPointerPosition(event);
      const x = 0.5 * (event.pageX + position.x);
      const y = 0.5 * (event.pageY + position.y);
      this._panEnd.set(x, y);
    }
    this._panDelta.subVectors(this._panEnd, this._panStart).multiplyScalar(this.panSpeed);
    this._pan(this._panDelta.x, this._panDelta.y);
    this._panStart.copy(this._panEnd);
  }
  _handleTouchMoveDolly(event) {
    const position = this._getSecondPointerPosition(event);
    const dx = event.pageX - position.x;
    const dy = event.pageY - position.y;
    const distance = Math.sqrt(dx * dx + dy * dy);
    this._dollyEnd.set(0, distance);
    this._dollyDelta.set(0, Math.pow(this._dollyEnd.y / this._dollyStart.y, this.zoomSpeed));
    this._dollyOut(this._dollyDelta.y);
    this._dollyStart.copy(this._dollyEnd);
    const centerX = (event.pageX + position.x) * 0.5;
    const centerY = (event.pageY + position.y) * 0.5;
    this._updateZoomParameters(centerX, centerY);
  }
  _handleTouchMoveDollyPan(event) {
    if (this.enableZoom) this._handleTouchMoveDolly(event);
    if (this.enablePan) this._handleTouchMovePan(event);
  }
  _handleTouchMoveDollyRotate(event) {
    if (this.enableZoom) this._handleTouchMoveDolly(event);
    if (this.enableRotate) this._handleTouchMoveRotate(event);
  }
  // pointers
  _addPointer(event) {
    this._pointers.push(event.pointerId);
  }
  _removePointer(event) {
    delete this._pointerPositions[event.pointerId];
    for (let i = 0; i < this._pointers.length; i++) {
      if (this._pointers[i] == event.pointerId) {
        this._pointers.splice(i, 1);
        return;
      }
    }
  }
  _isTrackingPointer(event) {
    for (let i = 0; i < this._pointers.length; i++) {
      if (this._pointers[i] == event.pointerId) return true;
    }
    return false;
  }
  _trackPointer(event) {
    let position = this._pointerPositions[event.pointerId];
    if (position === void 0) {
      position = new Vector2();
      this._pointerPositions[event.pointerId] = position;
    }
    position.set(event.pageX, event.pageY);
  }
  _getSecondPointerPosition(event) {
    const pointerId = event.pointerId === this._pointers[0] ? this._pointers[1] : this._pointers[0];
    return this._pointerPositions[pointerId];
  }
  //
  _customWheelEvent(event) {
    const mode = event.deltaMode;
    const newEvent = {
      clientX: event.clientX,
      clientY: event.clientY,
      deltaY: event.deltaY
    };
    switch (mode) {
      case 1:
        newEvent.deltaY *= 16;
        break;
      case 2:
        newEvent.deltaY *= 100;
        break;
    }
    if (event.ctrlKey && !this._controlActive) {
      newEvent.deltaY *= 10;
    }
    return newEvent;
  }
}
function onPointerDown(event) {
  if (this.enabled === false) return;
  if (this._pointers.length === 0) {
    this.domElement.setPointerCapture(event.pointerId);
    this.domElement.ownerDocument.addEventListener("pointermove", this._onPointerMove);
    this.domElement.ownerDocument.addEventListener("pointerup", this._onPointerUp);
  }
  if (this._isTrackingPointer(event)) return;
  this._addPointer(event);
  if (event.pointerType === "touch") {
    this._onTouchStart(event);
  } else {
    this._onMouseDown(event);
  }
}
function onPointerMove(event) {
  if (this.enabled === false) return;
  if (event.pointerType === "touch") {
    this._onTouchMove(event);
  } else {
    this._onMouseMove(event);
  }
}
function onPointerUp(event) {
  this._removePointer(event);
  switch (this._pointers.length) {
    case 0:
      this.domElement.releasePointerCapture(event.pointerId);
      this.domElement.ownerDocument.removeEventListener("pointermove", this._onPointerMove);
      this.domElement.ownerDocument.removeEventListener("pointerup", this._onPointerUp);
      this.dispatchEvent(_endEvent);
      this.state = _STATE.NONE;
      break;
    case 1:
      const pointerId = this._pointers[0];
      const position = this._pointerPositions[pointerId];
      this._onTouchStart({ pointerId, pageX: position.x, pageY: position.y });
      break;
  }
}
function onMouseDown(event) {
  let mouseAction;
  switch (event.button) {
    case 0:
      mouseAction = this.mouseButtons.LEFT;
      break;
    case 1:
      mouseAction = this.mouseButtons.MIDDLE;
      break;
    case 2:
      mouseAction = this.mouseButtons.RIGHT;
      break;
    default:
      mouseAction = -1;
  }
  switch (mouseAction) {
    case MOUSE.DOLLY:
      if (this.enableZoom === false) return;
      this._handleMouseDownDolly(event);
      this.state = _STATE.DOLLY;
      break;
    case MOUSE.ROTATE:
      if (event.ctrlKey || event.metaKey || event.shiftKey) {
        if (this.enablePan === false) return;
        this._handleMouseDownPan(event);
        this.state = _STATE.PAN;
      } else {
        if (this.enableRotate === false) return;
        this._handleMouseDownRotate(event);
        this.state = _STATE.ROTATE;
      }
      break;
    case MOUSE.PAN:
      if (event.ctrlKey || event.metaKey || event.shiftKey) {
        if (this.enableRotate === false) return;
        this._handleMouseDownRotate(event);
        this.state = _STATE.ROTATE;
      } else {
        if (this.enablePan === false) return;
        this._handleMouseDownPan(event);
        this.state = _STATE.PAN;
      }
      break;
    default:
      this.state = _STATE.NONE;
  }
  if (this.state !== _STATE.NONE) {
    this.dispatchEvent(_startEvent);
  }
}
function onMouseMove(event) {
  switch (this.state) {
    case _STATE.ROTATE:
      if (this.enableRotate === false) return;
      this._handleMouseMoveRotate(event);
      break;
    case _STATE.DOLLY:
      if (this.enableZoom === false) return;
      this._handleMouseMoveDolly(event);
      break;
    case _STATE.PAN:
      if (this.enablePan === false) return;
      this._handleMouseMovePan(event);
      break;
  }
}
function onMouseWheel(event) {
  if (this.enabled === false || this.enableZoom === false || this.state !== _STATE.NONE) return;
  event.preventDefault();
  this.dispatchEvent(_startEvent);
  this._handleMouseWheel(this._customWheelEvent(event));
  this.dispatchEvent(_endEvent);
}
function onKeyDown(event) {
  if (this.enabled === false) return;
  this._handleKeyDown(event);
}
function onTouchStart(event) {
  this._trackPointer(event);
  switch (this._pointers.length) {
    case 1:
      switch (this.touches.ONE) {
        case TOUCH.ROTATE:
          if (this.enableRotate === false) return;
          this._handleTouchStartRotate(event);
          this.state = _STATE.TOUCH_ROTATE;
          break;
        case TOUCH.PAN:
          if (this.enablePan === false) return;
          this._handleTouchStartPan(event);
          this.state = _STATE.TOUCH_PAN;
          break;
        default:
          this.state = _STATE.NONE;
      }
      break;
    case 2:
      switch (this.touches.TWO) {
        case TOUCH.DOLLY_PAN:
          if (this.enableZoom === false && this.enablePan === false) return;
          this._handleTouchStartDollyPan(event);
          this.state = _STATE.TOUCH_DOLLY_PAN;
          break;
        case TOUCH.DOLLY_ROTATE:
          if (this.enableZoom === false && this.enableRotate === false) return;
          this._handleTouchStartDollyRotate(event);
          this.state = _STATE.TOUCH_DOLLY_ROTATE;
          break;
        default:
          this.state = _STATE.NONE;
      }
      break;
    default:
      this.state = _STATE.NONE;
  }
  if (this.state !== _STATE.NONE) {
    this.dispatchEvent(_startEvent);
  }
}
function onTouchMove(event) {
  this._trackPointer(event);
  switch (this.state) {
    case _STATE.TOUCH_ROTATE:
      if (this.enableRotate === false) return;
      this._handleTouchMoveRotate(event);
      this.update();
      break;
    case _STATE.TOUCH_PAN:
      if (this.enablePan === false) return;
      this._handleTouchMovePan(event);
      this.update();
      break;
    case _STATE.TOUCH_DOLLY_PAN:
      if (this.enableZoom === false && this.enablePan === false) return;
      this._handleTouchMoveDollyPan(event);
      this.update();
      break;
    case _STATE.TOUCH_DOLLY_ROTATE:
      if (this.enableZoom === false && this.enableRotate === false) return;
      this._handleTouchMoveDollyRotate(event);
      this.update();
      break;
    default:
      this.state = _STATE.NONE;
  }
}
function onContextMenu(event) {
  if (this.enabled === false) return;
  event.preventDefault();
}
function interceptControlDown(event) {
  if (event.key === "Control") {
    this._controlActive = true;
    const document = this.domElement.getRootNode();
    document.addEventListener("keyup", this._interceptControlUp, { passive: true, capture: true });
  }
}
function interceptControlUp(event) {
  if (event.key === "Control") {
    this._controlActive = false;
    const document = this.domElement.getRootNode();
    document.removeEventListener("keyup", this._interceptControlUp, { passive: true, capture: true });
  }
}
const _MirisScene = class _MirisScene extends HTMLElement {
  constructor() {
    super();
    __privateAdd(this, _MirisScene_instances);
    __privateAdd(this, _renderer, null);
    __privateAdd(this, _scene, null);
    __privateAdd(this, _camera, null);
    __privateAdd(this, _cameraControls, null);
    __privateAdd(this, _observer, null);
    __privateAdd(this, _shadow);
    __privateAdd(this, _objectDragging, false);
    __privateAdd(this, _exposure, null);
    __privateAdd(this, _ready);
    __privateAdd(this, _readyResolve);
    __privateAdd(this, _readyReject);
    __privateAdd(this, _isReadySettled, false);
    __privateAdd(this, _viewerKey, null);
    __privateAdd(this, _needsRender, true);
    __privateMethod(this, _MirisScene_instances, initReadyPromise_fn).call(this);
    __privateSet(this, _shadow, this.attachShadow({ mode: "closed" }));
    __privateGet(this, _shadow).adoptedStyleSheets.push(__privateGet(_MirisScene, _styleSheet));
  }
  get threeCamera() {
    return __privateGet(this, _camera);
  }
  set threeCamera(camera) {
    __privateSet(this, _camera, camera);
  }
  get exposure() {
    return __privateGet(this, _exposure);
  }
  set exposure(exposure) {
    if (exposure === __privateGet(this, _exposure)) {
      return;
    }
    __privateSet(this, _exposure, exposure);
    if (null !== exposure) {
      if (__privateGet(this, _renderer)) {
        __privateGet(this, _renderer).domElement.style.setProperty(
          "filter",
          `brightness(${exposure})`
        );
      }
      this.setAttribute("exposure", String(exposure));
    } else {
      if (__privateGet(this, _renderer)) {
        __privateGet(this, _renderer).domElement.style.removeProperty("filter");
      }
      this.removeAttribute("exposure");
    }
  }
  // prettier-ignore
  get cameraControls() {
    return __privateGet(this, _cameraControls);
  }
  get ready() {
    return __privateGet(this, _ready);
  }
  get _scene() {
    if (!__privateGet(this, _scene)) {
      throw new Error("Scene has not yet been initialized.");
    }
    return __privateGet(this, _scene);
  }
  get viewerKey() {
    return __privateGet(this, _viewerKey);
  }
  set viewerKey(viewerKey) {
    if (viewerKey === __privateGet(this, _viewerKey)) return;
    if (__privateGet(this, _scene)) __privateGet(this, _scene).viewerKey = viewerKey;
    __privateSet(this, _viewerKey, viewerKey);
    if (viewerKey) this.setAttribute("viewer-key", viewerKey);
    else this.removeAttribute("viewer-key");
  }
  async connectedCallback() {
    if (__privateGet(this, _isReadySettled)) {
      __privateMethod(this, _MirisScene_instances, initReadyPromise_fn).call(this);
    }
    const camera = __privateSet(this, _camera, new PerspectiveCamera());
    const renderer = __privateSet(this, _renderer, new WebGLRenderer({
      alpha: true,
      preserveDrawingBuffer: true
    }));
    const objectControls = new MirisControls(
      null,
      camera,
      renderer.domElement
    );
    const cameraControls = __privateSet(this, _cameraControls, new OrbitControls(
      camera,
      renderer.domElement
    ));
    const scene = __privateSet(this, _scene, new MirisScene$1({ viewerKey: this.viewerKey }));
    const observer = __privateSet(this, _observer, new ResizeObserver((entries) => {
      const entry = entries[entries.length - 1];
      const width = entry.contentBoxSize[0].inlineSize;
      const height = entry.contentBoxSize[0].blockSize;
      renderer.setPixelRatio(devicePixelRatio);
      renderer.setSize(width, height, false);
      if (__privateGet(this, _camera)) {
        __privateGet(this, _camera).aspect = width / height;
        __privateGet(this, _camera).updateProjectionMatrix();
      }
    }));
    __privateGet(this, _shadow).append(renderer.domElement);
    observer.observe(this);
    objectControls.addEventListener("start", () => {
      __privateSet(this, _objectDragging, true);
    });
    objectControls.addEventListener("end", () => {
      __privateSet(this, _objectDragging, false);
    });
    Bus.subscribe(this, "add", (object) => {
      if (scene.children.includes(object)) return;
      if (object instanceof PerspectiveCamera) {
        if (__privateGet(this, _camera)) scene.remove(__privateGet(this, _camera));
        objectControls.object = object;
        __privateSet(this, _camera, object);
      }
      scene.add(object);
      this._forceRender();
    });
    Bus.subscribe(this, "remove", (object) => {
      if (object instanceof PerspectiveCamera) {
        scene.remove(object);
        __privateSet(this, _camera, new PerspectiveCamera());
      }
      scene.remove(object);
      this._forceRender();
    });
    Bus.subscribe(this, "control", (object) => {
      if (object instanceof PerspectiveCamera) {
        cameraControls.object = object;
        cameraControls.enabled = true;
      } else objectControls.objects.add(object);
    });
    Bus.subscribe(this, "uncontrol", (object) => {
      cameraControls.enabled = false;
      objectControls.objects.delete(object);
    });
    const sceneResolve = __privateGet(this, _readyResolve);
    const sceneReject = __privateGet(this, _readyReject);
    try {
      await scene.ready;
    } catch (error) {
      sceneReject(error);
      return;
    }
    sceneResolve(this);
    await this._setupAnimationLoop();
    renderer.xr.enabled = true;
    if (null !== this.exposure) {
      renderer.domElement.style.setProperty(
        "filter",
        `brightness(${this.exposure})`
      );
    }
    scene.addEventListener("sceneloaded", () => {
      __privateMethod(this, _MirisScene_instances, onSceneLoaded_fn).call(this);
    });
    __privateMethod(this, _MirisScene_instances, adjustCameraClipPlanes_fn).call(this);
    objectControls.addEventListener("start", () => {
      const { enabled } = cameraControls;
      cameraControls.enabled = false;
      objectControls.addEventListener("end", () => {
        cameraControls.enabled = enabled;
      });
    });
  }
  /**
   * @internal
   */
  async _setupAnimationLoop() {
    const miris = await Miris.instance();
    __privateGet(this, _scene).matrixWorldAutoUpdate = false;
    __privateGet(this, _renderer)?.setAnimationLoop(() => {
      __privateGet(this, _cameraControls)?.update();
      __privateGet(this, _scene)?.updateMatrixWorld();
      if (__privateGet(this, _camera)) {
        __privateGet(this, _camera).updateWorldMatrix(true, false);
        const coreCamera = __privateGet(this, _scene)?.coreScene?.camera;
        if (coreCamera) {
          coreCamera.matrix = __privateGet(this, _camera).matrixWorld.toArray();
          coreCamera.aspect = __privateGet(this, _camera).aspect;
          coreCamera.fov = __privateGet(this, _camera).fov;
          coreCamera.near = __privateGet(this, _camera).near;
          coreCamera.far = __privateGet(this, _camera).far;
        }
      }
      const needsRender = miris.update();
      if ((needsRender || __privateGet(this, _needsRender) || __privateGet(this, _objectDragging)) && __privateGet(this, _camera)) {
        this.dispatchEvent(new CustomEvent("prerenderupdate"));
        __privateGet(this, _renderer)?.render(__privateGet(this, _scene), __privateGet(this, _camera));
        this.dispatchEvent(new CustomEvent("postrenderupdate"));
        __privateSet(this, _needsRender, false);
      }
    });
  }
  /**
   * @internal
   */
  _getRenderStats() {
    return {
      callCount: __privateGet(this, _renderer)?.info.render.calls,
      programCount: __privateGet(this, _renderer)?.info.programs?.length,
      triangleCount: __privateGet(this, _renderer)?.info.render.triangles,
      gpuTextures: __privateGet(this, _renderer)?.info.memory.textures,
      gpuGeometries: __privateGet(this, _renderer)?.info.memory.geometries
    };
  }
  disconnectedCallback() {
    __privateGet(this, _readyReject).call(this, new Error("Scene disconnected"));
    __privateGet(this, _observer)?.disconnect();
    __privateSet(this, _observer, null);
    __privateGet(this, _renderer)?.setAnimationLoop(null);
    __privateGet(this, _renderer)?.dispose();
    __privateSet(this, _renderer, null);
    Bus.unsubscribe(this, "add");
    Bus.unsubscribe(this, "remove");
    Bus.unsubscribe(this, "control");
    Bus.unsubscribe(this, "uncontrol");
    __privateGet(this, _scene)?.dispose();
  }
  attributeChangedCallback(name, _oldValue, newValue) {
    switch (name) {
      case "exposure":
        this.exposure = null !== newValue ? Number(newValue) : newValue;
        break;
      case "viewer-key":
        this.viewerKey = newValue;
        break;
    }
  }
  setViewerKey(viewerKey) {
    this.viewerKey = viewerKey;
  }
  _forceRender() {
    __privateSet(this, _needsRender, true);
  }
  fetchAssets(...args) {
    if (!__privateGet(this, _scene)) {
      throw new Error("Scene has not yet been initialized.");
    }
    return __privateGet(this, _scene).fetchAssets(...args);
  }
  get coreScene() {
    return __privateGet(this, _scene)?.coreScene;
  }
  get threeScene() {
    return __privateGet(this, _scene);
  }
  get threeRenderer() {
    return __privateGet(this, _renderer);
  }
};
_styleSheet = new WeakMap();
_renderer = new WeakMap();
_scene = new WeakMap();
_camera = new WeakMap();
_cameraControls = new WeakMap();
_observer = new WeakMap();
_shadow = new WeakMap();
_objectDragging = new WeakMap();
_exposure = new WeakMap();
_ready = new WeakMap();
_readyResolve = new WeakMap();
_readyReject = new WeakMap();
_isReadySettled = new WeakMap();
_MirisScene_instances = new WeakSet();
initReadyPromise_fn = function() {
  __privateSet(this, _isReadySettled, false);
  __privateSet(this, _ready, new Promise((resolve, reject) => {
    __privateSet(this, _readyResolve, (scene) => {
      if (!__privateGet(this, _isReadySettled)) {
        __privateSet(this, _isReadySettled, true);
        resolve(scene);
      }
    });
    __privateSet(this, _readyReject, (reason) => {
      if (!__privateGet(this, _isReadySettled)) {
        __privateSet(this, _isReadySettled, true);
        reject(reason);
      }
    });
  }));
  __privateGet(this, _ready).catch(() => {
  });
};
_viewerKey = new WeakMap();
_needsRender = new WeakMap();
adjustCameraClipPlanes_fn = function(near = 0.01, far = 300) {
  if (__privateGet(this, _camera)) {
    __privateGet(this, _camera).near = near;
    __privateGet(this, _camera).far = far;
    __privateGet(this, _camera).updateProjectionMatrix();
  }
};
onSceneLoaded_fn = function() {
  __privateMethod(this, _MirisScene_instances, updateStreamBounds_fn).call(this);
  __privateMethod(this, _MirisScene_instances, checkForDefaultCamera_fn).call(this);
  this.dispatchEvent(new CustomEvent("sceneloaded", { bubbles: true }));
};
updateStreamBounds_fn = function() {
  if (this.threeCamera && __privateGet(this, _scene)) {
    let hasValidBounds = false;
    let largestMagnitude = 0;
    for (const child of __privateGet(this, _scene).children) {
      if (child instanceof MirisStream$1) {
        const bounds = child.getBounds();
        const [sx = 0, sy = 0, sz = 0] = bounds.size;
        if (!Number.isFinite(sx) || !Number.isFinite(sy) || !Number.isFinite(sz) || sx === 0 && sy === 0 && sz === 0) {
          continue;
        }
        const magnitude = Math.hypot(sx, sy, sz);
        if (Number.isFinite(magnitude) && magnitude > 0) {
          largestMagnitude = Math.max(magnitude, largestMagnitude);
          hasValidBounds = true;
        }
      }
    }
    if (!hasValidBounds || !Number.isFinite(largestMagnitude) || largestMagnitude <= 0) {
      return;
    }
    __privateMethod(this, _MirisScene_instances, adjustCameraClipPlanes_fn).call(this, largestMagnitude * 1e-3, largestMagnitude * 100);
  }
};
checkForDefaultCamera_fn = function() {
  const transform = __privateGet(this, _scene)?.coreScene?.getDefaultCameraTransform();
  if (!transform || !__privateGet(this, _camera)) return;
  const cameraElement = this.querySelector(
    "miris-camera"
  );
  const userSetPosition = cameraElement?.positionExplicitlySet ?? false;
  const userSetRotation = cameraElement?.rotationExplicitlySet ?? false;
  if (userSetPosition && userSetRotation) return;
  if (!userSetPosition && !userSetRotation) {
    new Matrix4().fromArray(transform).decompose(
      __privateGet(this, _camera).position,
      __privateGet(this, _camera).quaternion,
      new Vector3()
      // scale (unused)
    );
    return;
  }
  const position = new Vector3();
  const quaternion = new Quaternion();
  new Matrix4().fromArray(transform).decompose(position, quaternion, new Vector3());
  if (!userSetPosition) __privateGet(this, _camera).position.copy(position);
  if (!userSetRotation) __privateGet(this, _camera).quaternion.copy(quaternion);
};
__publicField(_MirisScene, "observedAttributes", ["exposure", "viewer-key"]);
__privateAdd(_MirisScene, _styleSheet);
__privateSet(_MirisScene, _styleSheet, new CSSStyleSheet());
__privateGet(_MirisScene, _styleSheet).replaceSync(`
      :host { display: block; }
      canvas { display: block; width: 100%; height: 100%; }
    `);
let MirisScene = _MirisScene;
class MirisStream extends MirisPrimitive {
  static observedAttributes = [
    "position",
    "rotation",
    "scale",
    "zoom",
    "auth-token",
    "controls",
    "disabled",
    "drm-key",
    "viewer-key",
    "uuid"
  ];
  #disabled = false;
  // prettier-ignore
  get disabled() {
    return this.#disabled;
  }
  set disabled(disabled) {
    if (disabled === this.#disabled) return;
    this.#disabled = disabled;
    if (disabled) {
      this.setAttribute("disabled", "");
      this._disable();
    } else {
      this.removeAttribute("disabled");
      this._enable();
    }
  }
  #uuid = null;
  // prettier-ignore
  get uuid() {
    return this.#uuid;
  }
  set uuid(uuid) {
    if (uuid === this.#uuid) return;
    if (this.threeObject) this.threeObject._clearBoxes();
    const oldUuid = this.#uuid;
    this.#uuid = uuid;
    if (uuid) {
      this.setAttribute("uuid", uuid);
      if (oldUuid) this._disable();
      this._enable();
    } else {
      this.removeAttribute("uuid");
      this._disable();
    }
  }
  #controls = false;
  // prettier-ignore
  get controls() {
    return this.#controls;
  }
  set controls(controls) {
    if (controls === this.#controls) return;
    this.#controls = controls;
    if (this.#orbitControls) this.#orbitControls.enabled = controls;
    if (controls) {
      this.setAttribute("controls", "");
      this.#control();
    } else {
      this.removeAttribute("controls");
      this.#uncontrol();
    }
  }
  #viewerKey = null;
  // prettier-ignore
  get viewerKey() {
    return this.#viewerKey;
  }
  set viewerKey(viewerKey) {
    if (viewerKey === this.#viewerKey) return;
    this.#viewerKey = viewerKey;
    if (viewerKey) this.setAttribute("viewer-key", viewerKey);
    else this.removeAttribute("viewer-key");
  }
  #authToken = null;
  // prettier-ignore
  get authToken() {
    return this.#authToken;
  }
  set authToken(authToken) {
    if (authToken === this.#authToken) return;
    this.#authToken = authToken;
    if (authToken) this.setAttribute("auth-token", authToken);
    else this.removeAttribute("auth-token");
  }
  #drmKey = null;
  // prettier-ignore
  get drmKey() {
    return this.#drmKey;
  }
  set drmKey(drmKey) {
    if (drmKey === this.#drmKey) return;
    this.#drmKey = drmKey;
    if (drmKey) this.setAttribute("drm-key", drmKey);
    else this.removeAttribute("drm-key");
  }
  threeObject = null;
  #camera = null;
  #orbitControls = null;
  #renderer = null;
  #observer = null;
  #shadow = null;
  #scene = null;
  constructor() {
    super();
    this.#viewerKey = this.getAttribute("viewer-key");
  }
  #enableScene() {
    if (this.#renderer) return;
    const renderer = new WebGLRenderer({
      alpha: true,
      preserveDrawingBuffer: true
    });
    const scene = new MirisScene$1({ viewerKey: this.viewerKey });
    const camera = new PerspectiveCamera();
    const controls = new OrbitControls(camera, renderer.domElement);
    const observer = new ResizeObserver((entries) => {
      const entry = entries[entries.length - 1];
      const width = entry.contentBoxSize[0].inlineSize;
      const height = entry.contentBoxSize[0].blockSize;
      renderer.setPixelRatio(devicePixelRatio);
      renderer.setSize(width, height, false);
      camera.aspect = width / height;
      camera.updateProjectionMatrix();
    });
    if (!this.#shadow) {
      this.#shadow = this.attachShadow({ mode: "closed" });
      const sheet = new CSSStyleSheet();
      sheet.insertRule(":host { display: block }");
      sheet.insertRule("canvas { display: block; width: 100%; height: 100% }");
      this.#shadow.adoptedStyleSheets.push(sheet);
      this.#shadow.append(renderer.domElement);
    }
    if (this.threeObject) scene.add(this.threeObject);
    controls.target.set(this.position.x, this.position.y, this.position.z);
    controls.enabled = this.controls;
    observer.observe(this);
    renderer.setAnimationLoop(() => {
      renderer.render(scene, camera);
      if (this.controls) controls.update();
    });
    this.#camera = camera;
    this.#orbitControls = controls;
    this.#renderer = renderer;
    this.#scene = scene;
    this.#observer = observer;
  }
  _enable() {
    if (this.disabled) return;
    if (!this.threeObject && this.uuid) {
      this.threeObject = new MirisStream$1({
        uuid: this.uuid,
        viewerKey: this.viewerKey ?? void 0,
        authToken: this.#authToken ?? void 0,
        drmKey: this.#drmKey ?? void 0
      });
      this.threeObject.name = this.uuid;
      this.threeObject.addEventListener("streamloaded", () => {
        this.#onStreamLoaded();
      });
      this.threeObject.addEventListener("rootloaded", () => {
        this.#onRootLoaded();
      });
    }
    super._enable();
    if (!this._parent && this.uuid && this.isConnected) this.#enableScene();
    if (this.#scene && this.threeObject) this.#scene.add(this.threeObject);
    if (this.controls) this.#control();
  }
  #disableScene() {
    if (this.#renderer) {
      this.#renderer?.dispose();
      this.#renderer = null;
    }
    if (this.#observer) {
      this.#observer?.disconnect();
      this.#observer = null;
    }
  }
  _disable() {
    if (!this._parent) this.#disableScene();
    if (this.threeObject) this.#scene?.remove(this.threeObject);
    if (this.controls) this.#uncontrol();
    super._disable();
  }
  #control() {
    if (!this.controls || !this.threeObject) return;
    const scene = this.closest("miris-scene");
    if (scene) Bus.publish(scene, "control", this.threeObject);
  }
  #uncontrol() {
    if (this.controls || !this.threeObject) return;
    const scene = this.closest("miris-scene");
    if (scene) Bus.publish(scene, "uncontrol", this.threeObject);
  }
  #onStreamLoaded() {
    this.dispatchEvent(new CustomEvent("streamloaded", { bubbles: true }));
  }
  #onRootLoaded() {
    this.dispatchEvent(new CustomEvent("rootloaded", { bubbles: true }));
  }
  attributeChangedCallback(name, oldValue, newValue) {
    super.attributeChangedCallback(name, oldValue, newValue);
    switch (name) {
      case "auth-token":
        this.#authToken = newValue;
        break;
      case "controls":
        this.controls = newValue !== null;
        break;
      case "drm-key":
        this.#drmKey = newValue;
        break;
      case "disabled":
        this.disabled = newValue !== null;
        break;
      case "viewer-key":
        this.#viewerKey = newValue;
        break;
      case "uuid":
        this.uuid = newValue;
        break;
    }
  }
  _update() {
    this.threeObject?._update();
  }
  getBounds() {
    if (this.threeObject) return this.threeObject.getBounds();
  }
  /**
   * @deprecated Use `getBounds` instead.
   */
  getObjectBounds() {
    if (this.threeObject) return this.threeObject.getBounds();
  }
  frameAsset(externalBounds) {
    const camera = this.#camera;
    if (!camera) return;
    const bounds = externalBounds ?? this.getBounds();
    if (!bounds) return;
    const distance = Math.max(
      bounds.size[0] * 2,
      bounds.size[1] * 2,
      bounds.size[2] * 2
    );
    if (distance === 0) return;
    const center = new Vector3(...bounds.center);
    const dir = new Vector3();
    dir.subVectors(camera.position, center);
    if (dir.lengthSq() === 0) dir.set(0, 0, 1);
    dir.normalize();
    camera.position.copy(dir.multiplyScalar(distance).add(center));
    camera.lookAt(center);
    camera.near = distance * 1e-3;
    camera.far = distance * 10;
    camera.updateProjectionMatrix();
    if (this.#orbitControls) {
      this.#orbitControls.target.copy(center);
      this.#orbitControls.update();
    }
  }
  /**
   * @internal
   */
  _exportVariantHierarchies() {
    if (!this.threeObject) return [];
    return this.threeObject._exportVariantHierarchies();
  }
  /**
   * @internal
   */
  _setVariantSelection(variantId) {
    if (!this.threeObject) return;
    this.threeObject._setVariantSelection(variantId);
  }
}
customElements.define("miris-scene", MirisScene);
customElements.define("miris-camera", MirisCamera);
customElements.define("miris-group", MirisGroup);
customElements.define("miris-stream", MirisStream);
export {
  MirisCamera,
  MirisGroup,
  MirisScene,
  MirisStream
};
