import {
  __privateAdd,
  __privateGet,
  __privateMethod,
  __privateSet,
  __publicField
} from "./chunk-HPRLEMBT.js";

// node_modules/rubiks-js/src/math/abstractVector.js
var Vector = class {
  /**
   * @abstract
   * @param {number} _a
   */
  scale(_a) {
    throw new Error("must be implemented in subclass");
  }
  /**
   * @abstract
   * @param {V} _v
   * @returns {V}
   */
  add(_v) {
    throw new Error("must be implemented in subclass");
  }
  /**
   * @abstract
   * @param {V} _v
   * @return {V}
   */
  sub(_v) {
    throw new Error("must be implemented in subclass");
  }
  /**
   * @abstract
   * @param {V} _v
   * @return {V}
   */
  mult(_v) {
    throw new Error("must be implemented in subclass");
  }
  /**
   * @abstract
   * @param {V} _v
   * @return {number}
   */
  dot(_v) {
    throw new Error("must be implemented in subclass");
  }
  /**
   * @abstract
   * @return {number[]}
   */
  toArray() {
    throw new Error("must be implemented in subclass");
  }
  get squareMag() {
    const t = this;
    return this.dot(t);
  }
  get mag() {
    return Math.sqrt(this.squareMag);
  }
  get normalized() {
    return this.scale(1 / this.mag);
  }
  get negate() {
    return this.scale(-1);
  }
};

// node_modules/rubiks-js/src/math/vector.js
var V2 = class _V2 extends Vector {
  /**
   * @param {number} x
   * @param {number} y
   */
  constructor(x, y) {
    super();
    this.x = x;
    this.y = y;
  }
  /** @param {number} a */
  scale(a) {
    return new _V2(a * this.x, a * this.y);
  }
  /** @param {V2} v */
  add({ x, y }) {
    return new _V2(this.x + x, this.y + y);
  }
  /** @param {V2} v */
  sub({ x, y }) {
    return new _V2(this.x - x, this.y - y);
  }
  /** @param {V2} v */
  mult({ x, y }) {
    return new _V2(this.x * x, this.y * y);
  }
  /** @param {V2} v */
  dot({ x, y }) {
    return this.x * x + this.y * y;
  }
  toArray() {
    return [this.x, this.y];
  }
  /**
   * @param {WebGL2RenderingContext} gl
   * @param {WebGLUniformLocation} location
   */
  setUniform(gl, location) {
    gl.uniform2f(location, this.x, this.y);
  }
  static get zero() {
    return new _V2(0, 0);
  }
};
var V3 = class _V3 extends Vector {
  /**
   * @param {number} x
   * @param {number} y
   * @param {number} z
   */
  constructor(x, y, z) {
    super();
    this.x = x;
    this.y = y;
    this.z = z;
  }
  /** @param {number} a */
  scale(a) {
    return new _V3(a * this.x, a * this.y, a * this.z);
  }
  /** @param {V3} v */
  add({ x, y, z }) {
    return new _V3(this.x + x, this.y + y, this.z + z);
  }
  /** @param {V3} v */
  sub({ x, y, z }) {
    return new _V3(this.x - x, this.y - y, this.z - z);
  }
  /** @param {V3} v */
  mult({ x, y, z }) {
    return new _V3(this.x * x, this.y * y, this.z * z);
  }
  /** @param {V3} v */
  cross({ x, y, z }) {
    return new _V3(this.y * z - this.z * y, this.z * x - this.x * z, this.x * y - this.y * x);
  }
  /** @param {V3} v */
  dot({ x, y, z }) {
    return this.x * x + this.y * y + this.z * z;
  }
  toArray() {
    return [this.x, this.y, this.z];
  }
  /**
   * @param {WebGL2RenderingContext} gl
   * @param {WebGLUniformLocation} location
   */
  setUniform(gl, location) {
    gl.uniform3f(location, this.x, this.y, this.z);
  }
  toV2() {
    return new V2(this.x, this.y);
  }
  static get zero() {
    return new _V3(0, 0, 0);
  }
  static get one() {
    return new _V3(1, 1, 1);
  }
  static get up() {
    return new _V3(0, 1, 0);
  }
  static get down() {
    return new _V3(0, -1, 0);
  }
  static get left() {
    return new _V3(1, 0, 0);
  }
  static get right() {
    return new _V3(-1, 0, 0);
  }
  static get forward() {
    return new _V3(0, 0, 1);
  }
  static get back() {
    return new _V3(0, 0, -1);
  }
  /**
   * @param {V3} v1
   * @param {V3} v2
   * @param {number} t
   */
  static lerp(v1, v2, t) {
    return v1.add(v2.sub(v1).scale(t));
  }
  /**
   * @param {V3} v1
   * @param {V3} v2
   */
  static angle(v1, v2) {
    return Math.acos(v1.dot(v2) / Math.sqrt(v1.squareMag * v2.squareMag));
  }
  /** @param {number} axis */
  static getRotationAxis(axis) {
    if (axis === 0)
      return _V3.right;
    if (axis === 1)
      return _V3.down;
    return _V3.back;
  }
};
var V4 = class _V4 extends Vector {
  /**
   * @param {number} x
   * @param {number} y
   * @param {number} z
   * @param {number} w
   */
  constructor(x, y, z, w) {
    super();
    this.x = x;
    this.y = y;
    this.z = z;
    this.w = w;
  }
  /** @param {number} a */
  scale(a) {
    return new _V4(a * this.x, a * this.y, a * this.z, a * this.w);
  }
  /** @param {V4} v */
  add({ x, y, z, w }) {
    return new _V4(this.x + x, this.y + y, this.z + z, this.w + w);
  }
  /** @param {V4} v */
  sub({ x, y, z, w }) {
    return new _V4(this.x - x, this.y - y, this.z - z, this.w - w);
  }
  /** @param {V4} v */
  mult({ x, y, z, w }) {
    return new _V4(this.x * x, this.y * y, this.z * z, this.w * w);
  }
  /** @param {V4} v */
  dot({ x, y, z, w }) {
    return this.x * x + this.y * y + this.z * z + this.w * w;
  }
  toV3() {
    return new V3(this.x, this.y, this.z);
  }
  toArray() {
    return [this.x, this.y, this.z, this.w];
  }
  /**
   * @param {WebGL2RenderingContext} gl
   * @param {WebGLUniformLocation} location
   */
  setUniform(gl, location) {
    gl.uniform4f(location, this.x, this.y, this.z, this.w);
  }
};

// node_modules/rubiks-js/src/math/matrix.js
var M44 = class _M44 {
  /**
   * @param {V4} r1
   * @param {V4} r2
   * @param {V4} r3
   * @param {V4} r4
   */
  constructor(r1, r2, r3, r4) {
    this.r1 = r1;
    this.r2 = r2;
    this.r3 = r3;
    this.r4 = r4;
  }
  /** @param {number} a */
  scale(a) {
    return new _M44(this.r1.scale(a), this.r2.scale(a), this.r3.scale(a), this.r4.scale(a));
  }
  /** @param {M44} m */
  add({ r1, r2, r3, r4 }) {
    return new _M44(this.r1.add(r1), this.r2.add(r2), this.r3.add(r3), this.r4.add(r4));
  }
  /** @param {M44} m */
  sub({ r1, r2, r3, r4 }) {
    return new _M44(this.r1.sub(r1), this.r2.sub(r2), this.r3.sub(r3), this.r4.sub(r4));
  }
  /**
   * @overload
   * @param {M44} m
   * @return {M44}
   * 
   * @overload
   * @param {V4} m
   * @return {V4}
   * 
   * @param {M44 | V4} m
   */
  mult(m) {
    if ("x" in m) {
      return new V4(
        this.r1.dot(m),
        this.r2.dot(m),
        this.r3.dot(m),
        this.r4.dot(m)
      );
    }
    return new _M44(
      new V4(this.r1.dot(m.c1), this.r1.dot(m.c2), this.r1.dot(m.c3), this.r1.dot(m.c4)),
      new V4(this.r2.dot(m.c1), this.r2.dot(m.c2), this.r2.dot(m.c3), this.r2.dot(m.c4)),
      new V4(this.r3.dot(m.c1), this.r3.dot(m.c2), this.r3.dot(m.c3), this.r3.dot(m.c4)),
      new V4(this.r4.dot(m.c1), this.r4.dot(m.c2), this.r4.dot(m.c3), this.r4.dot(m.c4))
    );
  }
  toArray() {
    return [...this.r1.toArray(), ...this.r2.toArray(), ...this.r3.toArray(), ...this.r4.toArray()];
  }
  static get identity() {
    return new _M44(
      new V4(1, 0, 0, 0),
      new V4(0, 1, 0, 0),
      new V4(0, 0, 1, 0),
      new V4(0, 0, 0, 1)
    );
  }
  get c1() {
    return new V4(this.r1.x, this.r2.x, this.r3.x, this.r4.x);
  }
  get c2() {
    return new V4(this.r1.y, this.r2.y, this.r3.y, this.r4.y);
  }
  get c3() {
    return new V4(this.r1.z, this.r2.z, this.r3.z, this.r4.z);
  }
  get c4() {
    return new V4(this.r1.w, this.r2.w, this.r3.w, this.r4.w);
  }
  /**
   * @param {WebGL2RenderingContext} gl
   * @param {WebGLUniformLocation} location
   */
  setUniform(gl, location) {
    const data = new Float32Array(this.toArray());
    gl.uniformMatrix4fv(location, true, data);
  }
  get transpose() {
    return new _M44(this.c1, this.c2, this.c3, this.c4);
  }
  get inverse() {
    const [i00, i01, i02, i03] = this.r1.toArray();
    const [i10, i11, i12, i13] = this.r2.toArray();
    const [i20, i21, i22, i23] = this.r3.toArray();
    const [i30, i31, i32, i33] = this.r4.toArray();
    const s0 = i00 * i11 - i10 * i01;
    const s1 = i00 * i12 - i10 * i02;
    const s2 = i00 * i13 - i10 * i03;
    const s3 = i01 * i12 - i11 * i02;
    const s4 = i01 * i13 - i11 * i03;
    const s5 = i02 * i13 - i12 * i03;
    const c5 = i22 * i33 - i32 * i23;
    const c4 = i21 * i33 - i31 * i23;
    const c3 = i21 * i32 - i31 * i22;
    const c2 = i20 * i33 - i30 * i23;
    const c1 = i20 * i32 - i30 * i22;
    const c0 = i20 * i31 - i30 * i21;
    const det = s0 * c5 - s1 * c4 + s2 * c3 + s3 * c2 - s4 * c1 + s5 * c0;
    const invDet = 1 / det;
    return new _M44(
      new V4(
        i11 * c5 - i12 * c4 + i13 * c3,
        -i01 * c5 + i02 * c4 - i03 * c3,
        i31 * s5 - i32 * s4 + i33 * s3,
        -i21 * s5 + i22 * s4 - i23 * s3
      ),
      new V4(
        -i10 * c5 + i12 * c2 - i13 * c1,
        i00 * c5 - i02 * c2 + i03 * c1,
        -i30 * s5 + i32 * s2 - i33 * s1,
        i20 * s5 - i22 * s2 + i23 * s1
      ),
      new V4(
        i10 * c4 - i11 * c2 + i13 * c0,
        -i00 * c4 + i01 * c2 - i03 * c0,
        i30 * s4 - i31 * s2 + i33 * s0,
        -i20 * s4 + i21 * s2 - i23 * s0
      ),
      new V4(
        -i10 * c3 + i11 * c1 - i12 * c0,
        i00 * c3 - i01 * c1 + i02 * c0,
        -i30 * s3 + i31 * s1 - i32 * s0,
        i20 * s3 - i21 * s1 + i22 * s0
      )
    ).scale(invDet);
  }
  /**
   * @param {number} fovy
   * @param {number} aspect
   * @param {number} near
   * @param {number} far
   */
  static perspective(fovy, aspect, near, far) {
    const tanHalfFovy = Math.tan(fovy / 2);
    const x = 1 / (aspect * tanHalfFovy);
    const y = 1 / tanHalfFovy;
    const fpn = far + near;
    const fmn = far - near;
    const oon = 0.5 / near;
    const oof = 0.5 / far;
    const z = -fpn / fmn;
    const w = 1 / (oof - oon);
    return new _M44(
      new V4(x, 0, 0, 0),
      new V4(0, y, 0, 0),
      new V4(0, 0, z, w),
      new V4(0, 0, -1, 0)
    );
  }
  /**
   * @param {V3} eye
   * @param {V3} center
   * @param {V3} up
   */
  static lookAt(eye, center, up) {
    const za = center.sub(eye).normalized;
    const xa = za.cross(up).normalized;
    const ya = xa.cross(za);
    const xd = -xa.dot(eye);
    const yd = -ya.dot(eye);
    const zd = za.dot(eye);
    return new _M44(
      new V4(xa.x, xa.y, xa.z, xd),
      new V4(ya.x, ya.y, ya.z, yd),
      new V4(-za.x, -za.y, -za.z, zd),
      new V4(0, 0, 0, 1)
    );
  }
};

// node_modules/rubiks-js/src/math/quarternion.js
var Quaternion = class _Quaternion {
  /**
   * @param {number} real
   * @param {V3} im
   */
  constructor(real, im) {
    this.real = real;
    this.im = im;
  }
  /**
   * @param {V3} axis
   * @param {number} angle
   * @param {boolean} [degree=true]
   */
  static fromAngle(axis, angle, degree = true) {
    if (degree) {
      angle *= Math.PI / 180;
    }
    const half = angle / 2;
    const real = Math.cos(half);
    const im = axis.normalized.scale(Math.sin(half));
    return new _Quaternion(real, im);
  }
  get matrix() {
    const { x, y, z } = this.im;
    const w = this.real;
    const xx = x * x;
    const yy = y * y;
    const zz = z * z;
    const xy = x * y;
    const xz = x * z;
    const xw = x * w;
    const yz = y * z;
    const yw = y * w;
    const zw = z * w;
    return new M44(
      new V4(1 - 2 * (yy + zz), 2 * (xy - zw), 2 * (xz + yw), 0),
      new V4(2 * (xy + zw), 1 - 2 * (xx + zz), 2 * (yz - xw), 0),
      new V4(2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xx + yy), 0),
      new V4(0, 0, 0, 1)
    );
  }
  /** @param {Quaternion} q */
  mult({ real, im }) {
    return new _Quaternion(this.real * real - this.im.dot(im), this.im.cross(im).add(im.scale(this.real)).add(this.im.scale(real)));
  }
  /** @param {V3} v */
  rotate(v) {
    return new _Quaternion(this.real, this.im.negate).mult(new _Quaternion(0, v)).mult(this).im;
  }
  get conjugate() {
    return new _Quaternion(this.real, this.im.negate);
  }
  get mag() {
    return Math.sqrt(this.real * this.real + this.im.squareMag);
  }
  /** @param {number} n */
  power(n) {
    const { mag } = this;
    const phi = Math.acos(this.real / mag);
    const unit = this.im.normalized;
    const scalar = Math.pow(mag, n);
    return new _Quaternion(scalar * Math.cos(phi * n), unit.scale(scalar * Math.sin(phi * n)));
  }
  static get identity() {
    return new _Quaternion(1, V3.zero);
  }
  /**
   * @param {Quaternion} q1
   * @param {Quaternion} q2
   * @param {number} t
   */
  static slerp(q1, q2, t) {
    return q1.mult(q1.conjugate.mult(q2).power(t));
  }
};

// node_modules/rubiks-js/src/ui/program.js
var _program, _uniformMap, _path, _gl, _Program_instances, createShader_fn;
var Program = class {
  /**
   * @param {string} path
   * @param {string} vertexShaderSource
   * @param {string} fragmentShaderSource
   * @param {WebGL2RenderingContext} gl
   */
  constructor(path, vertexShaderSource, fragmentShaderSource, gl) {
    __privateAdd(this, _Program_instances);
    /** @type {WebGLProgram} */
    __privateAdd(this, _program);
    /** @type {Map<string, WebGLUniformLocation>} */
    __privateAdd(this, _uniformMap);
    /** @type {string} */
    __privateAdd(this, _path);
    /** @type {WebGL2RenderingContext} */
    __privateAdd(this, _gl);
    __privateSet(this, _path, path);
    __privateSet(this, _gl, gl);
    const vertexShader = __privateMethod(this, _Program_instances, createShader_fn).call(this, vertexShaderSource, __privateGet(this, _gl).VERTEX_SHADER, "vertex");
    const fragmentShader = __privateMethod(this, _Program_instances, createShader_fn).call(this, fragmentShaderSource, __privateGet(this, _gl).FRAGMENT_SHADER, "fragment");
    const p = __privateGet(this, _gl).createProgram();
    if (!p)
      throw new Error("Fatal: webgl could not create program object!");
    __privateSet(this, _program, p);
    __privateGet(this, _gl).attachShader(__privateGet(this, _program), vertexShader);
    __privateGet(this, _gl).attachShader(__privateGet(this, _program), fragmentShader);
    __privateGet(this, _gl).linkProgram(__privateGet(this, _program));
    const success = __privateGet(this, _gl).getProgramParameter(__privateGet(this, _program), __privateGet(this, _gl).LINK_STATUS);
    if (!success) {
      const info = __privateGet(this, _gl).getProgramInfoLog(__privateGet(this, _program));
      __privateGet(this, _gl).deleteProgram(__privateGet(this, _program));
      throw new Error(`Link Program: ${info}`);
    }
    const numUniforms = (
      /** @type {number} */
      __privateGet(this, _gl).getProgramParameter(__privateGet(this, _program), __privateGet(this, _gl).ACTIVE_UNIFORMS)
    );
    const uniformIndices = [...Array(numUniforms).keys()];
    const uniformNames = uniformIndices.map((index) => {
      const info = __privateGet(this, _gl).getActiveUniform(__privateGet(this, _program), index);
      if (info == null) {
        throw new Error("failed to get active uniform");
      }
      const location = __privateGet(this, _gl).getUniformLocation(__privateGet(this, _program), info.name);
      if (location == null) {
        throw new Error("failed to get uniform location");
      }
      return (
        /** @type {[string, WebGLUniformLocation]} */
        [info.name, location]
      );
    });
    __privateSet(this, _uniformMap, new Map(uniformNames));
  }
  use() {
    if (!__privateGet(this, _program)) {
      throw new Error("Fatal: program does not exists!");
    }
    __privateGet(this, _gl).useProgram(__privateGet(this, _program));
  }
  /**
   * @param {string} name
   * @param {import('../types').Uniform} u
   */
  uniform(name, u) {
    const location = __privateGet(this, _uniformMap).get(name);
    if (location == void 0) {
      throw new Error(`Fatal: unkown name: ${name}`);
    }
    u.setUniform(__privateGet(this, _gl), location);
  }
};
_program = new WeakMap();
_uniformMap = new WeakMap();
_path = new WeakMap();
_gl = new WeakMap();
_Program_instances = new WeakSet();
/**
 * @param {string} source
 * @param {number} type
 * @param {string} typeStr
 * @returns {WebGLShader}
 */
createShader_fn = function(source, type, typeStr) {
  const shader = __privateGet(this, _gl).createShader(type);
  if (!shader)
    throw new Error("Fatal: webgl could not create shader object!");
  __privateGet(this, _gl).shaderSource(shader, source);
  __privateGet(this, _gl).compileShader(shader);
  const success = (
    /** @type {boolean} */
    __privateGet(this, _gl).getShaderParameter(shader, __privateGet(this, _gl).COMPILE_STATUS)
  );
  if (success) {
    return shader;
  }
  const info = __privateGet(this, _gl).getShaderInfoLog(shader);
  __privateGet(this, _gl).deleteShader(shader);
  throw new Error(`Compile '${__privateGet(this, _path)}': ${typeStr}: ${info}`);
};

// node_modules/rubiks-js/src/ui/transform.js
var Transform = class _Transform {
  /**
   * @param {V3} position
   * @param {Quaternion} rotation
   * @param {TParent} parent
   */
  constructor(position, rotation, parent) {
    /** @type {M44} */
    __publicField(this, "localTransform");
    /** @type {M44} */
    __publicField(this, "globalTransform");
    /** @type {TChild[]} */
    __publicField(this, "children", []);
    this._position = position;
    this._rotation = rotation;
    this.parent = parent;
    this.setTransforms();
  }
  /** @protected */
  setTransforms() {
    const localTransform = _Transform.getLocalTransform(this._position, this._rotation);
    this.localTransform = localTransform;
    if (!this.parent) {
      this.globalTransform = localTransform;
    } else {
      const parentTransform = this.parent.transform.globalTransform;
      this.globalTransform = parentTransform.mult(localTransform);
    }
    this.children.forEach((child) => child.transform.setTransforms());
  }
  /** @param {V3} v */
  apply({ x, y, z }) {
    return this.globalTransform.mult(new V4(x, y, z, 1)).toV3();
  }
  /**
   * @param {V3} axis
   * @param {number} angle
   */
  rotate(axis, angle) {
    this.rotation = this._rotation.mult(Quaternion.fromAngle(this._rotation.rotate(axis), angle));
  }
  /** @param {V3} value */
  set position(value) {
    this._position = value;
    this.setTransforms();
  }
  /** @param {Quaternion} value */
  set rotation(value) {
    this._rotation = value;
    this.setTransforms();
  }
  get position() {
    return this._position;
  }
  get rotation() {
    return this._rotation;
  }
  /**
   * @param {V3} position
   * @param {Quaternion} rotation 
   * @returns {M44} 
   */
  static getLocalTransform({ x, y, z }, rotation) {
    const transform = rotation.matrix;
    transform.r1.w = x;
    transform.r2.w = y;
    transform.r3.w = z;
    return transform;
  }
};

// node_modules/rubiks-js/src/ui/facelet.js
var FaceletTransform = class extends Transform {
  /**
   * @param {V3} position
   * @param {Quaternion} rotation
   * @param {Cubie} parent
   */
  constructor(position, rotation, parent) {
    super(position, rotation, parent);
    /** @type {V3} */
    __publicField(this, "left");
    /** @type {V3} */
    __publicField(this, "top");
    /** @type {V3} */
    __publicField(this, "normal");
    /** @type {V3} */
    __publicField(this, "topLeft");
    /** @type {V3} */
    __publicField(this, "bottomRight");
    this.setTransforms();
  }
  /** @protected */
  setTransforms() {
    super.setTransforms();
    const rotationTransform = this.globalTransform.inverse.transpose;
    this.left = rotationTransform.mult(new V4(0, 0, -1, 1)).toV3().normalized;
    this.top = rotationTransform.mult(new V4(0, -1, 0, 1)).toV3().normalized;
    this.normal = rotationTransform.mult(new V4(-1, 0, 0, 1)).toV3().normalized;
    this.topLeft = this.globalTransform.mult(new V4(0, 0.5, 0.5, 1)).toV3();
    this.bottomRight = this.topLeft.add(this.left).add(this.top);
  }
};
var _hoveringMult;
var Facelet = class {
  /**
   * @param {FaceletTransform} transform
   * @param {number} side
   * @param {number[]} uvs
   * @param {V3} hoveringMult
   */
  constructor(transform, side, uvs, hoveringMult) {
    __publicField(this, "hovering", false);
    /** @type {V3} */
    __privateAdd(this, _hoveringMult);
    this.transform = transform;
    this.side = side;
    this.uvs = uvs;
    __privateSet(this, _hoveringMult, hoveringMult);
  }
  /**
   * @param {Program} program
   * @param {WebGL2RenderingContext} gl
   * @param {WebGLBuffer} uvsVbo
   */
  render(program, gl, uvsVbo) {
    gl.bindBuffer(gl.ARRAY_BUFFER, uvsVbo);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.uvs), gl.STATIC_DRAW);
    gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 8, 0);
    gl.bindBuffer(gl.ARRAY_BUFFER, null);
    program.uniform("model", this.transform.globalTransform);
    program.uniform("colorMult", this.hovering ? __privateGet(this, _hoveringMult) : V3.one);
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
  }
};
_hoveringMult = new WeakMap();
var InsideFacelet = class {
  /** @param {Transform<any, Cubie>} transform */
  constructor(transform) {
    this.transform = transform;
  }
  /**
   * @param {Program} program
   * @param {WebGL2RenderingContext} gl
   */
  render(program, gl) {
    program.uniform("model", this.transform.globalTransform);
    program.uniform("colorMult", V3.zero);
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
  }
};

// node_modules/rubiks-js/src/ui/cubie.js
var positionForSide = [
  V3.right,
  V3.left,
  V3.down,
  V3.up,
  V3.back,
  V3.forward
].map((v) => v.scale(0.5));
var rotationForSide = [
  Quaternion.identity,
  Quaternion.identity,
  Quaternion.fromAngle(V3.back, 90),
  Quaternion.fromAngle(V3.back, 90),
  Quaternion.fromAngle(V3.back, 90).mult(Quaternion.fromAngle(V3.down, 90)),
  Quaternion.fromAngle(V3.back, 90).mult(Quaternion.fromAngle(V3.down, 90))
];
var isInside = (side, index) => {
  const axis = Math.floor(side / 2);
  const invert = side % 2;
  const coordinate = Math.floor(index / Math.pow(3, axis)) % 3;
  return coordinate === 1 || coordinate === 0 && invert === 1 || coordinate === 2 && invert === 0;
};
var indexToPosition = (index) => {
  const x = Math.floor(index / 1) % 3;
  const y = Math.floor(index / 3) % 3;
  const z = Math.floor(index / 9) % 3;
  return [x, y, z];
};
var positionToUvs = (pos, side, uvs) => {
  const axis = Math.floor(side / 2);
  const uvCoords = [];
  for (let i = 0; i < 3; i++) {
    if (i !== axis) {
      uvCoords.push(pos[i]);
    }
  }
  const sideIndex = uvCoords[0] + uvCoords[1] * 3;
  return uvs[side][sideIndex];
};
var Cubie = class {
  /**
   * @param {number} index
   * @param {number[][][]} uvs
   * @param {V3[]} hoveringColors
   * @param {import('./rubiks').Rubiks} parent
   */
  constructor(index, uvs, hoveringColors, parent) {
    /** @type {Facelet[]} */
    __publicField(this, "facelets", []);
    /** @type {Transform<Facelet | InsideFacelet, import('./rubiks').Rubiks>} */
    __publicField(this, "transform");
    this.index = index;
    const pos = indexToPosition(index);
    const position = new V3(pos[0], pos[1], pos[2]).sub(V3.one);
    this.transform = new Transform(position, Quaternion.identity, parent);
    for (let side = 0; side < 6; side++) {
      const inside = isInside(side, this.index);
      const position2 = positionForSide[side];
      const rotation = rotationForSide[side];
      if (inside) {
        const transform2 = new Transform(position2, rotation, this);
        const facelet2 = new InsideFacelet(transform2);
        this.transform.children.push(facelet2);
        continue;
      }
      const uv = positionToUvs(pos, side, uvs);
      const transform = new FaceletTransform(position2, rotation, this);
      const facelet = new Facelet(transform, side, uv, hoveringColors[side]);
      this.transform.children.push(facelet);
      this.facelets.push(facelet);
    }
  }
  /**
   * @param {number} side
   * @returns {Facelet}
   */
  getFaceletOfSide(side) {
    return (
      /** @type {Facelet} */
      this.facelets.find((facelet) => facelet.side === side)
    );
  }
  /**
   * @param {import('./program').Program} program
   * @param {WebGL2RenderingContext} gl
   * @param {WebGLBuffer} uvsVbo
   */
  render(program, gl, uvsVbo) {
    this.transform.children.forEach((child) => child.render.call(child, program, gl, uvsVbo));
  }
};

export {
  V2,
  V3,
  V4,
  M44,
  Quaternion,
  Program,
  Transform,
  isInside,
  indexToPosition,
  positionToUvs,
  Cubie
};
//# sourceMappingURL=chunk-ROHLD3FA.js.map
