import {Vector3, EventDispatcher, Object3D, PerspectiveCamera, Quaternion, Euler, AnimationMixer, AnimationClip, VectorKeyframeTrack, QuaternionKeyframeTrack} from "./three.js";
import {TweenMax, gsap as gsap2} from "./gsap.js";
class p {
  constructor(t) {
    this.epsilon = 1e-3, this.values = {}, this.targetValues = {}, this.deltaValues = {}, Object.assign(this.values, t.values), Object.assign(this.targetValues, t.values), this.deltaValues = {};
    for (const t2 in this.values)
      this.deltaValues[t2] = 0;
    this.dampingFactor = t.dampingFactor, t.epsilon && (this.epsilon = t.epsilon), this.hasReached = true;
  }
  update() {
    const t = {};
    let e = true;
    for (const i in this.values)
      t[i] = this.targetValues[i] - this.values[i], e = e && Math.abs(t[i]) < this.epsilon;
    if (e) {
      for (const e2 in this.values)
        this.deltaValues[e2] = t[e2], this.values[e2] = this.targetValues[e2];
      this.hasReached = true;
    } else
      for (const e2 in this.values)
        this.deltaValues[e2] = this.dampingFactor * t[e2], this.values[e2] += this.deltaValues[e2];
  }
  setTarget(t) {
    for (const e in t)
      this.targetValues[e] = t[e];
    this.hasReached = false;
  }
  addToTarget(t, e) {
    this.targetValues[t] += e, this.hasReached = false;
  }
  resetAll(t) {
    for (const e in this.values)
      this.targetValues[e] = t, this.values[e] = t, this.deltaValues[e] = 0;
    this.hasReached = true;
  }
  resetData(t) {
    for (const e in t)
      this.targetValues[e] = t[e], this.values[e] = t[e], this.deltaValues[e] = 0;
    this.hasReached = true;
  }
  getCurrentValues() {
    return Object.assign({}, this.values);
  }
  getDeltaValues() {
    return Object.assign({}, this.deltaValues);
  }
  reachedTarget() {
    return this.hasReached;
  }
}
var m, u, g;
!function(t) {
  t.Pan = "Pan", t.Tilt = "Tilt", t.Roll = "Roll", t.Truck = "Truck", t.Pedestal = "Pedestal", t.Dolly = "Dolly", t.Zoom = "Zoom";
}(m || (m = {})), function(t) {
  t.Body = "body", t.Head = "head", t.Eyes = "eyes";
}(u || (u = {})), function(t) {
  t.X = "x", t.Y = "y", t.Z = "z";
}(g || (g = {}));
const b = {[g.X]: new Vector3(1, 0, 0), [g.Y]: new Vector3(0, 1, 0), [g.Z]: new Vector3(0, 0, 1)}, y = {[g.X]: {[m.Pan]: g.X, [m.Tilt]: g.Z, [m.Roll]: g.Y}, [g.Y]: {[m.Pan]: g.Y, [m.Tilt]: g.X, [m.Roll]: g.Z}, [g.Z]: {[m.Pan]: g.Z, [m.Tilt]: g.Y, [m.Roll]: g.X}};
class v extends EventDispatcher {
  constructor(t, e) {
    super(), this.inTransit = false, this.upAxis = g.Y, this.actionAxes = y[this.upAxis], this.hasAnimation = false, this.animationTranslationObjectName = "Translation", this.animationRotationObjectName = "Rotation", this.translateAlong = {[m.Tilt]: false, [m.Pan]: true, [m.Roll]: false}, this.camera = t, this.scene = e, this.body = new Object3D(), this.head = new Object3D(), this.eyes = new Object3D(), this.head.name = this.animationRotationObjectName, this.body.name = this.animationTranslationObjectName, this.body.rotation.order = this.getRotationOrder(), this.head.rotation.order = this.getRotationOrder(), this.eyes.rotation.order = this.getRotationOrder(), this.scene.add(this.body.add(this.head.add(this.eyes.add(this.camera)))), this.cameraIsInRig = true, this.unpackTransform();
  }
  getAxisFor(t) {
    return this.actionAxes[t];
  }
  getAxisVectorFor(t) {
    return b[this.actionAxes[t]];
  }
  do(t, e, i) {
    const n = this[i];
    switch (t) {
      case m.Pan:
      case m.Tilt:
      case m.Roll: {
        const i2 = this.getAxisVectorFor(t);
        n ? n.rotateOnAxis(i2, e) : this.translateAlong[t] ? this.body.rotateOnAxis(i2, e) : this.eyes.rotateOnAxis(i2, e);
        break;
      }
      case m.Truck: {
        const t2 = this.getAxisVectorFor(m.Tilt);
        (n || this.body).translateOnAxis(t2, e);
        break;
      }
      case m.Pedestal: {
        const t2 = this.getAxisVectorFor(m.Pan);
        (n || this.body).translateOnAxis(t2, e);
        break;
      }
      case m.Dolly: {
        const t2 = this.getAxisVectorFor(m.Roll);
        (n || this.body).translateOnAxis(t2, e);
        break;
      }
      case m.Zoom:
        this.camera instanceof PerspectiveCamera && (this.camera.fov = e, this.camera.updateProjectionMatrix());
    }
  }
  getWorldCoordinates() {
    const e = new Vector3();
    this.camera.getWorldPosition(e);
    const i = new Quaternion();
    return this.camera.getWorldQuaternion(i), {position: e, quaternion: i};
  }
  setWorldCoordinates({position: t, quaternion: e}) {
    const i = new Euler().setFromQuaternion(e, this.getRotationOrder()), s = [m.Pan, m.Tilt, m.Roll];
    this.eyes.position.set(0, 0, 0), this.eyes.rotation.set(0, 0, 0), this.head.position.set(0, 0, 0), this.head.rotation.set(0, 0, 0), this.body.position.copy(t), s.forEach((t2) => {
      const e2 = this.getAxisFor(t2);
      this.translateAlong[t2] ? this.body.rotation[e2] = i[e2] : this.eyes.rotation[e2] = i[e2];
    }), this.camera.rotation.set(0, 0, 0), this.camera.position.set(0, 0, 0);
  }
  packTransform() {
    const {position: t, quaternion: e} = this.getWorldCoordinates();
    this.body.position.copy(t), this.body.rotation.set(0, 0, 0), this.head.quaternion.copy(e), this.head.position.set(0, 0, 0), this.eyes.position.set(0, 0, 0), this.eyes.rotation.set(0, 0, 0);
  }
  unpackTransform() {
    const {position: t, quaternion: e} = this.getWorldCoordinates();
    this.setWorldCoordinates({position: t, quaternion: e});
  }
  disassemble() {
    this.cameraIsInRig && (this.scene.attach(this.camera), this.cameraIsInRig = false);
  }
  assemble() {
    this.cameraIsInRig || (this.eyes.attach(this.camera), this.unpackTransform(), this.cameraIsInRig = true);
  }
  getRotationOrder() {
    return Object.values(this.actionAxes).join("").toUpperCase();
  }
  isInRig() {
    return this.cameraIsInRig;
  }
  isMoving() {
    return this.inTransit;
  }
  setUpAxis(t) {
    this.upAxis = t, this.actionAxes = y[this.upAxis], this.body.rotation.order = this.getRotationOrder();
  }
  setAnimationClip(t, e, i) {
    this.animationClip = t, e && (this.animationTranslationObjectName = e), i && (this.animationRotationObjectName = i), this.hasAnimation = true, this.animationClip.duration += 0.01, this.mixer = new AnimationMixer(this.body);
    const s = this.mixer.clipAction(this.animationClip);
    s.clampWhenFinished = true, s.play();
  }
  flyTo(t, e, i = 1, s = "power1", n = true) {
    if (!this.isMoving()) {
      const a = this.getWorldCoordinates(), o = {px: a.position.x, py: a.position.y, pz: a.position.z, qx: a.quaternion.x, qy: a.quaternion.y, qz: a.quaternion.z, qw: a.quaternion.w, slerpAmt: 0}, r = {px: t.x, py: t.y, pz: t.z, qx: e.x, qy: e.y, qz: e.z, qw: e.w, slerpAmt: 1}, h = () => {
        this.inTransit = true, this.packTransform(), this.dispatchEvent({type: "CameraMoveStart"});
      }, d = (t2) => {
        this.body.position.set(o.px, o.py, o.pz), n ? this.head.quaternion.slerp(e, o.slerpAmt) : this.head.quaternion.set(o.qx, o.qy, o.qz, o.qw), this.dispatchEvent({type: "CameraMoveUpdate", progress: t2.progress()});
      }, l = () => {
        this.inTransit = false, this.unpackTransform(), this.dispatchEvent({type: "CameraMoveEnd"});
      };
      TweenMax.to(o, Object.assign(Object.assign({duration: i, ease: s}, r), {onStart: h, onUpdate: function() {
        d(this);
      }, onComplete: l}));
    }
  }
  flyToKeyframe(t, e = 1, i = "power1") {
    if (this.hasAnimation && !this.isMoving()) {
      const s = {time: this.mixer.time}, n = {time: this.animationClip.tracks[0].times[t]}, a = () => {
        this.inTransit = true, this.dispatchEvent({type: "CameraMoveStart"});
      }, o = (t2) => {
        this.mixer.setTime(s.time), this.dispatchEvent({type: "CameraMoveUpdate", progress: t2.progress()});
      }, r = () => {
        this.inTransit = false, this.dispatchEvent({type: "CameraMoveEnd"});
      };
      TweenMax.to(s, Object.assign(Object.assign({duration: e, ease: i}, n), {onStart: a, onUpdate: function() {
        o(this);
      }, onComplete: r}));
    }
  }
  setAnimationPercentage(t) {
    if (this.hasAnimation) {
      const e = Math.max(0, Math.min(t * this.animationClip.duration, this.animationClip.duration - 1e-4));
      this.mixer.setTime(e);
    }
  }
  setAnimationTime(t) {
    this.hasAnimation && this.mixer.setTime(t);
  }
  setAnimationKeyframe(t) {
    this.hasAnimation && this.mixer.setTime(this.animationClip.tracks[0].times[t]);
  }
}
class x extends EventDispatcher {
  constructor() {
    super();
  }
}
const f = {keyMapping: {forward: ["ArrowUp", "w", "W"], backward: ["ArrowDown", "s", "S"], left: ["ArrowLeft", "a", "A"], right: ["ArrowRight", "d", "D"], up: ["u", "U"], down: ["n", "N"]}, dampingFactor: 0.5, incrementor: 1, preventBubbling: true};
class E extends x {
  constructor(t) {
    super(), Object.assign(this, f, t);
    const e = {};
    for (const t2 in this.keyMapping)
      e[t2] = 0;
    this.damper = new p({values: e, dampingFactor: this.dampingFactor}), this.onKeyUp = this.onKeyUp.bind(this), this.onKeyDown = this.onKeyDown.bind(this);
  }
  connect() {
    document.addEventListener("keyup", this.onKeyUp, true), document.addEventListener("keydown", this.onKeyDown, true), this.connected = true;
  }
  disconnect() {
    document.removeEventListener("keyup", this.onKeyUp, true), document.removeEventListener("keydown", this.onKeyDown, true), this.connected = false;
  }
  update() {
    this.type !== "continuous" || this.damper.reachedTarget() || (this.damper.update(), this.dispatchEvent({type: "update", values: this.damper.getCurrentValues(), deltas: this.damper.getDeltaValues()}), this.damper.reachedTarget() && (this.damper.resetAll(0), this.dispatchEvent({type: "inertiacomplete"})));
  }
  isEnabled() {
    return this.connected;
  }
  onKeyUp(t) {
    if (this.type === "discrete") {
      for (const e in this.keyMapping)
        if (this.keyMapping[e].includes(t.key)) {
          this.preventBubbling && t.preventDefault(), this.dispatchEvent({type: "trigger", trigger: e});
          break;
        }
    }
  }
  onKeyDown(t) {
    if (this.type === "continuous") {
      for (const e in this.keyMapping)
        if (this.keyMapping[e].includes(t.key)) {
          this.preventBubbling && t.preventDefault(), this.damper.addToTarget(e, this.incrementor);
          break;
        }
    }
  }
}
const w = {domElement: document.body, dampingFactor: 0.5, shouldNormalize: true, normalizeAroundZero: true, multipointerThreshold: 100};
class P extends x {
  constructor(t) {
    super(), this.domElement = document.body, this.shouldNormalize = true, this.normalizeAroundZero = true, this.pointerCount = 0, this.recordedPosition = false, this.cache = [], this.lastDownTime = 0, this.lastUpTime = 0, Object.assign(this, w, t), this.damper = new p({values: {x: null, y: null}, dampingFactor: this.dampingFactor}), this.setDimensions(), this.onPointerMove = this.onPointerMove.bind(this), this.onPointerUp = this.onPointerUp.bind(this), this.onPointerDown = this.onPointerDown.bind(this), this.onResize = this.onResize.bind(this);
  }
  connect() {
    this.domElement.addEventListener("pointermove", this.onPointerMove, {passive: true}), this.domElement.addEventListener("pointerdown", this.onPointerDown, {passive: true}), this.domElement.addEventListener("pointerleave", this.onPointerUp, {passive: true}), this.domElement.addEventListener("pointerup", this.onPointerUp, {passive: true}), window.addEventListener("resize", this.onResize), this.connected = true;
  }
  disconnect() {
    this.domElement.removeEventListener("pointermove", this.onPointerMove), this.domElement.removeEventListener("pointerdown", this.onPointerDown), this.domElement.removeEventListener("pointerleave", this.onPointerUp), this.domElement.removeEventListener("pointerup", this.onPointerUp), this.connected = false;
  }
  update(t) {
    this.pointerCount !== this.cache.length && t - this.lastDownTime > this.multipointerThreshold && t - this.lastUpTime > this.multipointerThreshold && (this.pointerCount = this.cache.length, this.pointerCount === 0 ? (this.damper.resetAll(null), this.recordedPosition = false) : (this.damper.resetData(this.getPointerPosition(this.cache[0])), this.recordedPosition = true)), this.damper.reachedTarget() || (this.damper.update(), this.dispatchEvent({type: "update", values: this.shouldNormalize ? this.normalize(this.damper.getCurrentValues(), this.normalizeAroundZero) : this.damper.getCurrentValues(), deltas: this.shouldNormalize ? this.normalize(this.damper.getDeltaValues(), false) : this.damper.getDeltaValues(), pointerCount: this.pointerCount}), this.damper.reachedTarget() && this.dispatchEvent({type: "inertiacomplete"}));
  }
  isEnabled() {
    return this.connected;
  }
  setDimensions() {
    this.width = this.domElement.getBoundingClientRect().width, this.height = this.domElement.getBoundingClientRect().height;
  }
  getPointerPosition(t) {
    return {x: Math.max(0, Math.min(this.width, t.x - this.domElement.offsetLeft)), y: Math.max(0, Math.min(this.height, t.y - this.domElement.offsetTop))};
  }
  normalize(t, e) {
    let i = t.x / this.width, s = t.y / this.height;
    return e && (i = 2 * i - 1, s = 2 * s - 1), {x: i, y: s};
  }
  onPointerMove(t) {
    this.pointerCount === this.cache.length && (this.cache.length === 0 ? this.recordedPosition ? this.damper.setTarget(this.getPointerPosition(t)) : (this.damper.resetData(this.getPointerPosition(t)), this.recordedPosition = true) : t.pointerId === this.cache[0].pointerId && this.damper.setTarget(this.getPointerPosition(t)));
  }
  onPointerDown(t) {
    t.button === 0 && (this.cache.push(t), this.lastDownTime = window.performance.now());
  }
  onPointerUp(t) {
    if (t.button === 0 || t.type === "pointerleave") {
      for (let e = 0; e < this.cache.length; e++)
        if (this.cache[e].pointerId == t.pointerId) {
          this.cache.splice(e, 1);
          break;
        }
      this.lastUpTime = window.performance.now();
    }
  }
  onResize() {
    this.setDimensions();
  }
}
const A = {startOffset: "0px", endOffset: "0px", buffer: 0.1, dampingFactor: 0.5};
class T extends x {
  constructor(t) {
    super(), Object.assign(this, A, t), this.lastSeenScrollValue = window.scrollY || -1, this.previousScrollValue = this.lastSeenScrollValue, this.values = {scrollPx: null, scrollPercent: null}, this.damper = new p({values: this.values, dampingFactor: this.dampingFactor}), this.calculateDimensions = this.calculateDimensions.bind(this), this.onScroll = this.onScroll.bind(this), this.resizeObserver = new ResizeObserver(this.calculateDimensions), this.calculateDimensions();
  }
  connect() {
    window.addEventListener("scroll", this.onScroll, {passive: true}), this.resizeObserver.observe(document.body), this.connected = true;
  }
  disconnect() {
    window.removeEventListener("scroll", this.onScroll), this.resizeObserver.unobserve(document.body), this.connected = false;
  }
  update() {
    if (this.lastSeenScrollValue !== this.previousScrollValue && this.lastSeenScrollValue >= this.bufferedStartPosition && this.lastSeenScrollValue <= this.bufferedEndPosition) {
      const t = Math.max(0, Math.min(this.distance, this.lastSeenScrollValue - this.startPosition)), e = Math.max(0, Math.min(1, t / this.distance));
      this.values = {scrollPx: t, scrollPercent: e}, this.damper.setTarget(this.values), this.previousScrollValue = this.lastSeenScrollValue;
    }
    this.damper.reachedTarget() || (this.damper.update(), this.dispatchEvent({type: "update", values: this.values, dampenedValues: this.damper.getCurrentValues()}), this.damper.reachedTarget() && this.dispatchEvent({type: "inertiacomplete"}));
  }
  isEnabled() {
    return this.connected;
  }
  parseOffset(t) {
    let e = 0;
    return t && (e = parseInt(t), t.indexOf("vh") !== -1 ? e = e * window.innerHeight / 100 : this.distance && t.indexOf("%") !== -1 && (e = e * this.distance / 100)), e;
  }
  calculateOffset(t) {
    return t ? this.calculateOffset(t.offsetParent) + t.offsetTop : 0;
  }
  calculateDimensions() {
    const t = this.scrollElement.clientHeight, e = this.calculateOffset(this.scrollElement);
    this.startPosition = e - window.innerHeight + this.parseOffset(this.startOffset), this.endPosition = e + t + this.parseOffset(this.endOffset), this.distance = this.endPosition - this.startPosition, this.bufferedStartPosition = Math.max(0, this.startPosition * (1 - this.buffer)), this.bufferedEndPosition = Math.min(this.endPosition * (1 + this.buffer), document.body.getBoundingClientRect().height);
  }
  onScroll() {
    this.lastSeenScrollValue = window.scrollY;
  }
}
const C = {domElement: document.body, thresholdX: 60, thresholdY: 60};
class L extends x {
  constructor(t = {}) {
    super(), Object.assign(this, C, t), this.onPointerUp = this.onPointerUp.bind(this), this.onPointerDown = this.onPointerDown.bind(this);
  }
  connect() {
    this.domElement.addEventListener("pointerdown", this.onPointerDown, {passive: true}), this.domElement.addEventListener("pointerup", this.onPointerUp, {passive: true}), this.connected = true;
  }
  disconnect() {
    this.domElement.removeEventListener("pointerdown", this.onPointerDown), this.domElement.removeEventListener("pointerup", this.onPointerUp), this.connected = false;
  }
  update() {
  }
  isEnabled() {
    return this.connected;
  }
  onPointerDown(t) {
    t.pointerType !== "mouse" && t.isPrimary && (this.startX = t.screenX, this.startY = t.screenY);
  }
  onPointerUp(t) {
    if (t.pointerType !== "mouse" && t.isPrimary) {
      const e = t.screenX - this.startX, i = t.screenY - this.startY;
      (Math.abs(e) >= this.thresholdX || Math.abs(i) >= this.thresholdY) && this.dispatchEvent({type: "trigger", x: Math.abs(e) >= this.thresholdX ? Math.sign(e) : 0, y: Math.abs(i) >= this.thresholdY ? Math.sign(-1 * i) : 0});
    }
  }
}
const S = {dampingFactor: 0.5, thresholdX: 15, thresholdY: 15, debounceDuration: 700};
class F extends x {
  constructor(t) {
    super(), this.lastThresholdTrigger = 0, Object.assign(this, S, t), this.damper = new p({values: {x: 0, y: 0}, dampingFactor: this.dampingFactor}), this.onWheel = this.onWheel.bind(this);
  }
  connect() {
    (this.domElement || window).addEventListener("wheel", this.onWheel, {passive: true}), this.connected = true;
  }
  disconnect() {
    (this.domElement || window).removeEventListener("wheel", this.onWheel), this.connected = false;
  }
  update() {
    this.type !== "continuous" || this.damper.reachedTarget() || (this.damper.update(), this.dispatchEvent({type: "update", values: this.damper.getCurrentValues(), deltas: this.damper.getDeltaValues()}), this.damper.reachedTarget() && (this.damper.resetAll(0), this.dispatchEvent({type: "inertiacomplete"})));
  }
  isEnabled() {
    return this.connected;
  }
  onWheel(t) {
    if (this.type === "continuous")
      this.damper.addToTarget("x", t.deltaX), this.damper.addToTarget("y", t.deltaY);
    else if (this.type === "discrete" && (Math.abs(t.deltaX) >= this.thresholdX || Math.abs(t.deltaY) >= this.thresholdY)) {
      const e = window.performance.now();
      e - this.lastThresholdTrigger > this.debounceDuration && (this.lastThresholdTrigger = e, this.dispatchEvent({type: "trigger", x: Math.abs(t.deltaX) >= this.thresholdX ? Math.sign(t.deltaX) : 0, y: Math.abs(t.deltaY) >= this.thresholdY ? Math.sign(t.deltaY) : 0}));
    }
  }
}
const R = {domElement: document.body, pointerDampFactor: 0.3, pointerScaleFactor: 4, keyboardDampFactor: 0.5, keyboardScaleFactor: 0.5, wheelDampFactor: 0.25, wheelScaleFactor: 0.05, panDegreeFactor: Math.PI / 4, tiltDegreeFactor: Math.PI / 10};
class k {
  constructor(t, e = {}) {
    this.enabled = false, this.cameraRig = t, this.wheelScaleFactor = e.wheelScaleFactor || R.wheelScaleFactor, this.pointerScaleFactor = e.pointerScaleFactor || R.pointerScaleFactor, this.panDegreeFactor = e.panDegreeFactor || R.panDegreeFactor, this.tiltDegreeFactor = e.tiltDegreeFactor || R.tiltDegreeFactor, this.keyboardAdaptor = new E({type: "continuous", dampingFactor: e.keyboardDampFactor || R.keyboardDampFactor, incrementor: e.keyboardScaleFactor || R.keyboardScaleFactor}), this.wheelAdaptor = new F({type: "continuous", dampingFactor: e.wheelDampFactor || R.wheelDampFactor, domElement: e.domElement || R.domElement}), this.pointerAdaptor = new P({domElement: e.domElement || R.domElement, dampingFactor: e.pointerDampFactor || R.pointerDampFactor}), this.onWheel = this.onWheel.bind(this), this.onKey = this.onKey.bind(this), this.onPointer = this.onPointer.bind(this);
  }
  isEnabled() {
    return this.enabled;
  }
  enable() {
    this.wheelAdaptor.connect(), this.keyboardAdaptor.connect(), this.pointerAdaptor.connect(), this.wheelAdaptor.addEventListener("update", this.onWheel), this.keyboardAdaptor.addEventListener("update", this.onKey), this.pointerAdaptor.addEventListener("update", this.onPointer), this.enabled = true;
  }
  disable() {
    this.wheelAdaptor.disconnect(), this.keyboardAdaptor.disconnect(), this.pointerAdaptor.disconnect(), this.wheelAdaptor.removeEventListener("update", this.onWheel), this.keyboardAdaptor.removeEventListener("update", this.onKey), this.pointerAdaptor.removeEventListener("update", this.onPointer), this.enabled = false;
  }
  onWheel(t) {
    this.cameraRig.do(m.Dolly, t.deltas.y * this.wheelScaleFactor), this.cameraRig.do(m.Truck, t.deltas.x * this.wheelScaleFactor);
  }
  onKey(t) {
    this.cameraRig.do(m.Dolly, t.values.backward - t.values.forward), this.cameraRig.do(m.Truck, t.values.right - t.values.left), this.cameraRig.do(m.Pedestal, t.values.up - t.values.down);
  }
  onPointer(t) {
    switch (t.pointerCount) {
      case 1:
        this.cameraRig.do(m.Pan, t.deltas.x * this.panDegreeFactor), this.cameraRig.do(m.Tilt, t.deltas.y * this.tiltDegreeFactor);
        break;
      case 2:
        this.cameraRig.do(m.Dolly, -t.deltas.y * this.pointerScaleFactor), this.cameraRig.do(m.Truck, -t.deltas.x * this.pointerScaleFactor);
    }
  }
  update(t) {
    this.enabled && (this.keyboardAdaptor.update(), this.wheelAdaptor.update(), this.pointerAdaptor.update(t));
  }
}
const O = {startOffset: "0px", endOffset: "0px", dampingFactor: 1, buffer: 0.1, cameraStart: "0%", cameraEnd: "100%", scrollActions: []}, M = (t, e, i, s, n) => Math.max(s, Math.min(n, (n - s) / (i - e) * (t - e) + s));
class I {
  constructor(t, e) {
    this.enabled = false, this.cameraRig = t, this.cameraRig.setAnimationTime(0), this.scrollAdaptor = new T({scrollElement: e.scrollElement, dampingFactor: e.dampingFactor || O.dampingFactor, startOffset: e.startOffset || O.startOffset, endOffset: e.endOffset || O.endOffset, buffer: e.buffer || O.buffer}), this.cameraStart = e.cameraStart || O.cameraStart, this.cameraEnd = e.cameraEnd || O.cameraEnd, this.scrollActions = e.scrollActions || O.scrollActions, this.buffer = e.buffer || O.buffer, this.calculateStops(), this.onScroll = this.onScroll.bind(this);
  }
  isEnabled() {
    return this.enabled;
  }
  enable() {
    this.scrollAdaptor.connect(), this.scrollAdaptor.addEventListener("update", this.onScroll), this.enabled = true;
  }
  disable() {
    this.scrollAdaptor.disconnect(), this.scrollAdaptor.removeEventListener("update", this.onScroll), this.enabled = false;
  }
  update() {
    this.enabled && this.scrollAdaptor.update();
  }
  calculateStops() {
    this.cameraStartPx = this.scrollAdaptor.parseOffset(this.cameraStart), this.cameraEndPx = this.scrollAdaptor.parseOffset(this.cameraEnd), this.cameraBufferedStartPx = this.cameraStartPx * (1 - this.buffer), this.cameraBufferedEndPx = this.cameraEndPx * (1 + this.buffer), this.scrollActions.forEach((t) => {
      t.startPx = this.scrollAdaptor.parseOffset(t.start), t.endPx = this.scrollAdaptor.parseOffset(t.end), t.bufferedStartPx = t.startPx * (1 - this.buffer), t.bufferedEndPx = t.endPx * (1 + this.buffer);
    });
  }
  onScroll(t) {
    const e = t.dampenedValues.scrollPx;
    e >= this.cameraBufferedStartPx && e <= this.cameraBufferedEndPx && this.cameraRig.setAnimationPercentage(M(e, this.cameraStartPx, this.cameraEndPx, 0, 1)), this.scrollActions.forEach((t2) => {
      e >= t2.bufferedStartPx && e <= t2.bufferedEndPx && t2.callback(M(e, t2.startPx, t2.endPx, 0, 1));
    });
  }
}
const D = {cycle: false, useKeyboard: true};
class q extends EventDispatcher {
  constructor(t, e = [], i = {}) {
    super(), this.currentIndex = null, this.upcomingIndex = null, this.enabled = false, this.cameraRig = t, this.pois = e, Object.assign(this, D, i), this.useKeyboard && (this.keyboardAdaptor = new E({type: "discrete", keyMapping: {next: ["ArrowDown", "ArrowRight"], prev: ["ArrowUp", "ArrowLeft"]}}), this.onKey = this.onKey.bind(this)), this.onCameraStart = this.onCameraStart.bind(this), this.onCameraUpdate = this.onCameraUpdate.bind(this), this.onCameraEnd = this.onCameraEnd.bind(this);
  }
  getCurrentIndex() {
    return this.currentIndex;
  }
  nextPOI() {
    const t = this.currentIndex + 1;
    t >= this.pois.length && !this.cycle ? this.dispatchEvent({type: "ExitPOIs", exitFrom: "end"}) : this.goToPOI(t % this.pois.length);
  }
  prevPOI() {
    const t = this.currentIndex - 1;
    t < 0 && !this.cycle ? this.dispatchEvent({type: "ExitPOIs", exitFrom: "start"}) : this.goToPOI((t + this.pois.length) % this.pois.length);
  }
  goToPOI(t) {
    this.upcomingIndex = t;
    const e = this.pois[this.upcomingIndex];
    this.cameraRig.flyTo(e.position, e.quaternion, e.duration, e.ease);
  }
  enable() {
    this.useKeyboard && (this.keyboardAdaptor.connect(), this.keyboardAdaptor.addEventListener("trigger", this.onKey)), this.cameraRig.addEventListener("CameraMoveStart", this.onCameraStart), this.cameraRig.addEventListener("CameraMoveUpdate", this.onCameraUpdate), this.cameraRig.addEventListener("CameraMoveEnd", this.onCameraEnd), this.enabled = true;
  }
  disable() {
    this.useKeyboard && (this.keyboardAdaptor.disconnect(), this.keyboardAdaptor.removeEventListener("trigger", this.onKey)), this.cameraRig.removeEventListener("CameraMoveStart", this.onCameraStart), this.cameraRig.removeEventListener("CameraMoveUpdate", this.onCameraUpdate), this.cameraRig.removeEventListener("CameraMoveEnd", this.onCameraEnd), this.enabled = false;
  }
  update() {
  }
  isEnabled() {
    return this.enabled;
  }
  updatePois(t) {
    this.dispatchEvent({type: "update", currentIndex: this.currentIndex, upcomingIndex: this.upcomingIndex, progress: t});
  }
  onCameraStart() {
    this.updatePois(0);
  }
  onCameraUpdate(t) {
    this.updatePois(t.progress);
  }
  onCameraEnd() {
    this.currentIndex = this.upcomingIndex, this.upcomingIndex = null;
  }
  onKey(t) {
    t.trigger === "next" ? this.nextPOI() : t.trigger === "prev" && this.prevPOI();
  }
}
const z = {wheelThreshold: 15, swipeThreshold: 60, duration: 1, ease: "power1", useKeyboard: true};
class U extends EventDispatcher {
  constructor(t, e = [], i = {}) {
    super(), this.currentIndex = 0, this.upcomingIndex = null, this.enabled = false, this.cameraRig = t, this.pois = e, Object.assign(this, z, i), this.wheelAdaptor = new F({type: "discrete", thresholdY: this.wheelThreshold}), this.swipeAdaptor = new L({thresholdY: this.swipeThreshold}), this.useKeyboard && (this.keyboardAdaptor = new E({type: "discrete", keyMapping: {next: ["ArrowDown", "ArrowRight"], prev: ["ArrowUp", "ArrowLeft"]}}), this.onKey = this.onKey.bind(this)), this.onCameraStart = this.onCameraStart.bind(this), this.onCameraUpdate = this.onCameraUpdate.bind(this), this.onCameraEnd = this.onCameraEnd.bind(this), this.onTrigger = this.onTrigger.bind(this);
  }
  getCurrentIndex() {
    return this.currentIndex;
  }
  enable() {
    this.useKeyboard && (this.keyboardAdaptor.addEventListener("trigger", this.onKey), this.keyboardAdaptor.connect()), this.wheelAdaptor.addEventListener("trigger", this.onTrigger), this.swipeAdaptor.addEventListener("trigger", this.onTrigger), this.cameraRig.addEventListener("CameraMoveStart", this.onCameraStart), this.cameraRig.addEventListener("CameraMoveUpdate", this.onCameraUpdate), this.cameraRig.addEventListener("CameraMoveEnd", this.onCameraEnd), this.wheelAdaptor.connect(), this.swipeAdaptor.connect(), this.enabled = true;
  }
  disable() {
    this.useKeyboard && (this.keyboardAdaptor.removeEventListener("trigger", this.onKey), this.keyboardAdaptor.disconnect()), this.wheelAdaptor.removeEventListener("trigger", this.onTrigger), this.swipeAdaptor.removeEventListener("trigger", this.onTrigger), this.cameraRig.removeEventListener("CameraMoveStart", this.onCameraStart), this.cameraRig.removeEventListener("CameraMoveUpdate", this.onCameraUpdate), this.cameraRig.removeEventListener("CameraMoveEnd", this.onCameraEnd), this.wheelAdaptor.disconnect(), this.swipeAdaptor.disconnect(), this.enabled = false;
  }
  update() {
  }
  isEnabled() {
    return this.enabled;
  }
  onKey(t) {
    switch (t.trigger) {
      case "prev":
        this.onTrigger({y: -1});
        break;
      case "next":
        this.onTrigger({y: 1});
    }
  }
  onTrigger(t) {
    const e = this.currentIndex + t.y;
    e >= this.pois.length ? this.dispatchEvent({type: "ExitPOIs", exitFrom: "end"}) : e < 0 ? this.dispatchEvent({type: "ExitPOIs", exitFrom: "start"}) : (this.upcomingIndex = e, this.cameraRig.flyToKeyframe(this.pois[this.upcomingIndex].frame, this.duration, this.ease));
  }
  updatePois(t) {
    this.dispatchEvent({type: "update", currentIndex: this.currentIndex, upcomingIndex: this.upcomingIndex, progress: t});
  }
  onCameraStart() {
    this.updatePois(0);
  }
  onCameraUpdate(t) {
    this.updatePois(t.progress);
  }
  onCameraEnd() {
    this.currentIndex = this.upcomingIndex, this.upcomingIndex = null;
  }
}
const V = {domElement: document.body, panFactor: Math.PI / 20, tiltFactor: Math.PI / 20, truckFactor: 1, pedestalFactor: 1, dampingFactor: 0.7};
class K {
  constructor(t, e = {}) {
    this.enabled = false, this.cameraRig = t, Object.assign(this, V, e), this.pointerAdaptor = new P({domElement: e.domElement || V.domElement, dampingFactor: e.dampingFactor || V.dampingFactor}), this.onPointerMove = this.onPointerMove.bind(this);
  }
  isEnabled() {
    return this.enabled;
  }
  enable() {
    this.pointerAdaptor.connect(), this.pointerAdaptor.addEventListener("update", this.onPointerMove), this.enabled = true;
  }
  disable() {
    this.pointerAdaptor.disconnect(), this.pointerAdaptor.removeEventListener("update", this.onPointerMove), this.enabled = false;
  }
  update(t) {
    this.enabled && this.pointerAdaptor.update(t);
  }
  onPointerMove(t) {
    t.pointerCount === 0 && (this.cameraRig.do(m.Pan, -t.deltas.x * this.panFactor, u.Eyes), this.cameraRig.do(m.Tilt, -t.deltas.y * this.tiltFactor, u.Eyes), this.cameraRig.do(m.Truck, t.deltas.x * this.truckFactor, u.Eyes), this.cameraRig.do(m.Pedestal, t.deltas.y * this.pedestalFactor, u.Eyes));
  }
}
!function(t, e) {
  e === void 0 && (e = {});
  var i = e.insertAt;
  if (t && typeof document != "undefined") {
    var s = document.head || document.getElementsByTagName("head")[0], n = document.createElement("style");
    n.type = "text/css", i === "top" && s.firstChild ? s.insertBefore(n, s.firstChild) : s.appendChild(n), n.styleSheet ? n.styleSheet.cssText = t : n.appendChild(document.createTextNode(t));
  }
}(".tb-ch {\n  width: 350px;\n  height: 100%;\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: 99999;\n  background-color: rgba(255, 255, 255, 0.8);\n  box-sizing: border-box;\n  overflow-x: visible;\n  transition: all 0.2s ease-in-out;\n}\n  .tb-ch.collapsed {\n    left: -350px;\n  }\n  .tb-ch * {\n    box-sizing: border-box;\n  }\n  .tb-ch button {\n    text-transform: capitalize;\n    cursor: pointer;\n  }\n  .tb-ch .btn-round {\n    font-size: 1.8rem;\n    line-height: 1;\n    width: 2.5rem;\n    height: 2.5rem;\n    position: absolute;\n    right: -3rem;\n    bottom: 0.5rem;\n  }\n  .tb-ch .btn-round.collapse {\n      bottom: 3.5rem;\n    }\n  .tb-ch .controls {\n    position: absolute;\n    bottom: 0;\n    height: 185px;\n    border-top: 1px solid black;\n    padding: 0.5rem;\n    width: 100%;\n    display: flex;\n    flex-direction: column;\n    justify-content: space-between;\n  }\n  .tb-ch .btn-text {\n    padding: 0.5rem;\n    text-align: center;\n    width: 100%;\n  }\n  .tb-ch input[type='range'] {\n    width: 100%;\n  }\n  .tb-ch .pois {\n    height: calc(100vh - 185px - 1rem);\n    overflow: scroll;\n    padding: 1rem 1rem 0;\n  }\n  .tb-ch .poi {\n    margin-bottom: 1rem;\n  }\n  .tb-ch .poi h2 {\n      font-size: 1rem;\n    }\n  .tb-ch .poi .wrapper {\n      display: flex;\n      flex-direction: row;\n    }\n  .tb-ch .poi img {\n      display: block;\n      max-width: 100%;\n      min-width: 0;\n      margin-right: 0.5rem;\n    }\n  .tb-ch .poi .poi-controls {\n      display: flex;\n      flex-direction: column;\n    }\n  .tb-ch .poi .poi-controls button {\n        padding: 0.5rem;\n        width: 2rem;\n        height: 2rem;\n        margin-bottom: 0.25rem;\n      }\n  .tb-ch .poi .poi-params {\n      display: flex;\n      flex-direction: row;\n      flex-wrap: wrap;\n      width: calc(100% - 2.5rem);\n    }\n  .tb-ch .poi label,\n    .tb-ch .poi input,\n    .tb-ch .poi select {\n      width: 50%;\n      font-size: 0.7rem;\n      font-family: monospace;\n      margin: 0.25rem 0;\n    }\n  .tb-ch .poi input {\n      text-align: center;\n    }\n");
const j = ["none", "power1", "power2", "power3", "power4", "sine", "expo", "circ"], Y = "visit", W = "remove", B = "duration", X = "ease", N = "move-up", Z = "move-down";
class H {
  constructor(t, e, i, s) {
    this.useSlerp = true, this.rig = t, this.controls = e, this.canvas = i, this.pois = [], this.currentIndex = null, this.doCapture = false, this.isPlaying = false, this.initUI(s);
  }
  capture() {
    this.doCapture = true;
  }
  update(t) {
    if (this.doCapture) {
      const t2 = this.canvas.toDataURL();
      this.addPoi(t2), this.doCapture = false;
    }
    if (this.isPlaying) {
      this.playStartTime || (this.playStartTime = t, this.controls.disable(), this.rig.packTransform());
      const e = (t - this.playStartTime) / 1e3;
      this.rig.setAnimationTime(e), e > this.animationClip.duration && (this.isPlaying = false, this.playStartTime = null, this.controls.enable(), this.rig.unpackTransform());
    }
  }
  addPoi(t) {
    this.pois.push(Object.assign(Object.assign({}, this.rig.getWorldCoordinates()), {duration: 1, ease: "power1", image: t})), this.currentIndex = this.pois.length - 1, this.createClip(), this.render();
  }
  updatePoi(t, e) {
    this.pois[t] = Object.assign(Object.assign({}, this.pois[t]), e);
  }
  movePoi(t, e) {
    if (t + e >= 0 && t + e < this.pois.length) {
      const i = this.pois[t];
      this.pois[t] = this.pois[t + e], this.pois[t + e] = i, this.render();
    }
  }
  removePoi(t) {
    this.pois.splice(t, 1), this.render();
  }
  goToPoi(t) {
    const e = this.pois[t];
    this.rig.flyTo(e.position, e.quaternion, e.duration, e.ease, this.useSlerp);
  }
  createClip() {
    if (this.pois.length > 0) {
      const e = [], i = [], s = [], a = new Vector3(), o = new Quaternion(), c = 10;
      let p2 = 0;
      for (let t = 0; t < this.pois.length - 1; t++) {
        const n = this.pois[t], r = this.pois[t + 1], h = {px: n.position.x, py: n.position.y, pz: n.position.z, qx: n.quaternion.x, qy: n.quaternion.y, qz: n.quaternion.z, qw: n.quaternion.w, slerpAmount: 0}, d = {px: r.position.x, py: r.position.y, pz: r.position.z, qx: r.quaternion.x, qy: r.quaternion.y, qz: r.quaternion.z, qw: r.quaternion.w, slerpAmount: 1, duration: r.duration, ease: r.ease}, m3 = gsap2.to(h, d);
        for (let t2 = 0; t2 < c; t2++) {
          const d2 = r.duration * (t2 / c);
          e.push(p2 + d2), m3.seek(d2), this.useSlerp ? o.slerpQuaternions(n.quaternion, r.quaternion, h.slerpAmount) : o.set(h.qx, h.qy, h.qz, h.qw), a.set(h.px, h.py, h.pz), o.toArray(s, s.length), a.toArray(i, i.length);
        }
        p2 += r.duration;
      }
      const m2 = this.pois[this.pois.length - 1];
      m2.quaternion.toArray(s, s.length), m2.position.toArray(i, i.length), e.push(p2), this.animationClip = new AnimationClip(null, p2, [new VectorKeyframeTrack("Translation.position", e, i), new QuaternionKeyframeTrack("Rotation.quaternion", e, s)]), this.rig.setAnimationClip(this.animationClip);
    }
  }
  scrubClip(t) {
    this.pois.length > 0 && this.rig.setAnimationPercentage(t);
  }
  playClip() {
    this.pois.length > 0 && (this.isPlaying = true);
  }
  export() {
    if (this.pois.length > 0) {
      const t = {};
      t.pois = this.pois.map((t2) => ({position: [t2.position.x, t2.position.y, t2.position.z], quaternion: [t2.quaternion.x, t2.quaternion.y, t2.quaternion.z, t2.quaternion.w], duration: t2.duration, ease: t2.ease})), this.animationClip && (t.animationClip = AnimationClip.toJSON(this.animationClip));
      const e = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(t)), i = document.createElement("a");
      i.href = "data:" + e, i.download = "camera-data.json", document.body.appendChild(i), i.click(), i.remove();
    }
  }
  exportImages() {
    const t = document.createElement("a");
    document.body.appendChild(t), this.pois.forEach((e, i) => {
      t.href = e.image, t.download = `camera-poi-${i}.png`, t.click();
    }), t.remove();
  }
  initUI(t) {
    this.drawer = document.createElement("div"), this.drawer.classList.add("tb-ch");
    const e = document.createElement("button");
    e.classList.add("btn-round", "add"), e.innerText = "+", e.onclick = this.capture.bind(this), this.collapseBtn = document.createElement("button"), this.collapseBtn.classList.add("btn-round", "collapse"), this.collapseBtn.innerText = "<", this.collapseBtn.onclick = this.collapse.bind(this);
    const i = document.createElement("div");
    i.classList.add("controls");
    const s = document.createElement("button");
    s.classList.add("btn-text", "export"), s.innerText = "export JSON", s.onclick = this.export.bind(this);
    const n = document.createElement("button");
    n.classList.add("btn-text", "export-images"), n.innerHTML = "export images", n.onclick = this.exportImages.bind(this);
    const a = document.createElement("button");
    a.classList.add("btn-text", "play"), a.innerText = "play", a.onclick = this.playClip.bind(this);
    const o = document.createElement("input");
    o.type = "range", o.min = "0", o.max = "1000", o.step = "0.1", o.value = "0";
    const r = this.scrubClip.bind(this);
    o.onmousedown = () => this.rig.packTransform(), o.onmouseup = () => this.rig.unpackTransform(), o.oninput = (t2) => r(parseInt(t2.target.value) / 1e3), this.domList = document.createElement("div"), this.domList.classList.add("pois"), this.domList.onclick = this.handleEvents.bind(this), this.domList.onchange = this.handleEvents.bind(this), i.append(a, o, n, s), this.drawer.append(e, this.collapseBtn, this.domList, i);
    (t || document.body).append(this.drawer);
  }
  handleEvents(t) {
    const e = t.target.dataset.index;
    e && (t.target.classList.contains(Y) ? this.goToPoi(parseInt(e)) : t.target.classList.contains(W) ? this.removePoi(parseInt(e)) : t.target.classList.contains(B) ? this.updatePoi(parseInt(e), {duration: parseFloat(t.target.value)}) : t.target.classList.contains(X) ? this.updatePoi(parseInt(e), {ease: t.target.value}) : t.target.classList.contains(N) ? this.movePoi(parseInt(e), -1) : t.target.classList.contains(Z) && this.movePoi(parseInt(e), 1), this.createClip());
  }
  collapse() {
    this.drawer.classList.contains("collapsed") ? (this.drawer.classList.remove("collapsed"), this.collapseBtn.innerText = "<") : (this.drawer.classList.add("collapsed"), this.collapseBtn.innerText = ">");
  }
  render() {
    this.domList.innerHTML = "", this.pois.forEach((t, e) => {
      const i = document.createElement("div");
      i.classList.add("poi");
      const s = document.createElement("h2");
      s.innerText = `${e + 1}.`;
      const n = document.createElement("div");
      n.classList.add("wrapper");
      const a = document.createElement("div");
      a.classList.add("poi-controls");
      const o = document.createElement("div");
      o.classList.add("poi-params");
      const r = new Image();
      r.src = t.image;
      const h = document.createElement("label");
      h.innerText = "Duration";
      const d = document.createElement("input");
      d.classList.add(B), d.dataset.index = `${e}`, d.type = "number", d.value = String(t.duration);
      const c = document.createElement("label");
      c.innerText = "Easing";
      const l = document.createElement("select");
      l.classList.add(X), l.dataset.index = `${e}`;
      const p2 = j.map((e2) => {
        const i2 = document.createElement("option");
        return i2.innerText = e2, i2.value = e2, i2.selected = e2 === t.ease, i2;
      });
      l.append(...p2);
      const m2 = document.createElement("button");
      m2.classList.add(W), m2.title = "Remove", m2.dataset.index = `${e}`, m2.innerText = "x";
      const u2 = document.createElement("button");
      u2.classList.add(Y), u2.title = "Visit", u2.dataset.index = `${e}`, u2.innerHTML = "&rarr;";
      const g2 = document.createElement("button");
      g2.classList.add(N), g2.title = "Move up", g2.dataset.index = `${e}`, g2.innerHTML = "&uarr;";
      const b2 = document.createElement("button");
      b2.classList.add(Z), b2.title = "Move down", b2.dataset.index = `${e}`, b2.innerHTML = "&darr;", a.append(m2, u2, g2, b2), o.append(h, d, c, l), n.append(r, a), i.append(s, n, o), this.domList.appendChild(i);
    });
  }
}
export {g as Axis, x as BaseAdaptor, m as CameraAction, H as CameraHelper, v as CameraRig, p as Damper, k as FreeMovementControls, E as KeyboardAdaptor, U as PathPointsControls, P as PointerAdaptor, u as RigComponent, T as ScrollAdaptor, I as ScrollControls, q as StoryPointsControls, L as SwipeAdaptor, K as ThreeDOFControls, F as WheelAdaptor};
export default null;