From 3d9050c9aa1d1297928eba810610088b5b58786f Mon Sep 17 00:00:00 2001 From: Rezmason Date: Wed, 27 Oct 2021 22:45:01 -0700 Subject: [PATCH] Upgraded glMatrix to the latest version, which contains mat4.perspectiveZO, the perspective function that works for WebGPU. --- lib/gl-matrix.js | 2408 +++++++++++++++++++++++++--------------------- 1 file changed, 1324 insertions(+), 1084 deletions(-) diff --git a/lib/gl-matrix.js b/lib/gl-matrix.js index 932bed2..b98099d 100644 --- a/lib/gl-matrix.js +++ b/lib/gl-matrix.js @@ -3,9 +3,9 @@ @fileoverview gl-matrix - High performance matrix and vector operations @author Brandon Jones @author Colin MacKenzie IV -@version 3.1.0 +@version 3.4.0 -Copyright (c) 2015-2019, Brandon Jones, Colin MacKenzie IV. +Copyright (c) 2015-2021, Brandon Jones, Colin MacKenzie IV. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,8 +29,8 @@ THE SOFTWARE. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (global = global || self, factory(global.glMatrix = {})); -}(this, function (exports) { 'use strict'; + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.glMatrix = {})); +})(this, (function (exports) { 'use strict'; /** * Common utilities @@ -38,12 +38,13 @@ THE SOFTWARE. */ // Configuration Constants var EPSILON = 0.000001; - var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array; + var ARRAY_TYPE = typeof Float32Array !== "undefined" ? Float32Array : Array; var RANDOM = Math.random; + var ANGLE_ORDER = "zyx"; /** * Sets the type of array used when creating new vectors and matrices * - * @param {Type} type Array type, such as Float32Array or Array + * @param {Float32ArrayConstructor | ArrayConstructor} type Array type, such as Float32Array or Array */ function setMatrixArrayType(type) { @@ -69,7 +70,7 @@ THE SOFTWARE. * @returns {Boolean} True if the numbers are approximately equal, false otherwise. */ - function equals(a, b) { + function equals$9(a, b) { return Math.abs(a - b) <= EPSILON * Math.max(1.0, Math.abs(a), Math.abs(b)); } if (!Math.hypot) Math.hypot = function () { @@ -84,12 +85,14 @@ THE SOFTWARE. }; var common = /*#__PURE__*/Object.freeze({ + __proto__: null, EPSILON: EPSILON, get ARRAY_TYPE () { return ARRAY_TYPE; }, RANDOM: RANDOM, + ANGLE_ORDER: ANGLE_ORDER, setMatrixArrayType: setMatrixArrayType, toRadian: toRadian, - equals: equals + equals: equals$9 }); /** @@ -103,7 +106,7 @@ THE SOFTWARE. * @returns {mat2} a new 2x2 matrix */ - function create() { + function create$8() { var out = new ARRAY_TYPE(4); if (ARRAY_TYPE != Float32Array) { @@ -118,11 +121,11 @@ THE SOFTWARE. /** * Creates a new mat2 initialized with values from an existing matrix * - * @param {mat2} a matrix to clone + * @param {ReadonlyMat2} a matrix to clone * @returns {mat2} a new 2x2 matrix */ - function clone(a) { + function clone$8(a) { var out = new ARRAY_TYPE(4); out[0] = a[0]; out[1] = a[1]; @@ -134,11 +137,11 @@ THE SOFTWARE. * Copy the values from one mat2 to another * * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix + * @param {ReadonlyMat2} a the source matrix * @returns {mat2} out */ - function copy(out, a) { + function copy$8(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; @@ -152,7 +155,7 @@ THE SOFTWARE. * @returns {mat2} out */ - function identity(out) { + function identity$5(out) { out[0] = 1; out[1] = 0; out[2] = 0; @@ -169,7 +172,7 @@ THE SOFTWARE. * @returns {mat2} out A new 2x2 matrix */ - function fromValues(m00, m01, m10, m11) { + function fromValues$8(m00, m01, m10, m11) { var out = new ARRAY_TYPE(4); out[0] = m00; out[1] = m01; @@ -188,7 +191,7 @@ THE SOFTWARE. * @returns {mat2} out */ - function set(out, m00, m01, m10, m11) { + function set$8(out, m00, m01, m10, m11) { out[0] = m00; out[1] = m01; out[2] = m10; @@ -199,11 +202,11 @@ THE SOFTWARE. * Transpose the values of a mat2 * * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix + * @param {ReadonlyMat2} a the source matrix * @returns {mat2} out */ - function transpose(out, a) { + function transpose$2(out, a) { // If we are transposing ourselves we can skip a few steps but have to cache // some values if (out === a) { @@ -223,11 +226,11 @@ THE SOFTWARE. * Inverts a mat2 * * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix + * @param {ReadonlyMat2} a the source matrix * @returns {mat2} out */ - function invert(out, a) { + function invert$5(out, a) { var a0 = a[0], a1 = a[1], a2 = a[2], @@ -250,12 +253,12 @@ THE SOFTWARE. * Calculates the adjugate of a mat2 * * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix + * @param {ReadonlyMat2} a the source matrix * @returns {mat2} out */ - function adjoint(out, a) { - // Caching this value is nessecary if out == a + function adjoint$2(out, a) { + // Caching this value is necessary if out == a var a0 = a[0]; out[0] = a[3]; out[1] = -a[1]; @@ -266,23 +269,23 @@ THE SOFTWARE. /** * Calculates the determinant of a mat2 * - * @param {mat2} a the source matrix + * @param {ReadonlyMat2} a the source matrix * @returns {Number} determinant of a */ - function determinant(a) { + function determinant$3(a) { return a[0] * a[3] - a[2] * a[1]; } /** * Multiplies two mat2's * * @param {mat2} out the receiving matrix - * @param {mat2} a the first operand - * @param {mat2} b the second operand + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand * @returns {mat2} out */ - function multiply(out, a, b) { + function multiply$8(out, a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], @@ -301,12 +304,12 @@ THE SOFTWARE. * Rotates a mat2 by the given angle * * @param {mat2} out the receiving matrix - * @param {mat2} a the matrix to rotate + * @param {ReadonlyMat2} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat2} out */ - function rotate(out, a, rad) { + function rotate$4(out, a, rad) { var a0 = a[0], a1 = a[1], a2 = a[2], @@ -323,12 +326,12 @@ THE SOFTWARE. * Scales the mat2 by the dimensions in the given vec2 * * @param {mat2} out the receiving matrix - * @param {mat2} a the matrix to rotate - * @param {vec2} v the vec2 to scale the matrix by + * @param {ReadonlyMat2} a the matrix to rotate + * @param {ReadonlyVec2} v the vec2 to scale the matrix by * @returns {mat2} out **/ - function scale(out, a, v) { + function scale$8(out, a, v) { var a0 = a[0], a1 = a[1], a2 = a[2], @@ -353,7 +356,7 @@ THE SOFTWARE. * @returns {mat2} out */ - function fromRotation(out, rad) { + function fromRotation$4(out, rad) { var s = Math.sin(rad); var c = Math.cos(rad); out[0] = c; @@ -370,11 +373,11 @@ THE SOFTWARE. * mat2.scale(dest, dest, vec); * * @param {mat2} out mat2 receiving operation result - * @param {vec2} v Scaling vector + * @param {ReadonlyVec2} v Scaling vector * @returns {mat2} out */ - function fromScaling(out, v) { + function fromScaling$3(out, v) { out[0] = v[0]; out[1] = 0; out[2] = 0; @@ -384,29 +387,29 @@ THE SOFTWARE. /** * Returns a string representation of a mat2 * - * @param {mat2} a matrix to represent as a string + * @param {ReadonlyMat2} a matrix to represent as a string * @returns {String} string representation of the matrix */ - function str(a) { - return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; + function str$8(a) { + return "mat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; } /** * Returns Frobenius norm of a mat2 * - * @param {mat2} a the matrix to calculate Frobenius norm of + * @param {ReadonlyMat2} a the matrix to calculate Frobenius norm of * @returns {Number} Frobenius norm */ - function frob(a) { + function frob$3(a) { return Math.hypot(a[0], a[1], a[2], a[3]); } /** * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix - * @param {mat2} L the lower triangular matrix - * @param {mat2} D the diagonal matrix - * @param {mat2} U the upper triangular matrix - * @param {mat2} a the input matrix to factorize + * @param {ReadonlyMat2} L the lower triangular matrix + * @param {ReadonlyMat2} D the diagonal matrix + * @param {ReadonlyMat2} U the upper triangular matrix + * @param {ReadonlyMat2} a the input matrix to factorize */ function LDU(L, D, U, a) { @@ -420,12 +423,12 @@ THE SOFTWARE. * Adds two mat2's * * @param {mat2} out the receiving matrix - * @param {mat2} a the first operand - * @param {mat2} b the second operand + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand * @returns {mat2} out */ - function add(out, a, b) { + function add$8(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; @@ -436,12 +439,12 @@ THE SOFTWARE. * Subtracts matrix b from matrix a * * @param {mat2} out the receiving matrix - * @param {mat2} a the first operand - * @param {mat2} b the second operand + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand * @returns {mat2} out */ - function subtract(out, a, b) { + function subtract$6(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; @@ -451,23 +454,23 @@ THE SOFTWARE. /** * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) * - * @param {mat2} a The first matrix. - * @param {mat2} b The second matrix. + * @param {ReadonlyMat2} a The first matrix. + * @param {ReadonlyMat2} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ - function exactEquals(a, b) { + function exactEquals$8(a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; } /** * Returns whether or not the matrices have approximately the same elements in the same position. * - * @param {mat2} a The first matrix. - * @param {mat2} b The second matrix. + * @param {ReadonlyMat2} a The first matrix. + * @param {ReadonlyMat2} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ - function equals$1(a, b) { + function equals$8(a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], @@ -482,12 +485,12 @@ THE SOFTWARE. * Multiply each element of the matrix by a scalar. * * @param {mat2} out the receiving matrix - * @param {mat2} a the matrix to scale + * @param {ReadonlyMat2} a the matrix to scale * @param {Number} b amount to scale the matrix's elements by * @returns {mat2} out */ - function multiplyScalar(out, a, b) { + function multiplyScalar$3(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; @@ -498,13 +501,13 @@ THE SOFTWARE. * Adds two mat2's after multiplying each element of the second operand by a scalar value. * * @param {mat2} out the receiving vector - * @param {mat2} a the first operand - * @param {mat2} b the second operand + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand * @param {Number} scale the amount to scale b's elements by before adding * @returns {mat2} out */ - function multiplyScalarAndAdd(out, a, b, scale) { + function multiplyScalarAndAdd$3(out, a, b, scale) { out[0] = a[0] + b[0] * scale; out[1] = a[1] + b[1] * scale; out[2] = a[2] + b[2] * scale; @@ -516,52 +519,53 @@ THE SOFTWARE. * @function */ - var mul = multiply; + var mul$8 = multiply$8; /** * Alias for {@link mat2.subtract} * @function */ - var sub = subtract; + var sub$6 = subtract$6; var mat2 = /*#__PURE__*/Object.freeze({ - create: create, - clone: clone, - copy: copy, - identity: identity, - fromValues: fromValues, - set: set, - transpose: transpose, - invert: invert, - adjoint: adjoint, - determinant: determinant, - multiply: multiply, - rotate: rotate, - scale: scale, - fromRotation: fromRotation, - fromScaling: fromScaling, - str: str, - frob: frob, + __proto__: null, + create: create$8, + clone: clone$8, + copy: copy$8, + identity: identity$5, + fromValues: fromValues$8, + set: set$8, + transpose: transpose$2, + invert: invert$5, + adjoint: adjoint$2, + determinant: determinant$3, + multiply: multiply$8, + rotate: rotate$4, + scale: scale$8, + fromRotation: fromRotation$4, + fromScaling: fromScaling$3, + str: str$8, + frob: frob$3, LDU: LDU, - add: add, - subtract: subtract, - exactEquals: exactEquals, - equals: equals$1, - multiplyScalar: multiplyScalar, - multiplyScalarAndAdd: multiplyScalarAndAdd, - mul: mul, - sub: sub + add: add$8, + subtract: subtract$6, + exactEquals: exactEquals$8, + equals: equals$8, + multiplyScalar: multiplyScalar$3, + multiplyScalarAndAdd: multiplyScalarAndAdd$3, + mul: mul$8, + sub: sub$6 }); /** * 2x3 Matrix * @module mat2d - * * @description * A mat2d contains six elements defined as: *
-   * [a, b, c,
-   *  d, tx, ty]
+   * [a, b,
+   *  c, d,
+   *  tx, ty]
    * 
* This is a short form for the 3x3 matrix: *
@@ -578,7 +582,7 @@ THE SOFTWARE.
    * @returns {mat2d} a new 2x3 matrix
    */
 
-  function create$1() {
+  function create$7() {
     var out = new ARRAY_TYPE(6);
 
     if (ARRAY_TYPE != Float32Array) {
@@ -595,11 +599,11 @@ THE SOFTWARE.
   /**
    * Creates a new mat2d initialized with values from an existing matrix
    *
-   * @param {mat2d} a matrix to clone
+   * @param {ReadonlyMat2d} a matrix to clone
    * @returns {mat2d} a new 2x3 matrix
    */
 
-  function clone$1(a) {
+  function clone$7(a) {
     var out = new ARRAY_TYPE(6);
     out[0] = a[0];
     out[1] = a[1];
@@ -613,11 +617,11 @@ THE SOFTWARE.
    * Copy the values from one mat2d to another
    *
    * @param {mat2d} out the receiving matrix
-   * @param {mat2d} a the source matrix
+   * @param {ReadonlyMat2d} a the source matrix
    * @returns {mat2d} out
    */
 
-  function copy$1(out, a) {
+  function copy$7(out, a) {
     out[0] = a[0];
     out[1] = a[1];
     out[2] = a[2];
@@ -633,7 +637,7 @@ THE SOFTWARE.
    * @returns {mat2d} out
    */
 
-  function identity$1(out) {
+  function identity$4(out) {
     out[0] = 1;
     out[1] = 0;
     out[2] = 0;
@@ -654,7 +658,7 @@ THE SOFTWARE.
    * @returns {mat2d} A new mat2d
    */
 
-  function fromValues$1(a, b, c, d, tx, ty) {
+  function fromValues$7(a, b, c, d, tx, ty) {
     var out = new ARRAY_TYPE(6);
     out[0] = a;
     out[1] = b;
@@ -677,7 +681,7 @@ THE SOFTWARE.
    * @returns {mat2d} out
    */
 
-  function set$1(out, a, b, c, d, tx, ty) {
+  function set$7(out, a, b, c, d, tx, ty) {
     out[0] = a;
     out[1] = b;
     out[2] = c;
@@ -690,11 +694,11 @@ THE SOFTWARE.
    * Inverts a mat2d
    *
    * @param {mat2d} out the receiving matrix
-   * @param {mat2d} a the source matrix
+   * @param {ReadonlyMat2d} a the source matrix
    * @returns {mat2d} out
    */
 
-  function invert$1(out, a) {
+  function invert$4(out, a) {
     var aa = a[0],
         ab = a[1],
         ac = a[2],
@@ -719,23 +723,23 @@ THE SOFTWARE.
   /**
    * Calculates the determinant of a mat2d
    *
-   * @param {mat2d} a the source matrix
+   * @param {ReadonlyMat2d} a the source matrix
    * @returns {Number} determinant of a
    */
 
-  function determinant$1(a) {
+  function determinant$2(a) {
     return a[0] * a[3] - a[1] * a[2];
   }
   /**
    * Multiplies two mat2d's
    *
    * @param {mat2d} out the receiving matrix
-   * @param {mat2d} a the first operand
-   * @param {mat2d} b the second operand
+   * @param {ReadonlyMat2d} a the first operand
+   * @param {ReadonlyMat2d} b the second operand
    * @returns {mat2d} out
    */
 
-  function multiply$1(out, a, b) {
+  function multiply$7(out, a, b) {
     var a0 = a[0],
         a1 = a[1],
         a2 = a[2],
@@ -760,12 +764,12 @@ THE SOFTWARE.
    * Rotates a mat2d by the given angle
    *
    * @param {mat2d} out the receiving matrix
-   * @param {mat2d} a the matrix to rotate
+   * @param {ReadonlyMat2d} a the matrix to rotate
    * @param {Number} rad the angle to rotate the matrix by
    * @returns {mat2d} out
    */
 
-  function rotate$1(out, a, rad) {
+  function rotate$3(out, a, rad) {
     var a0 = a[0],
         a1 = a[1],
         a2 = a[2],
@@ -786,12 +790,12 @@ THE SOFTWARE.
    * Scales the mat2d by the dimensions in the given vec2
    *
    * @param {mat2d} out the receiving matrix
-   * @param {mat2d} a the matrix to translate
-   * @param {vec2} v the vec2 to scale the matrix by
+   * @param {ReadonlyMat2d} a the matrix to translate
+   * @param {ReadonlyVec2} v the vec2 to scale the matrix by
    * @returns {mat2d} out
    **/
 
-  function scale$1(out, a, v) {
+  function scale$7(out, a, v) {
     var a0 = a[0],
         a1 = a[1],
         a2 = a[2],
@@ -812,12 +816,12 @@ THE SOFTWARE.
    * Translates the mat2d by the dimensions in the given vec2
    *
    * @param {mat2d} out the receiving matrix
-   * @param {mat2d} a the matrix to translate
-   * @param {vec2} v the vec2 to translate the matrix by
+   * @param {ReadonlyMat2d} a the matrix to translate
+   * @param {ReadonlyVec2} v the vec2 to translate the matrix by
    * @returns {mat2d} out
    **/
 
-  function translate(out, a, v) {
+  function translate$3(out, a, v) {
     var a0 = a[0],
         a1 = a[1],
         a2 = a[2],
@@ -846,7 +850,7 @@ THE SOFTWARE.
    * @returns {mat2d} out
    */
 
-  function fromRotation$1(out, rad) {
+  function fromRotation$3(out, rad) {
     var s = Math.sin(rad),
         c = Math.cos(rad);
     out[0] = c;
@@ -865,11 +869,11 @@ THE SOFTWARE.
    *     mat2d.scale(dest, dest, vec);
    *
    * @param {mat2d} out mat2d receiving operation result
-   * @param {vec2} v Scaling vector
+   * @param {ReadonlyVec2} v Scaling vector
    * @returns {mat2d} out
    */
 
-  function fromScaling$1(out, v) {
+  function fromScaling$2(out, v) {
     out[0] = v[0];
     out[1] = 0;
     out[2] = 0;
@@ -886,11 +890,11 @@ THE SOFTWARE.
    *     mat2d.translate(dest, dest, vec);
    *
    * @param {mat2d} out mat2d receiving operation result
-   * @param {vec2} v Translation vector
+   * @param {ReadonlyVec2} v Translation vector
    * @returns {mat2d} out
    */
 
-  function fromTranslation(out, v) {
+  function fromTranslation$3(out, v) {
     out[0] = 1;
     out[1] = 0;
     out[2] = 0;
@@ -902,33 +906,33 @@ THE SOFTWARE.
   /**
    * Returns a string representation of a mat2d
    *
-   * @param {mat2d} a matrix to represent as a string
+   * @param {ReadonlyMat2d} a matrix to represent as a string
    * @returns {String} string representation of the matrix
    */
 
-  function str$1(a) {
-    return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ')';
+  function str$7(a) {
+    return "mat2d(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ")";
   }
   /**
    * Returns Frobenius norm of a mat2d
    *
-   * @param {mat2d} a the matrix to calculate Frobenius norm of
+   * @param {ReadonlyMat2d} a the matrix to calculate Frobenius norm of
    * @returns {Number} Frobenius norm
    */
 
-  function frob$1(a) {
+  function frob$2(a) {
     return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], 1);
   }
   /**
    * Adds two mat2d's
    *
    * @param {mat2d} out the receiving matrix
-   * @param {mat2d} a the first operand
-   * @param {mat2d} b the second operand
+   * @param {ReadonlyMat2d} a the first operand
+   * @param {ReadonlyMat2d} b the second operand
    * @returns {mat2d} out
    */
 
-  function add$1(out, a, b) {
+  function add$7(out, a, b) {
     out[0] = a[0] + b[0];
     out[1] = a[1] + b[1];
     out[2] = a[2] + b[2];
@@ -941,12 +945,12 @@ THE SOFTWARE.
    * Subtracts matrix b from matrix a
    *
    * @param {mat2d} out the receiving matrix
-   * @param {mat2d} a the first operand
-   * @param {mat2d} b the second operand
+   * @param {ReadonlyMat2d} a the first operand
+   * @param {ReadonlyMat2d} b the second operand
    * @returns {mat2d} out
    */
 
-  function subtract$1(out, a, b) {
+  function subtract$5(out, a, b) {
     out[0] = a[0] - b[0];
     out[1] = a[1] - b[1];
     out[2] = a[2] - b[2];
@@ -959,12 +963,12 @@ THE SOFTWARE.
    * Multiply each element of the matrix by a scalar.
    *
    * @param {mat2d} out the receiving matrix
-   * @param {mat2d} a the matrix to scale
+   * @param {ReadonlyMat2d} a the matrix to scale
    * @param {Number} b amount to scale the matrix's elements by
    * @returns {mat2d} out
    */
 
-  function multiplyScalar$1(out, a, b) {
+  function multiplyScalar$2(out, a, b) {
     out[0] = a[0] * b;
     out[1] = a[1] * b;
     out[2] = a[2] * b;
@@ -977,13 +981,13 @@ THE SOFTWARE.
    * Adds two mat2d's after multiplying each element of the second operand by a scalar value.
    *
    * @param {mat2d} out the receiving vector
-   * @param {mat2d} a the first operand
-   * @param {mat2d} b the second operand
+   * @param {ReadonlyMat2d} a the first operand
+   * @param {ReadonlyMat2d} b the second operand
    * @param {Number} scale the amount to scale b's elements by before adding
    * @returns {mat2d} out
    */
 
-  function multiplyScalarAndAdd$1(out, a, b, scale) {
+  function multiplyScalarAndAdd$2(out, a, b, scale) {
     out[0] = a[0] + b[0] * scale;
     out[1] = a[1] + b[1] * scale;
     out[2] = a[2] + b[2] * scale;
@@ -995,23 +999,23 @@ THE SOFTWARE.
   /**
    * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
    *
-   * @param {mat2d} a The first matrix.
-   * @param {mat2d} b The second matrix.
+   * @param {ReadonlyMat2d} a The first matrix.
+   * @param {ReadonlyMat2d} b The second matrix.
    * @returns {Boolean} True if the matrices are equal, false otherwise.
    */
 
-  function exactEquals$1(a, b) {
+  function exactEquals$7(a, b) {
     return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5];
   }
   /**
    * Returns whether or not the matrices have approximately the same elements in the same position.
    *
-   * @param {mat2d} a The first matrix.
-   * @param {mat2d} b The second matrix.
+   * @param {ReadonlyMat2d} a The first matrix.
+   * @param {ReadonlyMat2d} b The second matrix.
    * @returns {Boolean} True if the matrices are equal, false otherwise.
    */
 
-  function equals$2(a, b) {
+  function equals$7(a, b) {
     var a0 = a[0],
         a1 = a[1],
         a2 = a[2],
@@ -1031,40 +1035,41 @@ THE SOFTWARE.
    * @function
    */
 
-  var mul$1 = multiply$1;
+  var mul$7 = multiply$7;
   /**
    * Alias for {@link mat2d.subtract}
    * @function
    */
 
-  var sub$1 = subtract$1;
+  var sub$5 = subtract$5;
 
   var mat2d = /*#__PURE__*/Object.freeze({
-    create: create$1,
-    clone: clone$1,
-    copy: copy$1,
-    identity: identity$1,
-    fromValues: fromValues$1,
-    set: set$1,
-    invert: invert$1,
-    determinant: determinant$1,
-    multiply: multiply$1,
-    rotate: rotate$1,
-    scale: scale$1,
-    translate: translate,
-    fromRotation: fromRotation$1,
-    fromScaling: fromScaling$1,
-    fromTranslation: fromTranslation,
-    str: str$1,
-    frob: frob$1,
-    add: add$1,
-    subtract: subtract$1,
-    multiplyScalar: multiplyScalar$1,
-    multiplyScalarAndAdd: multiplyScalarAndAdd$1,
-    exactEquals: exactEquals$1,
-    equals: equals$2,
-    mul: mul$1,
-    sub: sub$1
+    __proto__: null,
+    create: create$7,
+    clone: clone$7,
+    copy: copy$7,
+    identity: identity$4,
+    fromValues: fromValues$7,
+    set: set$7,
+    invert: invert$4,
+    determinant: determinant$2,
+    multiply: multiply$7,
+    rotate: rotate$3,
+    scale: scale$7,
+    translate: translate$3,
+    fromRotation: fromRotation$3,
+    fromScaling: fromScaling$2,
+    fromTranslation: fromTranslation$3,
+    str: str$7,
+    frob: frob$2,
+    add: add$7,
+    subtract: subtract$5,
+    multiplyScalar: multiplyScalar$2,
+    multiplyScalarAndAdd: multiplyScalarAndAdd$2,
+    exactEquals: exactEquals$7,
+    equals: equals$7,
+    mul: mul$7,
+    sub: sub$5
   });
 
   /**
@@ -1078,7 +1083,7 @@ THE SOFTWARE.
    * @returns {mat3} a new 3x3 matrix
    */
 
-  function create$2() {
+  function create$6() {
     var out = new ARRAY_TYPE(9);
 
     if (ARRAY_TYPE != Float32Array) {
@@ -1099,11 +1104,11 @@ THE SOFTWARE.
    * Copies the upper-left 3x3 values into the given mat3.
    *
    * @param {mat3} out the receiving 3x3 matrix
-   * @param {mat4} a   the source 4x4 matrix
+   * @param {ReadonlyMat4} a   the source 4x4 matrix
    * @returns {mat3} out
    */
 
-  function fromMat4(out, a) {
+  function fromMat4$1(out, a) {
     out[0] = a[0];
     out[1] = a[1];
     out[2] = a[2];
@@ -1118,11 +1123,11 @@ THE SOFTWARE.
   /**
    * Creates a new mat3 initialized with values from an existing matrix
    *
-   * @param {mat3} a matrix to clone
+   * @param {ReadonlyMat3} a matrix to clone
    * @returns {mat3} a new 3x3 matrix
    */
 
-  function clone$2(a) {
+  function clone$6(a) {
     var out = new ARRAY_TYPE(9);
     out[0] = a[0];
     out[1] = a[1];
@@ -1139,11 +1144,11 @@ THE SOFTWARE.
    * Copy the values from one mat3 to another
    *
    * @param {mat3} out the receiving matrix
-   * @param {mat3} a the source matrix
+   * @param {ReadonlyMat3} a the source matrix
    * @returns {mat3} out
    */
 
-  function copy$2(out, a) {
+  function copy$6(out, a) {
     out[0] = a[0];
     out[1] = a[1];
     out[2] = a[2];
@@ -1170,7 +1175,7 @@ THE SOFTWARE.
    * @returns {mat3} A new mat3
    */
 
-  function fromValues$2(m00, m01, m02, m10, m11, m12, m20, m21, m22) {
+  function fromValues$6(m00, m01, m02, m10, m11, m12, m20, m21, m22) {
     var out = new ARRAY_TYPE(9);
     out[0] = m00;
     out[1] = m01;
@@ -1199,7 +1204,7 @@ THE SOFTWARE.
    * @returns {mat3} out
    */
 
-  function set$2(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) {
+  function set$6(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) {
     out[0] = m00;
     out[1] = m01;
     out[2] = m02;
@@ -1218,7 +1223,7 @@ THE SOFTWARE.
    * @returns {mat3} out
    */
 
-  function identity$2(out) {
+  function identity$3(out) {
     out[0] = 1;
     out[1] = 0;
     out[2] = 0;
@@ -1234,7 +1239,7 @@ THE SOFTWARE.
    * Transpose the values of a mat3
    *
    * @param {mat3} out the receiving matrix
-   * @param {mat3} a the source matrix
+   * @param {ReadonlyMat3} a the source matrix
    * @returns {mat3} out
    */
 
@@ -1268,11 +1273,11 @@ THE SOFTWARE.
    * Inverts a mat3
    *
    * @param {mat3} out the receiving matrix
-   * @param {mat3} a the source matrix
+   * @param {ReadonlyMat3} a the source matrix
    * @returns {mat3} out
    */
 
-  function invert$2(out, a) {
+  function invert$3(out, a) {
     var a00 = a[0],
         a01 = a[1],
         a02 = a[2];
@@ -1308,7 +1313,7 @@ THE SOFTWARE.
    * Calculates the adjugate of a mat3
    *
    * @param {mat3} out the receiving matrix
-   * @param {mat3} a the source matrix
+   * @param {ReadonlyMat3} a the source matrix
    * @returns {mat3} out
    */
 
@@ -1336,11 +1341,11 @@ THE SOFTWARE.
   /**
    * Calculates the determinant of a mat3
    *
-   * @param {mat3} a the source matrix
+   * @param {ReadonlyMat3} a the source matrix
    * @returns {Number} determinant of a
    */
 
-  function determinant$2(a) {
+  function determinant$1(a) {
     var a00 = a[0],
         a01 = a[1],
         a02 = a[2];
@@ -1356,12 +1361,12 @@ THE SOFTWARE.
    * Multiplies two mat3's
    *
    * @param {mat3} out the receiving matrix
-   * @param {mat3} a the first operand
-   * @param {mat3} b the second operand
+   * @param {ReadonlyMat3} a the first operand
+   * @param {ReadonlyMat3} b the second operand
    * @returns {mat3} out
    */
 
-  function multiply$2(out, a, b) {
+  function multiply$6(out, a, b) {
     var a00 = a[0],
         a01 = a[1],
         a02 = a[2];
@@ -1395,12 +1400,12 @@ THE SOFTWARE.
    * Translate a mat3 by the given vector
    *
    * @param {mat3} out the receiving matrix
-   * @param {mat3} a the matrix to translate
-   * @param {vec2} v vector to translate by
+   * @param {ReadonlyMat3} a the matrix to translate
+   * @param {ReadonlyVec2} v vector to translate by
    * @returns {mat3} out
    */
 
-  function translate$1(out, a, v) {
+  function translate$2(out, a, v) {
     var a00 = a[0],
         a01 = a[1],
         a02 = a[2],
@@ -1427,7 +1432,7 @@ THE SOFTWARE.
    * Rotates a mat3 by the given angle
    *
    * @param {mat3} out the receiving matrix
-   * @param {mat3} a the matrix to rotate
+   * @param {ReadonlyMat3} a the matrix to rotate
    * @param {Number} rad the angle to rotate the matrix by
    * @returns {mat3} out
    */
@@ -1459,12 +1464,12 @@ THE SOFTWARE.
    * Scales the mat3 by the dimensions in the given vec2
    *
    * @param {mat3} out the receiving matrix
-   * @param {mat3} a the matrix to rotate
-   * @param {vec2} v the vec2 to scale the matrix by
+   * @param {ReadonlyMat3} a the matrix to rotate
+   * @param {ReadonlyVec2} v the vec2 to scale the matrix by
    * @returns {mat3} out
    **/
 
-  function scale$2(out, a, v) {
+  function scale$6(out, a, v) {
     var x = v[0],
         y = v[1];
     out[0] = x * a[0];
@@ -1486,11 +1491,11 @@ THE SOFTWARE.
    *     mat3.translate(dest, dest, vec);
    *
    * @param {mat3} out mat3 receiving operation result
-   * @param {vec2} v Translation vector
+   * @param {ReadonlyVec2} v Translation vector
    * @returns {mat3} out
    */
 
-  function fromTranslation$1(out, v) {
+  function fromTranslation$2(out, v) {
     out[0] = 1;
     out[1] = 0;
     out[2] = 0;
@@ -1536,11 +1541,11 @@ THE SOFTWARE.
    *     mat3.scale(dest, dest, vec);
    *
    * @param {mat3} out mat3 receiving operation result
-   * @param {vec2} v Scaling vector
+   * @param {ReadonlyVec2} v Scaling vector
    * @returns {mat3} out
    */
 
-  function fromScaling$2(out, v) {
+  function fromScaling$1(out, v) {
     out[0] = v[0];
     out[1] = 0;
     out[2] = 0;
@@ -1556,7 +1561,7 @@ THE SOFTWARE.
    * Copies the values from a mat2d into a mat3
    *
    * @param {mat3} out the receiving matrix
-   * @param {mat2d} a the matrix to copy
+   * @param {ReadonlyMat2d} a the matrix to copy
    * @returns {mat3} out
    **/
 
@@ -1573,15 +1578,15 @@ THE SOFTWARE.
     return out;
   }
   /**
-  * Calculates a 3x3 matrix from the given quaternion
-  *
-  * @param {mat3} out mat3 receiving operation result
-  * @param {quat} q Quaternion to create matrix from
-  *
-  * @returns {mat3} out
-  */
+   * Calculates a 3x3 matrix from the given quaternion
+   *
+   * @param {mat3} out mat3 receiving operation result
+   * @param {ReadonlyQuat} q Quaternion to create matrix from
+   *
+   * @returns {mat3} out
+   */
 
-  function fromQuat(out, q) {
+  function fromQuat$1(out, q) {
     var x = q[0],
         y = q[1],
         z = q[2],
@@ -1610,13 +1615,13 @@ THE SOFTWARE.
     return out;
   }
   /**
-  * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
-  *
-  * @param {mat3} out mat3 receiving operation result
-  * @param {mat4} a Mat4 to derive the normal matrix from
-  *
-  * @returns {mat3} out
-  */
+   * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
+   *
+   * @param {mat3} out mat3 receiving operation result
+   * @param {ReadonlyMat4} a Mat4 to derive the normal matrix from
+   *
+   * @returns {mat3} out
+   */
 
   function normalFromMat4(out, a) {
     var a00 = a[0],
@@ -1690,33 +1695,33 @@ THE SOFTWARE.
   /**
    * Returns a string representation of a mat3
    *
-   * @param {mat3} a matrix to represent as a string
+   * @param {ReadonlyMat3} a matrix to represent as a string
    * @returns {String} string representation of the matrix
    */
 
-  function str$2(a) {
-    return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + a[8] + ')';
+  function str$6(a) {
+    return "mat3(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ")";
   }
   /**
    * Returns Frobenius norm of a mat3
    *
-   * @param {mat3} a the matrix to calculate Frobenius norm of
+   * @param {ReadonlyMat3} a the matrix to calculate Frobenius norm of
    * @returns {Number} Frobenius norm
    */
 
-  function frob$2(a) {
+  function frob$1(a) {
     return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
   }
   /**
    * Adds two mat3's
    *
    * @param {mat3} out the receiving matrix
-   * @param {mat3} a the first operand
-   * @param {mat3} b the second operand
+   * @param {ReadonlyMat3} a the first operand
+   * @param {ReadonlyMat3} b the second operand
    * @returns {mat3} out
    */
 
-  function add$2(out, a, b) {
+  function add$6(out, a, b) {
     out[0] = a[0] + b[0];
     out[1] = a[1] + b[1];
     out[2] = a[2] + b[2];
@@ -1732,12 +1737,12 @@ THE SOFTWARE.
    * Subtracts matrix b from matrix a
    *
    * @param {mat3} out the receiving matrix
-   * @param {mat3} a the first operand
-   * @param {mat3} b the second operand
+   * @param {ReadonlyMat3} a the first operand
+   * @param {ReadonlyMat3} b the second operand
    * @returns {mat3} out
    */
 
-  function subtract$2(out, a, b) {
+  function subtract$4(out, a, b) {
     out[0] = a[0] - b[0];
     out[1] = a[1] - b[1];
     out[2] = a[2] - b[2];
@@ -1753,12 +1758,12 @@ THE SOFTWARE.
    * Multiply each element of the matrix by a scalar.
    *
    * @param {mat3} out the receiving matrix
-   * @param {mat3} a the matrix to scale
+   * @param {ReadonlyMat3} a the matrix to scale
    * @param {Number} b amount to scale the matrix's elements by
    * @returns {mat3} out
    */
 
-  function multiplyScalar$2(out, a, b) {
+  function multiplyScalar$1(out, a, b) {
     out[0] = a[0] * b;
     out[1] = a[1] * b;
     out[2] = a[2] * b;
@@ -1774,13 +1779,13 @@ THE SOFTWARE.
    * Adds two mat3's after multiplying each element of the second operand by a scalar value.
    *
    * @param {mat3} out the receiving vector
-   * @param {mat3} a the first operand
-   * @param {mat3} b the second operand
+   * @param {ReadonlyMat3} a the first operand
+   * @param {ReadonlyMat3} b the second operand
    * @param {Number} scale the amount to scale b's elements by before adding
    * @returns {mat3} out
    */
 
-  function multiplyScalarAndAdd$2(out, a, b, scale) {
+  function multiplyScalarAndAdd$1(out, a, b, scale) {
     out[0] = a[0] + b[0] * scale;
     out[1] = a[1] + b[1] * scale;
     out[2] = a[2] + b[2] * scale;
@@ -1795,23 +1800,23 @@ THE SOFTWARE.
   /**
    * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
    *
-   * @param {mat3} a The first matrix.
-   * @param {mat3} b The second matrix.
+   * @param {ReadonlyMat3} a The first matrix.
+   * @param {ReadonlyMat3} b The second matrix.
    * @returns {Boolean} True if the matrices are equal, false otherwise.
    */
 
-  function exactEquals$2(a, b) {
+  function exactEquals$6(a, b) {
     return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8];
   }
   /**
    * Returns whether or not the matrices have approximately the same elements in the same position.
    *
-   * @param {mat3} a The first matrix.
-   * @param {mat3} b The second matrix.
+   * @param {ReadonlyMat3} a The first matrix.
+   * @param {ReadonlyMat3} b The second matrix.
    * @returns {Boolean} True if the matrices are equal, false otherwise.
    */
 
-  function equals$3(a, b) {
+  function equals$6(a, b) {
     var a0 = a[0],
         a1 = a[1],
         a2 = a[2],
@@ -1837,47 +1842,48 @@ THE SOFTWARE.
    * @function
    */
 
-  var mul$2 = multiply$2;
+  var mul$6 = multiply$6;
   /**
    * Alias for {@link mat3.subtract}
    * @function
    */
 
-  var sub$2 = subtract$2;
+  var sub$4 = subtract$4;
 
   var mat3 = /*#__PURE__*/Object.freeze({
-    create: create$2,
-    fromMat4: fromMat4,
-    clone: clone$2,
-    copy: copy$2,
-    fromValues: fromValues$2,
-    set: set$2,
-    identity: identity$2,
+    __proto__: null,
+    create: create$6,
+    fromMat4: fromMat4$1,
+    clone: clone$6,
+    copy: copy$6,
+    fromValues: fromValues$6,
+    set: set$6,
+    identity: identity$3,
     transpose: transpose$1,
-    invert: invert$2,
+    invert: invert$3,
     adjoint: adjoint$1,
-    determinant: determinant$2,
-    multiply: multiply$2,
-    translate: translate$1,
+    determinant: determinant$1,
+    multiply: multiply$6,
+    translate: translate$2,
     rotate: rotate$2,
-    scale: scale$2,
-    fromTranslation: fromTranslation$1,
+    scale: scale$6,
+    fromTranslation: fromTranslation$2,
     fromRotation: fromRotation$2,
-    fromScaling: fromScaling$2,
+    fromScaling: fromScaling$1,
     fromMat2d: fromMat2d,
-    fromQuat: fromQuat,
+    fromQuat: fromQuat$1,
     normalFromMat4: normalFromMat4,
     projection: projection,
-    str: str$2,
-    frob: frob$2,
-    add: add$2,
-    subtract: subtract$2,
-    multiplyScalar: multiplyScalar$2,
-    multiplyScalarAndAdd: multiplyScalarAndAdd$2,
-    exactEquals: exactEquals$2,
-    equals: equals$3,
-    mul: mul$2,
-    sub: sub$2
+    str: str$6,
+    frob: frob$1,
+    add: add$6,
+    subtract: subtract$4,
+    multiplyScalar: multiplyScalar$1,
+    multiplyScalarAndAdd: multiplyScalarAndAdd$1,
+    exactEquals: exactEquals$6,
+    equals: equals$6,
+    mul: mul$6,
+    sub: sub$4
   });
 
   /**
@@ -1891,7 +1897,7 @@ THE SOFTWARE.
    * @returns {mat4} a new 4x4 matrix
    */
 
-  function create$3() {
+  function create$5() {
     var out = new ARRAY_TYPE(16);
 
     if (ARRAY_TYPE != Float32Array) {
@@ -1918,11 +1924,11 @@ THE SOFTWARE.
   /**
    * Creates a new mat4 initialized with values from an existing matrix
    *
-   * @param {mat4} a matrix to clone
+   * @param {ReadonlyMat4} a matrix to clone
    * @returns {mat4} a new 4x4 matrix
    */
 
-  function clone$3(a) {
+  function clone$5(a) {
     var out = new ARRAY_TYPE(16);
     out[0] = a[0];
     out[1] = a[1];
@@ -1946,11 +1952,11 @@ THE SOFTWARE.
    * Copy the values from one mat4 to another
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the source matrix
+   * @param {ReadonlyMat4} a the source matrix
    * @returns {mat4} out
    */
 
-  function copy$3(out, a) {
+  function copy$5(out, a) {
     out[0] = a[0];
     out[1] = a[1];
     out[2] = a[2];
@@ -1991,7 +1997,7 @@ THE SOFTWARE.
    * @returns {mat4} A new mat4
    */
 
-  function fromValues$3(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
+  function fromValues$5(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
     var out = new ARRAY_TYPE(16);
     out[0] = m00;
     out[1] = m01;
@@ -2034,7 +2040,7 @@ THE SOFTWARE.
    * @returns {mat4} out
    */
 
-  function set$3(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
+  function set$5(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
     out[0] = m00;
     out[1] = m01;
     out[2] = m02;
@@ -2060,7 +2066,7 @@ THE SOFTWARE.
    * @returns {mat4} out
    */
 
-  function identity$3(out) {
+  function identity$2(out) {
     out[0] = 1;
     out[1] = 0;
     out[2] = 0;
@@ -2083,11 +2089,11 @@ THE SOFTWARE.
    * Transpose the values of a mat4
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the source matrix
+   * @param {ReadonlyMat4} a the source matrix
    * @returns {mat4} out
    */
 
-  function transpose$2(out, a) {
+  function transpose(out, a) {
     // If we are transposing ourselves we can skip a few steps but have to cache some values
     if (out === a) {
       var a01 = a[1],
@@ -2133,11 +2139,11 @@ THE SOFTWARE.
    * Inverts a mat4
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the source matrix
+   * @param {ReadonlyMat4} a the source matrix
    * @returns {mat4} out
    */
 
-  function invert$3(out, a) {
+  function invert$2(out, a) {
     var a00 = a[0],
         a01 = a[1],
         a02 = a[2],
@@ -2196,53 +2202,11 @@ THE SOFTWARE.
    * Calculates the adjugate of a mat4
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the source matrix
+   * @param {ReadonlyMat4} a the source matrix
    * @returns {mat4} out
    */
 
-  function adjoint$2(out, a) {
-    var a00 = a[0],
-        a01 = a[1],
-        a02 = a[2],
-        a03 = a[3];
-    var a10 = a[4],
-        a11 = a[5],
-        a12 = a[6],
-        a13 = a[7];
-    var a20 = a[8],
-        a21 = a[9],
-        a22 = a[10],
-        a23 = a[11];
-    var a30 = a[12],
-        a31 = a[13],
-        a32 = a[14],
-        a33 = a[15];
-    out[0] = a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22);
-    out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
-    out[2] = a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12);
-    out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
-    out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
-    out[5] = a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22);
-    out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
-    out[7] = a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12);
-    out[8] = a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21);
-    out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
-    out[10] = a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11);
-    out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
-    out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
-    out[13] = a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21);
-    out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
-    out[15] = a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11);
-    return out;
-  }
-  /**
-   * Calculates the determinant of a mat4
-   *
-   * @param {mat4} a the source matrix
-   * @returns {Number} determinant of a
-   */
-
-  function determinant$3(a) {
+  function adjoint(out, a) {
     var a00 = a[0],
         a01 = a[1],
         a02 = a[2],
@@ -2270,20 +2234,72 @@ THE SOFTWARE.
     var b08 = a20 * a33 - a23 * a30;
     var b09 = a21 * a32 - a22 * a31;
     var b10 = a21 * a33 - a23 * a31;
-    var b11 = a22 * a33 - a23 * a32; // Calculate the determinant
+    var b11 = a22 * a33 - a23 * a32;
+    out[0] = a11 * b11 - a12 * b10 + a13 * b09;
+    out[1] = a02 * b10 - a01 * b11 - a03 * b09;
+    out[2] = a31 * b05 - a32 * b04 + a33 * b03;
+    out[3] = a22 * b04 - a21 * b05 - a23 * b03;
+    out[4] = a12 * b08 - a10 * b11 - a13 * b07;
+    out[5] = a00 * b11 - a02 * b08 + a03 * b07;
+    out[6] = a32 * b02 - a30 * b05 - a33 * b01;
+    out[7] = a20 * b05 - a22 * b02 + a23 * b01;
+    out[8] = a10 * b10 - a11 * b08 + a13 * b06;
+    out[9] = a01 * b08 - a00 * b10 - a03 * b06;
+    out[10] = a30 * b04 - a31 * b02 + a33 * b00;
+    out[11] = a21 * b02 - a20 * b04 - a23 * b00;
+    out[12] = a11 * b07 - a10 * b09 - a12 * b06;
+    out[13] = a00 * b09 - a01 * b07 + a02 * b06;
+    out[14] = a31 * b01 - a30 * b03 - a32 * b00;
+    out[15] = a20 * b03 - a21 * b01 + a22 * b00;
+    return out;
+  }
+  /**
+   * Calculates the determinant of a mat4
+   *
+   * @param {ReadonlyMat4} a the source matrix
+   * @returns {Number} determinant of a
+   */
 
-    return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
+  function determinant(a) {
+    var a00 = a[0],
+        a01 = a[1],
+        a02 = a[2],
+        a03 = a[3];
+    var a10 = a[4],
+        a11 = a[5],
+        a12 = a[6],
+        a13 = a[7];
+    var a20 = a[8],
+        a21 = a[9],
+        a22 = a[10],
+        a23 = a[11];
+    var a30 = a[12],
+        a31 = a[13],
+        a32 = a[14],
+        a33 = a[15];
+    var b0 = a00 * a11 - a01 * a10;
+    var b1 = a00 * a12 - a02 * a10;
+    var b2 = a01 * a12 - a02 * a11;
+    var b3 = a20 * a31 - a21 * a30;
+    var b4 = a20 * a32 - a22 * a30;
+    var b5 = a21 * a32 - a22 * a31;
+    var b6 = a00 * b5 - a01 * b4 + a02 * b3;
+    var b7 = a10 * b5 - a11 * b4 + a12 * b3;
+    var b8 = a20 * b2 - a21 * b1 + a22 * b0;
+    var b9 = a30 * b2 - a31 * b1 + a32 * b0; // Calculate the determinant
+
+    return a13 * b6 - a03 * b7 + a33 * b8 - a23 * b9;
   }
   /**
    * Multiplies two mat4s
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the first operand
-   * @param {mat4} b the second operand
+   * @param {ReadonlyMat4} a the first operand
+   * @param {ReadonlyMat4} b the second operand
    * @returns {mat4} out
    */
 
-  function multiply$3(out, a, b) {
+  function multiply$5(out, a, b) {
     var a00 = a[0],
         a01 = a[1],
         a02 = a[2],
@@ -2339,12 +2355,12 @@ THE SOFTWARE.
    * Translate a mat4 by the given vector
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the matrix to translate
-   * @param {vec3} v vector to translate by
+   * @param {ReadonlyMat4} a the matrix to translate
+   * @param {ReadonlyVec3} v vector to translate by
    * @returns {mat4} out
    */
 
-  function translate$2(out, a, v) {
+  function translate$1(out, a, v) {
     var x = v[0],
         y = v[1],
         z = v[2];
@@ -2394,12 +2410,12 @@ THE SOFTWARE.
    * Scales the mat4 by the dimensions in the given vec3 not using vectorization
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the matrix to scale
-   * @param {vec3} v the vec3 to scale the matrix by
+   * @param {ReadonlyMat4} a the matrix to scale
+   * @param {ReadonlyVec3} v the vec3 to scale the matrix by
    * @returns {mat4} out
    **/
 
-  function scale$3(out, a, v) {
+  function scale$5(out, a, v) {
     var x = v[0],
         y = v[1],
         z = v[2];
@@ -2425,13 +2441,13 @@ THE SOFTWARE.
    * Rotates a mat4 by the given angle around the given axis
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the matrix to rotate
+   * @param {ReadonlyMat4} a the matrix to rotate
    * @param {Number} rad the angle to rotate the matrix by
-   * @param {vec3} axis the axis to rotate around
+   * @param {ReadonlyVec3} axis the axis to rotate around
    * @returns {mat4} out
    */
 
-  function rotate$3(out, a, rad, axis) {
+  function rotate$1(out, a, rad, axis) {
     var x = axis[0],
         y = axis[1],
         z = axis[2];
@@ -2505,12 +2521,12 @@ THE SOFTWARE.
    * Rotates a matrix by the given angle around the X axis
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the matrix to rotate
+   * @param {ReadonlyMat4} a the matrix to rotate
    * @param {Number} rad the angle to rotate the matrix by
    * @returns {mat4} out
    */
 
-  function rotateX(out, a, rad) {
+  function rotateX$3(out, a, rad) {
     var s = Math.sin(rad);
     var c = Math.cos(rad);
     var a10 = a[4];
@@ -2549,12 +2565,12 @@ THE SOFTWARE.
    * Rotates a matrix by the given angle around the Y axis
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the matrix to rotate
+   * @param {ReadonlyMat4} a the matrix to rotate
    * @param {Number} rad the angle to rotate the matrix by
    * @returns {mat4} out
    */
 
-  function rotateY(out, a, rad) {
+  function rotateY$3(out, a, rad) {
     var s = Math.sin(rad);
     var c = Math.cos(rad);
     var a00 = a[0];
@@ -2593,12 +2609,12 @@ THE SOFTWARE.
    * Rotates a matrix by the given angle around the Z axis
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the matrix to rotate
+   * @param {ReadonlyMat4} a the matrix to rotate
    * @param {Number} rad the angle to rotate the matrix by
    * @returns {mat4} out
    */
 
-  function rotateZ(out, a, rad) {
+  function rotateZ$3(out, a, rad) {
     var s = Math.sin(rad);
     var c = Math.cos(rad);
     var a00 = a[0];
@@ -2641,11 +2657,11 @@ THE SOFTWARE.
    *     mat4.translate(dest, dest, vec);
    *
    * @param {mat4} out mat4 receiving operation result
-   * @param {vec3} v Translation vector
+   * @param {ReadonlyVec3} v Translation vector
    * @returns {mat4} out
    */
 
-  function fromTranslation$2(out, v) {
+  function fromTranslation$1(out, v) {
     out[0] = 1;
     out[1] = 0;
     out[2] = 0;
@@ -2672,11 +2688,11 @@ THE SOFTWARE.
    *     mat4.scale(dest, dest, vec);
    *
    * @param {mat4} out mat4 receiving operation result
-   * @param {vec3} v Scaling vector
+   * @param {ReadonlyVec3} v Scaling vector
    * @returns {mat4} out
    */
 
-  function fromScaling$3(out, v) {
+  function fromScaling(out, v) {
     out[0] = v[0];
     out[1] = 0;
     out[2] = 0;
@@ -2704,11 +2720,11 @@ THE SOFTWARE.
    *
    * @param {mat4} out mat4 receiving operation result
    * @param {Number} rad the angle to rotate the matrix by
-   * @param {vec3} axis the axis to rotate around
+   * @param {ReadonlyVec3} axis the axis to rotate around
    * @returns {mat4} out
    */
 
-  function fromRotation$3(out, rad, axis) {
+  function fromRotation$1(out, rad, axis) {
     var x = axis[0],
         y = axis[1],
         z = axis[2];
@@ -2859,11 +2875,11 @@ THE SOFTWARE.
    *
    * @param {mat4} out mat4 receiving operation result
    * @param {quat4} q Rotation quaternion
-   * @param {vec3} v Translation vector
+   * @param {ReadonlyVec3} v Translation vector
    * @returns {mat4} out
    */
 
-  function fromRotationTranslation(out, q, v) {
+  function fromRotationTranslation$1(out, q, v) {
     // Quaternion math
     var x = q[0],
         y = q[1],
@@ -2903,7 +2919,7 @@ THE SOFTWARE.
    * Creates a new mat4 from a dual quat.
    *
    * @param {mat4} out Matrix
-   * @param {quat2} a Dual Quaternion
+   * @param {ReadonlyQuat2} a Dual Quaternion
    * @returns {mat4} mat4 receiving operation result
    */
 
@@ -2929,7 +2945,7 @@ THE SOFTWARE.
       translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;
     }
 
-    fromRotationTranslation(out, a, translation);
+    fromRotationTranslation$1(out, a, translation);
     return out;
   }
   /**
@@ -2938,11 +2954,11 @@ THE SOFTWARE.
    *  the returned vector will be the same as the translation vector
    *  originally supplied.
    * @param  {vec3} out Vector to receive translation component
-   * @param  {mat4} mat Matrix to be decomposed (input)
+   * @param  {ReadonlyMat4} mat Matrix to be decomposed (input)
    * @return {vec3} out
    */
 
-  function getTranslation(out, mat) {
+  function getTranslation$1(out, mat) {
     out[0] = mat[12];
     out[1] = mat[13];
     out[2] = mat[14];
@@ -2955,7 +2971,7 @@ THE SOFTWARE.
    *  the same as the scaling vector
    *  originally supplied.
    * @param  {vec3} out Vector to receive scaling factor component
-   * @param  {mat4} mat Matrix to be decomposed (input)
+   * @param  {ReadonlyMat4} mat Matrix to be decomposed (input)
    * @return {vec3} out
    */
 
@@ -2980,7 +2996,7 @@ THE SOFTWARE.
    *  fromRotationTranslation, the returned quaternion will be the
    *  same as the quaternion originally supplied.
    * @param {quat} out Quaternion to receive the rotation component
-   * @param {mat4} mat Matrix to be decomposed (input)
+   * @param {ReadonlyMat4} mat Matrix to be decomposed (input)
    * @return {quat} out
    */
 
@@ -3030,6 +3046,75 @@ THE SOFTWARE.
 
     return out;
   }
+  /**
+   * Decomposes a transformation matrix into its rotation, translation
+   * and scale components. Returns only the rotation component
+   * @param  {quat} out_r Quaternion to receive the rotation component
+   * @param  {vec3} out_t Vector to receive the translation vector
+   * @param  {vec3} out_s Vector to receive the scaling factor
+   * @param  {ReadonlyMat4} mat Matrix to be decomposed (input)
+   * @returns {quat} out_r
+   */
+
+  function decompose(out_r, out_t, out_s, mat) {
+    out_t[0] = mat[12];
+    out_t[1] = mat[13];
+    out_t[2] = mat[14];
+    var m11 = mat[0];
+    var m12 = mat[1];
+    var m13 = mat[2];
+    var m21 = mat[4];
+    var m22 = mat[5];
+    var m23 = mat[6];
+    var m31 = mat[8];
+    var m32 = mat[9];
+    var m33 = mat[10];
+    out_s[0] = Math.hypot(m11, m12, m13);
+    out_s[1] = Math.hypot(m21, m22, m23);
+    out_s[2] = Math.hypot(m31, m32, m33);
+    var is1 = 1 / out_s[0];
+    var is2 = 1 / out_s[1];
+    var is3 = 1 / out_s[2];
+    var sm11 = m11 * is1;
+    var sm12 = m12 * is2;
+    var sm13 = m13 * is3;
+    var sm21 = m21 * is1;
+    var sm22 = m22 * is2;
+    var sm23 = m23 * is3;
+    var sm31 = m31 * is1;
+    var sm32 = m32 * is2;
+    var sm33 = m33 * is3;
+    var trace = sm11 + sm22 + sm33;
+    var S = 0;
+
+    if (trace > 0) {
+      S = Math.sqrt(trace + 1.0) * 2;
+      out_r[3] = 0.25 * S;
+      out_r[0] = (sm23 - sm32) / S;
+      out_r[1] = (sm31 - sm13) / S;
+      out_r[2] = (sm12 - sm21) / S;
+    } else if (sm11 > sm22 && sm11 > sm33) {
+      S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2;
+      out_r[3] = (sm23 - sm32) / S;
+      out_r[0] = 0.25 * S;
+      out_r[1] = (sm12 + sm21) / S;
+      out_r[2] = (sm31 + sm13) / S;
+    } else if (sm22 > sm33) {
+      S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2;
+      out_r[3] = (sm31 - sm13) / S;
+      out_r[0] = (sm12 + sm21) / S;
+      out_r[1] = 0.25 * S;
+      out_r[2] = (sm23 + sm32) / S;
+    } else {
+      S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2;
+      out_r[3] = (sm12 - sm21) / S;
+      out_r[0] = (sm31 + sm13) / S;
+      out_r[1] = (sm23 + sm32) / S;
+      out_r[2] = 0.25 * S;
+    }
+
+    return out_r;
+  }
   /**
    * Creates a matrix from a quaternion rotation, vector translation and vector scale
    * This is equivalent to (but much faster than):
@@ -3043,8 +3128,8 @@ THE SOFTWARE.
    *
    * @param {mat4} out mat4 receiving operation result
    * @param {quat4} q Rotation quaternion
-   * @param {vec3} v Translation vector
-   * @param {vec3} s Scaling vector
+   * @param {ReadonlyVec3} v Translation vector
+   * @param {ReadonlyVec3} s Scaling vector
    * @returns {mat4} out
    */
 
@@ -3102,9 +3187,9 @@ THE SOFTWARE.
    *
    * @param {mat4} out mat4 receiving operation result
    * @param {quat4} q Rotation quaternion
-   * @param {vec3} v Translation vector
-   * @param {vec3} s Scaling vector
-   * @param {vec3} o The origin vector around which to scale and rotate
+   * @param {ReadonlyVec3} v Translation vector
+   * @param {ReadonlyVec3} s Scaling vector
+   * @param {ReadonlyVec3} o The origin vector around which to scale and rotate
    * @returns {mat4} out
    */
 
@@ -3163,12 +3248,12 @@ THE SOFTWARE.
    * Calculates a 4x4 matrix from the given quaternion
    *
    * @param {mat4} out mat4 receiving operation result
-   * @param {quat} q Quaternion to create matrix from
+   * @param {ReadonlyQuat} q Quaternion to create matrix from
    *
    * @returns {mat4} out
    */
 
-  function fromQuat$1(out, q) {
+  function fromQuat(out, q) {
     var x = q[0],
         y = q[1],
         z = q[2],
@@ -3240,6 +3325,8 @@ THE SOFTWARE.
   }
   /**
    * Generates a perspective projection matrix with the given bounds.
+   * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],
+   * which matches WebGL/OpenGL's clip volume.
    * Passing null/undefined/no value for far will generate infinite projection matrix.
    *
    * @param {mat4} out mat4 frustum matrix will be written into
@@ -3250,9 +3337,8 @@ THE SOFTWARE.
    * @returns {mat4} out
    */
 
-  function perspective(out, fovy, aspect, near, far) {
-    var f = 1.0 / Math.tan(fovy / 2),
-        nf;
+  function perspectiveNO(out, fovy, aspect, near, far) {
+    var f = 1.0 / Math.tan(fovy / 2);
     out[0] = f / aspect;
     out[1] = 0;
     out[2] = 0;
@@ -3269,7 +3355,7 @@ THE SOFTWARE.
     out[15] = 0;
 
     if (far != null && far !== Infinity) {
-      nf = 1 / (near - far);
+      var nf = 1 / (near - far);
       out[10] = (far + near) * nf;
       out[14] = 2 * far * near * nf;
     } else {
@@ -3279,6 +3365,54 @@ THE SOFTWARE.
 
     return out;
   }
+  /**
+   * Alias for {@link mat4.perspectiveNO}
+   * @function
+   */
+
+  var perspective = perspectiveNO;
+  /**
+   * Generates a perspective projection matrix suitable for WebGPU with the given bounds.
+   * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],
+   * which matches WebGPU/Vulkan/DirectX/Metal's clip volume.
+   * Passing null/undefined/no value for far will generate infinite projection matrix.
+   *
+   * @param {mat4} out mat4 frustum matrix will be written into
+   * @param {number} fovy Vertical field of view in radians
+   * @param {number} aspect Aspect ratio. typically viewport width/height
+   * @param {number} near Near bound of the frustum
+   * @param {number} far Far bound of the frustum, can be null or Infinity
+   * @returns {mat4} out
+   */
+
+  function perspectiveZO(out, fovy, aspect, near, far) {
+    var f = 1.0 / Math.tan(fovy / 2);
+    out[0] = f / aspect;
+    out[1] = 0;
+    out[2] = 0;
+    out[3] = 0;
+    out[4] = 0;
+    out[5] = f;
+    out[6] = 0;
+    out[7] = 0;
+    out[8] = 0;
+    out[9] = 0;
+    out[11] = -1;
+    out[12] = 0;
+    out[13] = 0;
+    out[15] = 0;
+
+    if (far != null && far !== Infinity) {
+      var nf = 1 / (near - far);
+      out[10] = far * nf;
+      out[14] = far * near * nf;
+    } else {
+      out[10] = -1;
+      out[14] = -near;
+    }
+
+    return out;
+  }
   /**
    * Generates a perspective projection matrix with the given field of view.
    * This is primarily useful for generating projection matrices to be used
@@ -3317,7 +3451,9 @@ THE SOFTWARE.
     return out;
   }
   /**
-   * Generates a orthogonal projection matrix with the given bounds
+   * Generates a orthogonal projection matrix with the given bounds.
+   * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],
+   * which matches WebGL/OpenGL's clip volume.
    *
    * @param {mat4} out mat4 frustum matrix will be written into
    * @param {number} left Left bound of the frustum
@@ -3329,7 +3465,7 @@ THE SOFTWARE.
    * @returns {mat4} out
    */
 
-  function ortho(out, left, right, bottom, top, near, far) {
+  function orthoNO(out, left, right, bottom, top, near, far) {
     var lr = 1 / (left - right);
     var bt = 1 / (bottom - top);
     var nf = 1 / (near - far);
@@ -3351,14 +3487,57 @@ THE SOFTWARE.
     out[15] = 1;
     return out;
   }
+  /**
+   * Alias for {@link mat4.orthoNO}
+   * @function
+   */
+
+  var ortho = orthoNO;
+  /**
+   * Generates a orthogonal projection matrix with the given bounds.
+   * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],
+   * which matches WebGPU/Vulkan/DirectX/Metal's clip volume.
+   *
+   * @param {mat4} out mat4 frustum matrix will be written into
+   * @param {number} left Left bound of the frustum
+   * @param {number} right Right bound of the frustum
+   * @param {number} bottom Bottom bound of the frustum
+   * @param {number} top Top bound of the frustum
+   * @param {number} near Near bound of the frustum
+   * @param {number} far Far bound of the frustum
+   * @returns {mat4} out
+   */
+
+  function orthoZO(out, left, right, bottom, top, near, far) {
+    var lr = 1 / (left - right);
+    var bt = 1 / (bottom - top);
+    var nf = 1 / (near - far);
+    out[0] = -2 * lr;
+    out[1] = 0;
+    out[2] = 0;
+    out[3] = 0;
+    out[4] = 0;
+    out[5] = -2 * bt;
+    out[6] = 0;
+    out[7] = 0;
+    out[8] = 0;
+    out[9] = 0;
+    out[10] = nf;
+    out[11] = 0;
+    out[12] = (left + right) * lr;
+    out[13] = (top + bottom) * bt;
+    out[14] = near * nf;
+    out[15] = 1;
+    return out;
+  }
   /**
    * Generates a look-at matrix with the given eye position, focal point, and up axis.
    * If you want a matrix that actually makes an object look at another object, you should use targetTo instead.
    *
    * @param {mat4} out mat4 frustum matrix will be written into
-   * @param {vec3} eye Position of the viewer
-   * @param {vec3} center Point the viewer is looking at
-   * @param {vec3} up vec3 pointing up
+   * @param {ReadonlyVec3} eye Position of the viewer
+   * @param {ReadonlyVec3} center Point the viewer is looking at
+   * @param {ReadonlyVec3} up vec3 pointing up
    * @returns {mat4} out
    */
 
@@ -3375,7 +3554,7 @@ THE SOFTWARE.
     var centerz = center[2];
 
     if (Math.abs(eyex - centerx) < EPSILON && Math.abs(eyey - centery) < EPSILON && Math.abs(eyez - centerz) < EPSILON) {
-      return identity$3(out);
+      return identity$2(out);
     }
 
     z0 = eyex - centerx;
@@ -3439,9 +3618,9 @@ THE SOFTWARE.
    * Generates a matrix that makes something look at something else.
    *
    * @param {mat4} out mat4 frustum matrix will be written into
-   * @param {vec3} eye Position of the viewer
-   * @param {vec3} center Point the viewer is looking at
-   * @param {vec3} up vec3 pointing up
+   * @param {ReadonlyVec3} eye Position of the viewer
+   * @param {ReadonlyVec3} center Point the viewer is looking at
+   * @param {ReadonlyVec3} up vec3 pointing up
    * @returns {mat4} out
    */
 
@@ -3497,33 +3676,33 @@ THE SOFTWARE.
   /**
    * Returns a string representation of a mat4
    *
-   * @param {mat4} a matrix to represent as a string
+   * @param {ReadonlyMat4} a matrix to represent as a string
    * @returns {String} string representation of the matrix
    */
 
-  function str$3(a) {
-    return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' + a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')';
+  function str$5(a) {
+    return "mat4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + ")";
   }
   /**
    * Returns Frobenius norm of a mat4
    *
-   * @param {mat4} a the matrix to calculate Frobenius norm of
+   * @param {ReadonlyMat4} a the matrix to calculate Frobenius norm of
    * @returns {Number} Frobenius norm
    */
 
-  function frob$3(a) {
-    return Math.hypot(a[0], a[1], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
+  function frob(a) {
+    return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
   }
   /**
    * Adds two mat4's
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the first operand
-   * @param {mat4} b the second operand
+   * @param {ReadonlyMat4} a the first operand
+   * @param {ReadonlyMat4} b the second operand
    * @returns {mat4} out
    */
 
-  function add$3(out, a, b) {
+  function add$5(out, a, b) {
     out[0] = a[0] + b[0];
     out[1] = a[1] + b[1];
     out[2] = a[2] + b[2];
@@ -3546,8 +3725,8 @@ THE SOFTWARE.
    * Subtracts matrix b from matrix a
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the first operand
-   * @param {mat4} b the second operand
+   * @param {ReadonlyMat4} a the first operand
+   * @param {ReadonlyMat4} b the second operand
    * @returns {mat4} out
    */
 
@@ -3574,12 +3753,12 @@ THE SOFTWARE.
    * Multiply each element of the matrix by a scalar.
    *
    * @param {mat4} out the receiving matrix
-   * @param {mat4} a the matrix to scale
+   * @param {ReadonlyMat4} a the matrix to scale
    * @param {Number} b amount to scale the matrix's elements by
    * @returns {mat4} out
    */
 
-  function multiplyScalar$3(out, a, b) {
+  function multiplyScalar(out, a, b) {
     out[0] = a[0] * b;
     out[1] = a[1] * b;
     out[2] = a[2] * b;
@@ -3602,13 +3781,13 @@ THE SOFTWARE.
    * Adds two mat4's after multiplying each element of the second operand by a scalar value.
    *
    * @param {mat4} out the receiving vector
-   * @param {mat4} a the first operand
-   * @param {mat4} b the second operand
+   * @param {ReadonlyMat4} a the first operand
+   * @param {ReadonlyMat4} b the second operand
    * @param {Number} scale the amount to scale b's elements by before adding
    * @returns {mat4} out
    */
 
-  function multiplyScalarAndAdd$3(out, a, b, scale) {
+  function multiplyScalarAndAdd(out, a, b, scale) {
     out[0] = a[0] + b[0] * scale;
     out[1] = a[1] + b[1] * scale;
     out[2] = a[2] + b[2] * scale;
@@ -3630,23 +3809,23 @@ THE SOFTWARE.
   /**
    * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
    *
-   * @param {mat4} a The first matrix.
-   * @param {mat4} b The second matrix.
+   * @param {ReadonlyMat4} a The first matrix.
+   * @param {ReadonlyMat4} b The second matrix.
    * @returns {Boolean} True if the matrices are equal, false otherwise.
    */
 
-  function exactEquals$3(a, b) {
+  function exactEquals$5(a, b) {
     return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15];
   }
   /**
    * Returns whether or not the matrices have approximately the same elements in the same position.
    *
-   * @param {mat4} a The first matrix.
-   * @param {mat4} b The second matrix.
+   * @param {ReadonlyMat4} a The first matrix.
+   * @param {ReadonlyMat4} b The second matrix.
    * @returns {Boolean} True if the matrices are equal, false otherwise.
    */
 
-  function equals$4(a, b) {
+  function equals$5(a, b) {
     var a0 = a[0],
         a1 = a[1],
         a2 = a[2],
@@ -3686,7 +3865,7 @@ THE SOFTWARE.
    * @function
    */
 
-  var mul$3 = multiply$3;
+  var mul$5 = multiply$5;
   /**
    * Alias for {@link mat4.subtract}
    * @function
@@ -3695,52 +3874,58 @@ THE SOFTWARE.
   var sub$3 = subtract$3;
 
   var mat4 = /*#__PURE__*/Object.freeze({
-    create: create$3,
-    clone: clone$3,
-    copy: copy$3,
-    fromValues: fromValues$3,
-    set: set$3,
-    identity: identity$3,
-    transpose: transpose$2,
-    invert: invert$3,
-    adjoint: adjoint$2,
-    determinant: determinant$3,
-    multiply: multiply$3,
-    translate: translate$2,
-    scale: scale$3,
-    rotate: rotate$3,
-    rotateX: rotateX,
-    rotateY: rotateY,
-    rotateZ: rotateZ,
-    fromTranslation: fromTranslation$2,
-    fromScaling: fromScaling$3,
-    fromRotation: fromRotation$3,
+    __proto__: null,
+    create: create$5,
+    clone: clone$5,
+    copy: copy$5,
+    fromValues: fromValues$5,
+    set: set$5,
+    identity: identity$2,
+    transpose: transpose,
+    invert: invert$2,
+    adjoint: adjoint,
+    determinant: determinant,
+    multiply: multiply$5,
+    translate: translate$1,
+    scale: scale$5,
+    rotate: rotate$1,
+    rotateX: rotateX$3,
+    rotateY: rotateY$3,
+    rotateZ: rotateZ$3,
+    fromTranslation: fromTranslation$1,
+    fromScaling: fromScaling,
+    fromRotation: fromRotation$1,
     fromXRotation: fromXRotation,
     fromYRotation: fromYRotation,
     fromZRotation: fromZRotation,
-    fromRotationTranslation: fromRotationTranslation,
+    fromRotationTranslation: fromRotationTranslation$1,
     fromQuat2: fromQuat2,
-    getTranslation: getTranslation,
+    getTranslation: getTranslation$1,
     getScaling: getScaling,
     getRotation: getRotation,
+    decompose: decompose,
     fromRotationTranslationScale: fromRotationTranslationScale,
     fromRotationTranslationScaleOrigin: fromRotationTranslationScaleOrigin,
-    fromQuat: fromQuat$1,
+    fromQuat: fromQuat,
     frustum: frustum,
+    perspectiveNO: perspectiveNO,
     perspective: perspective,
+    perspectiveZO: perspectiveZO,
     perspectiveFromFieldOfView: perspectiveFromFieldOfView,
+    orthoNO: orthoNO,
     ortho: ortho,
+    orthoZO: orthoZO,
     lookAt: lookAt,
     targetTo: targetTo,
-    str: str$3,
-    frob: frob$3,
-    add: add$3,
+    str: str$5,
+    frob: frob,
+    add: add$5,
     subtract: subtract$3,
-    multiplyScalar: multiplyScalar$3,
-    multiplyScalarAndAdd: multiplyScalarAndAdd$3,
-    exactEquals: exactEquals$3,
-    equals: equals$4,
-    mul: mul$3,
+    multiplyScalar: multiplyScalar,
+    multiplyScalarAndAdd: multiplyScalarAndAdd,
+    exactEquals: exactEquals$5,
+    equals: equals$5,
+    mul: mul$5,
     sub: sub$3
   });
 
@@ -3769,7 +3954,7 @@ THE SOFTWARE.
   /**
    * Creates a new vec3 initialized with values from an existing vector
    *
-   * @param {vec3} a vector to clone
+   * @param {ReadonlyVec3} a vector to clone
    * @returns {vec3} a new 3D vector
    */
 
@@ -3783,11 +3968,11 @@ THE SOFTWARE.
   /**
    * Calculates the length of a vec3
    *
-   * @param {vec3} a vector to calculate length of
+   * @param {ReadonlyVec3} a vector to calculate length of
    * @returns {Number} length of a
    */
 
-  function length(a) {
+  function length$4(a) {
     var x = a[0];
     var y = a[1];
     var z = a[2];
@@ -3813,7 +3998,7 @@ THE SOFTWARE.
    * Copy the values from one vec3 to another
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the source vector
+   * @param {ReadonlyVec3} a the source vector
    * @returns {vec3} out
    */
 
@@ -3843,8 +4028,8 @@ THE SOFTWARE.
    * Adds two vec3's
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
    * @returns {vec3} out
    */
 
@@ -3858,12 +4043,12 @@ THE SOFTWARE.
    * Subtracts vector b from vector a
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
    * @returns {vec3} out
    */
 
-  function subtract$4(out, a, b) {
+  function subtract$2(out, a, b) {
     out[0] = a[0] - b[0];
     out[1] = a[1] - b[1];
     out[2] = a[2] - b[2];
@@ -3873,8 +4058,8 @@ THE SOFTWARE.
    * Multiplies two vec3's
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
    * @returns {vec3} out
    */
 
@@ -3888,12 +4073,12 @@ THE SOFTWARE.
    * Divides two vec3's
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
    * @returns {vec3} out
    */
 
-  function divide(out, a, b) {
+  function divide$2(out, a, b) {
     out[0] = a[0] / b[0];
     out[1] = a[1] / b[1];
     out[2] = a[2] / b[2];
@@ -3903,11 +4088,11 @@ THE SOFTWARE.
    * Math.ceil the components of a vec3
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a vector to ceil
+   * @param {ReadonlyVec3} a vector to ceil
    * @returns {vec3} out
    */
 
-  function ceil(out, a) {
+  function ceil$2(out, a) {
     out[0] = Math.ceil(a[0]);
     out[1] = Math.ceil(a[1]);
     out[2] = Math.ceil(a[2]);
@@ -3917,11 +4102,11 @@ THE SOFTWARE.
    * Math.floor the components of a vec3
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a vector to floor
+   * @param {ReadonlyVec3} a vector to floor
    * @returns {vec3} out
    */
 
-  function floor(out, a) {
+  function floor$2(out, a) {
     out[0] = Math.floor(a[0]);
     out[1] = Math.floor(a[1]);
     out[2] = Math.floor(a[2]);
@@ -3931,12 +4116,12 @@ THE SOFTWARE.
    * Returns the minimum of two vec3's
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
    * @returns {vec3} out
    */
 
-  function min(out, a, b) {
+  function min$2(out, a, b) {
     out[0] = Math.min(a[0], b[0]);
     out[1] = Math.min(a[1], b[1]);
     out[2] = Math.min(a[2], b[2]);
@@ -3946,12 +4131,12 @@ THE SOFTWARE.
    * Returns the maximum of two vec3's
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
    * @returns {vec3} out
    */
 
-  function max(out, a, b) {
+  function max$2(out, a, b) {
     out[0] = Math.max(a[0], b[0]);
     out[1] = Math.max(a[1], b[1]);
     out[2] = Math.max(a[2], b[2]);
@@ -3961,11 +4146,11 @@ THE SOFTWARE.
    * Math.round the components of a vec3
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a vector to round
+   * @param {ReadonlyVec3} a vector to round
    * @returns {vec3} out
    */
 
-  function round(out, a) {
+  function round$2(out, a) {
     out[0] = Math.round(a[0]);
     out[1] = Math.round(a[1]);
     out[2] = Math.round(a[2]);
@@ -3975,7 +4160,7 @@ THE SOFTWARE.
    * Scales a vec3 by a scalar number
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the vector to scale
+   * @param {ReadonlyVec3} a the vector to scale
    * @param {Number} b amount to scale the vector by
    * @returns {vec3} out
    */
@@ -3990,13 +4175,13 @@ THE SOFTWARE.
    * Adds two vec3's after scaling the second operand by a scalar value
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
    * @param {Number} scale the amount to scale b by before adding
    * @returns {vec3} out
    */
 
-  function scaleAndAdd(out, a, b, scale) {
+  function scaleAndAdd$2(out, a, b, scale) {
     out[0] = a[0] + b[0] * scale;
     out[1] = a[1] + b[1] * scale;
     out[2] = a[2] + b[2] * scale;
@@ -4005,12 +4190,12 @@ THE SOFTWARE.
   /**
    * Calculates the euclidian distance between two vec3's
    *
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
    * @returns {Number} distance between a and b
    */
 
-  function distance(a, b) {
+  function distance$2(a, b) {
     var x = b[0] - a[0];
     var y = b[1] - a[1];
     var z = b[2] - a[2];
@@ -4019,12 +4204,12 @@ THE SOFTWARE.
   /**
    * Calculates the squared euclidian distance between two vec3's
    *
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
    * @returns {Number} squared distance between a and b
    */
 
-  function squaredDistance(a, b) {
+  function squaredDistance$2(a, b) {
     var x = b[0] - a[0];
     var y = b[1] - a[1];
     var z = b[2] - a[2];
@@ -4033,11 +4218,11 @@ THE SOFTWARE.
   /**
    * Calculates the squared length of a vec3
    *
-   * @param {vec3} a vector to calculate squared length of
+   * @param {ReadonlyVec3} a vector to calculate squared length of
    * @returns {Number} squared length of a
    */
 
-  function squaredLength(a) {
+  function squaredLength$4(a) {
     var x = a[0];
     var y = a[1];
     var z = a[2];
@@ -4047,11 +4232,11 @@ THE SOFTWARE.
    * Negates the components of a vec3
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a vector to negate
+   * @param {ReadonlyVec3} a vector to negate
    * @returns {vec3} out
    */
 
-  function negate(out, a) {
+  function negate$2(out, a) {
     out[0] = -a[0];
     out[1] = -a[1];
     out[2] = -a[2];
@@ -4061,11 +4246,11 @@ THE SOFTWARE.
    * Returns the inverse of the components of a vec3
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a vector to invert
+   * @param {ReadonlyVec3} a vector to invert
    * @returns {vec3} out
    */
 
-  function inverse(out, a) {
+  function inverse$2(out, a) {
     out[0] = 1.0 / a[0];
     out[1] = 1.0 / a[1];
     out[2] = 1.0 / a[2];
@@ -4075,11 +4260,11 @@ THE SOFTWARE.
    * Normalize a vec3
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a vector to normalize
+   * @param {ReadonlyVec3} a vector to normalize
    * @returns {vec3} out
    */
 
-  function normalize(out, a) {
+  function normalize$4(out, a) {
     var x = a[0];
     var y = a[1];
     var z = a[2];
@@ -4098,24 +4283,24 @@ THE SOFTWARE.
   /**
    * Calculates the dot product of two vec3's
    *
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
    * @returns {Number} dot product of a and b
    */
 
-  function dot(a, b) {
+  function dot$4(a, b) {
     return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
   }
   /**
    * Computes the cross product of two vec3's
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
    * @returns {vec3} out
    */
 
-  function cross(out, a, b) {
+  function cross$2(out, a, b) {
     var ax = a[0],
         ay = a[1],
         az = a[2];
@@ -4131,13 +4316,13 @@ THE SOFTWARE.
    * Performs a linear interpolation between two vec3's
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
    * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
    * @returns {vec3} out
    */
 
-  function lerp(out, a, b, t) {
+  function lerp$4(out, a, b, t) {
     var ax = a[0];
     var ay = a[1];
     var az = a[2];
@@ -4146,14 +4331,34 @@ THE SOFTWARE.
     out[2] = az + t * (b[2] - az);
     return out;
   }
+  /**
+   * Performs a spherical linear interpolation between two vec3's
+   *
+   * @param {vec3} out the receiving vector
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
+   * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
+   * @returns {vec3} out
+   */
+
+  function slerp$1(out, a, b, t) {
+    var angle = Math.acos(Math.min(Math.max(dot$4(a, b), -1), 1));
+    var sinTotal = Math.sin(angle);
+    var ratioA = Math.sin((1 - t) * angle) / sinTotal;
+    var ratioB = Math.sin(t * angle) / sinTotal;
+    out[0] = ratioA * a[0] + ratioB * b[0];
+    out[1] = ratioA * a[1] + ratioB * b[1];
+    out[2] = ratioA * a[2] + ratioB * b[2];
+    return out;
+  }
   /**
    * Performs a hermite interpolation with two control points
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
-   * @param {vec3} c the third operand
-   * @param {vec3} d the fourth operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
+   * @param {ReadonlyVec3} c the third operand
+   * @param {ReadonlyVec3} d the fourth operand
    * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
    * @returns {vec3} out
    */
@@ -4173,10 +4378,10 @@ THE SOFTWARE.
    * Performs a bezier interpolation with two control points
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the first operand
-   * @param {vec3} b the second operand
-   * @param {vec3} c the third operand
-   * @param {vec3} d the fourth operand
+   * @param {ReadonlyVec3} a the first operand
+   * @param {ReadonlyVec3} b the second operand
+   * @param {ReadonlyVec3} c the third operand
+   * @param {ReadonlyVec3} d the fourth operand
    * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
    * @returns {vec3} out
    */
@@ -4198,12 +4403,12 @@ THE SOFTWARE.
    * Generates a random vector with the given scale
    *
    * @param {vec3} out the receiving vector
-   * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
+   * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned
    * @returns {vec3} out
    */
 
-  function random(out, scale) {
-    scale = scale || 1.0;
+  function random$3(out, scale) {
+    scale = scale === undefined ? 1.0 : scale;
     var r = RANDOM() * 2.0 * Math.PI;
     var z = RANDOM() * 2.0 - 1.0;
     var zScale = Math.sqrt(1.0 - z * z) * scale;
@@ -4217,12 +4422,12 @@ THE SOFTWARE.
    * 4th vector component is implicitly '1'
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the vector to transform
-   * @param {mat4} m matrix to transform with
+   * @param {ReadonlyVec3} a the vector to transform
+   * @param {ReadonlyMat4} m matrix to transform with
    * @returns {vec3} out
    */
 
-  function transformMat4(out, a, m) {
+  function transformMat4$2(out, a, m) {
     var x = a[0],
         y = a[1],
         z = a[2];
@@ -4237,12 +4442,12 @@ THE SOFTWARE.
    * Transforms the vec3 with a mat3.
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the vector to transform
-   * @param {mat3} m the 3x3 matrix to transform with
+   * @param {ReadonlyVec3} a the vector to transform
+   * @param {ReadonlyMat3} m the 3x3 matrix to transform with
    * @returns {vec3} out
    */
 
-  function transformMat3(out, a, m) {
+  function transformMat3$1(out, a, m) {
     var x = a[0],
         y = a[1],
         z = a[2];
@@ -4256,12 +4461,12 @@ THE SOFTWARE.
    * Can also be used for dual quaternions. (Multiply it with the real part)
    *
    * @param {vec3} out the receiving vector
-   * @param {vec3} a the vector to transform
-   * @param {quat} q quaternion to transform with
+   * @param {ReadonlyVec3} a the vector to transform
+   * @param {ReadonlyQuat} q quaternion to transform with
    * @returns {vec3} out
    */
 
-  function transformQuat(out, a, q) {
+  function transformQuat$1(out, a, q) {
     // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed
     var qx = q[0],
         qy = q[1],
@@ -4297,13 +4502,13 @@ THE SOFTWARE.
   /**
    * Rotate a 3D vector around the x-axis
    * @param {vec3} out The receiving vec3
-   * @param {vec3} a The vec3 point to rotate
-   * @param {vec3} b The origin of the rotation
-   * @param {Number} c The angle of rotation
+   * @param {ReadonlyVec3} a The vec3 point to rotate
+   * @param {ReadonlyVec3} b The origin of the rotation
+   * @param {Number} rad The angle of rotation in radians
    * @returns {vec3} out
    */
 
-  function rotateX$1(out, a, b, c) {
+  function rotateX$2(out, a, b, rad) {
     var p = [],
         r = []; //Translate point to the origin
 
@@ -4312,8 +4517,8 @@ THE SOFTWARE.
     p[2] = a[2] - b[2]; //perform rotation
 
     r[0] = p[0];
-    r[1] = p[1] * Math.cos(c) - p[2] * Math.sin(c);
-    r[2] = p[1] * Math.sin(c) + p[2] * Math.cos(c); //translate to correct position
+    r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad);
+    r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad); //translate to correct position
 
     out[0] = r[0] + b[0];
     out[1] = r[1] + b[1];
@@ -4323,13 +4528,13 @@ THE SOFTWARE.
   /**
    * Rotate a 3D vector around the y-axis
    * @param {vec3} out The receiving vec3
-   * @param {vec3} a The vec3 point to rotate
-   * @param {vec3} b The origin of the rotation
-   * @param {Number} c The angle of rotation
+   * @param {ReadonlyVec3} a The vec3 point to rotate
+   * @param {ReadonlyVec3} b The origin of the rotation
+   * @param {Number} rad The angle of rotation in radians
    * @returns {vec3} out
    */
 
-  function rotateY$1(out, a, b, c) {
+  function rotateY$2(out, a, b, rad) {
     var p = [],
         r = []; //Translate point to the origin
 
@@ -4337,9 +4542,9 @@ THE SOFTWARE.
     p[1] = a[1] - b[1];
     p[2] = a[2] - b[2]; //perform rotation
 
-    r[0] = p[2] * Math.sin(c) + p[0] * Math.cos(c);
+    r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad);
     r[1] = p[1];
-    r[2] = p[2] * Math.cos(c) - p[0] * Math.sin(c); //translate to correct position
+    r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad); //translate to correct position
 
     out[0] = r[0] + b[0];
     out[1] = r[1] + b[1];
@@ -4349,13 +4554,13 @@ THE SOFTWARE.
   /**
    * Rotate a 3D vector around the z-axis
    * @param {vec3} out The receiving vec3
-   * @param {vec3} a The vec3 point to rotate
-   * @param {vec3} b The origin of the rotation
-   * @param {Number} c The angle of rotation
+   * @param {ReadonlyVec3} a The vec3 point to rotate
+   * @param {ReadonlyVec3} b The origin of the rotation
+   * @param {Number} rad The angle of rotation in radians
    * @returns {vec3} out
    */
 
-  function rotateZ$1(out, a, b, c) {
+  function rotateZ$2(out, a, b, rad) {
     var p = [],
         r = []; //Translate point to the origin
 
@@ -4363,8 +4568,8 @@ THE SOFTWARE.
     p[1] = a[1] - b[1];
     p[2] = a[2] - b[2]; //perform rotation
 
-    r[0] = p[0] * Math.cos(c) - p[1] * Math.sin(c);
-    r[1] = p[0] * Math.sin(c) + p[1] * Math.cos(c);
+    r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad);
+    r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad);
     r[2] = p[2]; //translate to correct position
 
     out[0] = r[0] + b[0];
@@ -4374,25 +4579,21 @@ THE SOFTWARE.
   }
   /**
    * Get the angle between two 3D vectors
-   * @param {vec3} a The first operand
-   * @param {vec3} b The second operand
+   * @param {ReadonlyVec3} a The first operand
+   * @param {ReadonlyVec3} b The second operand
    * @returns {Number} The angle in radians
    */
 
-  function angle(a, b) {
-    var tempA = fromValues$4(a[0], a[1], a[2]);
-    var tempB = fromValues$4(b[0], b[1], b[2]);
-    normalize(tempA, tempA);
-    normalize(tempB, tempB);
-    var cosine = dot(tempA, tempB);
-
-    if (cosine > 1.0) {
-      return 0;
-    } else if (cosine < -1.0) {
-      return Math.PI;
-    } else {
-      return Math.acos(cosine);
-    }
+  function angle$1(a, b) {
+    var ax = a[0],
+        ay = a[1],
+        az = a[2],
+        bx = b[0],
+        by = b[1],
+        bz = b[2],
+        mag = Math.sqrt((ax * ax + ay * ay + az * az) * (bx * bx + by * by + bz * bz)),
+        cosine = mag && dot$4(a, b) / mag;
+    return Math.acos(Math.min(Math.max(cosine, -1), 1));
   }
   /**
    * Set the components of a vec3 to zero
@@ -4401,7 +4602,7 @@ THE SOFTWARE.
    * @returns {vec3} out
    */
 
-  function zero(out) {
+  function zero$2(out) {
     out[0] = 0.0;
     out[1] = 0.0;
     out[2] = 0.0;
@@ -4410,18 +4611,18 @@ THE SOFTWARE.
   /**
    * Returns a string representation of a vector
    *
-   * @param {vec3} a vector to represent as a string
+   * @param {ReadonlyVec3} a vector to represent as a string
    * @returns {String} string representation of the vector
    */
 
   function str$4(a) {
-    return 'vec3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ')';
+    return "vec3(" + a[0] + ", " + a[1] + ", " + a[2] + ")";
   }
   /**
    * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)
    *
-   * @param {vec3} a The first vector.
-   * @param {vec3} b The second vector.
+   * @param {ReadonlyVec3} a The first vector.
+   * @param {ReadonlyVec3} b The second vector.
    * @returns {Boolean} True if the vectors are equal, false otherwise.
    */
 
@@ -4431,12 +4632,12 @@ THE SOFTWARE.
   /**
    * Returns whether or not the vectors have approximately the same elements in the same position.
    *
-   * @param {vec3} a The first vector.
-   * @param {vec3} b The second vector.
+   * @param {ReadonlyVec3} a The first vector.
+   * @param {ReadonlyVec3} b The second vector.
    * @returns {Boolean} True if the vectors are equal, false otherwise.
    */
 
-  function equals$5(a, b) {
+  function equals$4(a, b) {
     var a0 = a[0],
         a1 = a[1],
         a2 = a[2];
@@ -4450,7 +4651,7 @@ THE SOFTWARE.
    * @function
    */
 
-  var sub$4 = subtract$4;
+  var sub$2 = subtract$2;
   /**
    * Alias for {@link vec3.multiply}
    * @function
@@ -4462,31 +4663,31 @@ THE SOFTWARE.
    * @function
    */
 
-  var div = divide;
+  var div$2 = divide$2;
   /**
    * Alias for {@link vec3.distance}
    * @function
    */
 
-  var dist = distance;
+  var dist$2 = distance$2;
   /**
    * Alias for {@link vec3.squaredDistance}
    * @function
    */
 
-  var sqrDist = squaredDistance;
+  var sqrDist$2 = squaredDistance$2;
   /**
    * Alias for {@link vec3.length}
    * @function
    */
 
-  var len = length;
+  var len$4 = length$4;
   /**
    * Alias for {@link vec3.squaredLength}
    * @function
    */
 
-  var sqrLen = squaredLength;
+  var sqrLen$4 = squaredLength$4;
   /**
    * Perform some operation over an array of vec3s.
    *
@@ -4500,7 +4701,7 @@ THE SOFTWARE.
    * @function
    */
 
-  var forEach = function () {
+  var forEach$2 = function () {
     var vec = create$4();
     return function (a, stride, offset, count, fn, arg) {
       var i, l;
@@ -4534,54 +4735,56 @@ THE SOFTWARE.
   }();
 
   var vec3 = /*#__PURE__*/Object.freeze({
+    __proto__: null,
     create: create$4,
     clone: clone$4,
-    length: length,
+    length: length$4,
     fromValues: fromValues$4,
     copy: copy$4,
     set: set$4,
     add: add$4,
-    subtract: subtract$4,
+    subtract: subtract$2,
     multiply: multiply$4,
-    divide: divide,
-    ceil: ceil,
-    floor: floor,
-    min: min,
-    max: max,
-    round: round,
+    divide: divide$2,
+    ceil: ceil$2,
+    floor: floor$2,
+    min: min$2,
+    max: max$2,
+    round: round$2,
     scale: scale$4,
-    scaleAndAdd: scaleAndAdd,
-    distance: distance,
-    squaredDistance: squaredDistance,
-    squaredLength: squaredLength,
-    negate: negate,
-    inverse: inverse,
-    normalize: normalize,
-    dot: dot,
-    cross: cross,
-    lerp: lerp,
+    scaleAndAdd: scaleAndAdd$2,
+    distance: distance$2,
+    squaredDistance: squaredDistance$2,
+    squaredLength: squaredLength$4,
+    negate: negate$2,
+    inverse: inverse$2,
+    normalize: normalize$4,
+    dot: dot$4,
+    cross: cross$2,
+    lerp: lerp$4,
+    slerp: slerp$1,
     hermite: hermite,
     bezier: bezier,
-    random: random,
-    transformMat4: transformMat4,
-    transformMat3: transformMat3,
-    transformQuat: transformQuat,
-    rotateX: rotateX$1,
-    rotateY: rotateY$1,
-    rotateZ: rotateZ$1,
-    angle: angle,
-    zero: zero,
+    random: random$3,
+    transformMat4: transformMat4$2,
+    transformMat3: transformMat3$1,
+    transformQuat: transformQuat$1,
+    rotateX: rotateX$2,
+    rotateY: rotateY$2,
+    rotateZ: rotateZ$2,
+    angle: angle$1,
+    zero: zero$2,
     str: str$4,
     exactEquals: exactEquals$4,
-    equals: equals$5,
-    sub: sub$4,
+    equals: equals$4,
+    sub: sub$2,
     mul: mul$4,
-    div: div,
-    dist: dist,
-    sqrDist: sqrDist,
-    len: len,
-    sqrLen: sqrLen,
-    forEach: forEach
+    div: div$2,
+    dist: dist$2,
+    sqrDist: sqrDist$2,
+    len: len$4,
+    sqrLen: sqrLen$4,
+    forEach: forEach$2
   });
 
   /**
@@ -4595,7 +4798,7 @@ THE SOFTWARE.
    * @returns {vec4} a new 4D vector
    */
 
-  function create$5() {
+  function create$3() {
     var out = new ARRAY_TYPE(4);
 
     if (ARRAY_TYPE != Float32Array) {
@@ -4610,11 +4813,11 @@ THE SOFTWARE.
   /**
    * Creates a new vec4 initialized with values from an existing vector
    *
-   * @param {vec4} a vector to clone
+   * @param {ReadonlyVec4} a vector to clone
    * @returns {vec4} a new 4D vector
    */
 
-  function clone$5(a) {
+  function clone$3(a) {
     var out = new ARRAY_TYPE(4);
     out[0] = a[0];
     out[1] = a[1];
@@ -4632,7 +4835,7 @@ THE SOFTWARE.
    * @returns {vec4} a new 4D vector
    */
 
-  function fromValues$5(x, y, z, w) {
+  function fromValues$3(x, y, z, w) {
     var out = new ARRAY_TYPE(4);
     out[0] = x;
     out[1] = y;
@@ -4644,11 +4847,11 @@ THE SOFTWARE.
    * Copy the values from one vec4 to another
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a the source vector
+   * @param {ReadonlyVec4} a the source vector
    * @returns {vec4} out
    */
 
-  function copy$5(out, a) {
+  function copy$3(out, a) {
     out[0] = a[0];
     out[1] = a[1];
     out[2] = a[2];
@@ -4666,7 +4869,7 @@ THE SOFTWARE.
    * @returns {vec4} out
    */
 
-  function set$5(out, x, y, z, w) {
+  function set$3(out, x, y, z, w) {
     out[0] = x;
     out[1] = y;
     out[2] = z;
@@ -4677,12 +4880,12 @@ THE SOFTWARE.
    * Adds two vec4's
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a the first operand
-   * @param {vec4} b the second operand
+   * @param {ReadonlyVec4} a the first operand
+   * @param {ReadonlyVec4} b the second operand
    * @returns {vec4} out
    */
 
-  function add$5(out, a, b) {
+  function add$3(out, a, b) {
     out[0] = a[0] + b[0];
     out[1] = a[1] + b[1];
     out[2] = a[2] + b[2];
@@ -4693,12 +4896,12 @@ THE SOFTWARE.
    * Subtracts vector b from vector a
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a the first operand
-   * @param {vec4} b the second operand
+   * @param {ReadonlyVec4} a the first operand
+   * @param {ReadonlyVec4} b the second operand
    * @returns {vec4} out
    */
 
-  function subtract$5(out, a, b) {
+  function subtract$1(out, a, b) {
     out[0] = a[0] - b[0];
     out[1] = a[1] - b[1];
     out[2] = a[2] - b[2];
@@ -4709,12 +4912,12 @@ THE SOFTWARE.
    * Multiplies two vec4's
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a the first operand
-   * @param {vec4} b the second operand
+   * @param {ReadonlyVec4} a the first operand
+   * @param {ReadonlyVec4} b the second operand
    * @returns {vec4} out
    */
 
-  function multiply$5(out, a, b) {
+  function multiply$3(out, a, b) {
     out[0] = a[0] * b[0];
     out[1] = a[1] * b[1];
     out[2] = a[2] * b[2];
@@ -4725,8 +4928,8 @@ THE SOFTWARE.
    * Divides two vec4's
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a the first operand
-   * @param {vec4} b the second operand
+   * @param {ReadonlyVec4} a the first operand
+   * @param {ReadonlyVec4} b the second operand
    * @returns {vec4} out
    */
 
@@ -4741,7 +4944,7 @@ THE SOFTWARE.
    * Math.ceil the components of a vec4
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a vector to ceil
+   * @param {ReadonlyVec4} a vector to ceil
    * @returns {vec4} out
    */
 
@@ -4756,7 +4959,7 @@ THE SOFTWARE.
    * Math.floor the components of a vec4
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a vector to floor
+   * @param {ReadonlyVec4} a vector to floor
    * @returns {vec4} out
    */
 
@@ -4771,8 +4974,8 @@ THE SOFTWARE.
    * Returns the minimum of two vec4's
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a the first operand
-   * @param {vec4} b the second operand
+   * @param {ReadonlyVec4} a the first operand
+   * @param {ReadonlyVec4} b the second operand
    * @returns {vec4} out
    */
 
@@ -4787,8 +4990,8 @@ THE SOFTWARE.
    * Returns the maximum of two vec4's
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a the first operand
-   * @param {vec4} b the second operand
+   * @param {ReadonlyVec4} a the first operand
+   * @param {ReadonlyVec4} b the second operand
    * @returns {vec4} out
    */
 
@@ -4803,7 +5006,7 @@ THE SOFTWARE.
    * Math.round the components of a vec4
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a vector to round
+   * @param {ReadonlyVec4} a vector to round
    * @returns {vec4} out
    */
 
@@ -4818,12 +5021,12 @@ THE SOFTWARE.
    * Scales a vec4 by a scalar number
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a the vector to scale
+   * @param {ReadonlyVec4} a the vector to scale
    * @param {Number} b amount to scale the vector by
    * @returns {vec4} out
    */
 
-  function scale$5(out, a, b) {
+  function scale$3(out, a, b) {
     out[0] = a[0] * b;
     out[1] = a[1] * b;
     out[2] = a[2] * b;
@@ -4834,8 +5037,8 @@ THE SOFTWARE.
    * Adds two vec4's after scaling the second operand by a scalar value
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a the first operand
-   * @param {vec4} b the second operand
+   * @param {ReadonlyVec4} a the first operand
+   * @param {ReadonlyVec4} b the second operand
    * @param {Number} scale the amount to scale b by before adding
    * @returns {vec4} out
    */
@@ -4850,8 +5053,8 @@ THE SOFTWARE.
   /**
    * Calculates the euclidian distance between two vec4's
    *
-   * @param {vec4} a the first operand
-   * @param {vec4} b the second operand
+   * @param {ReadonlyVec4} a the first operand
+   * @param {ReadonlyVec4} b the second operand
    * @returns {Number} distance between a and b
    */
 
@@ -4865,8 +5068,8 @@ THE SOFTWARE.
   /**
    * Calculates the squared euclidian distance between two vec4's
    *
-   * @param {vec4} a the first operand
-   * @param {vec4} b the second operand
+   * @param {ReadonlyVec4} a the first operand
+   * @param {ReadonlyVec4} b the second operand
    * @returns {Number} squared distance between a and b
    */
 
@@ -4880,11 +5083,11 @@ THE SOFTWARE.
   /**
    * Calculates the length of a vec4
    *
-   * @param {vec4} a vector to calculate length of
+   * @param {ReadonlyVec4} a vector to calculate length of
    * @returns {Number} length of a
    */
 
-  function length$1(a) {
+  function length$3(a) {
     var x = a[0];
     var y = a[1];
     var z = a[2];
@@ -4894,11 +5097,11 @@ THE SOFTWARE.
   /**
    * Calculates the squared length of a vec4
    *
-   * @param {vec4} a vector to calculate squared length of
+   * @param {ReadonlyVec4} a vector to calculate squared length of
    * @returns {Number} squared length of a
    */
 
-  function squaredLength$1(a) {
+  function squaredLength$3(a) {
     var x = a[0];
     var y = a[1];
     var z = a[2];
@@ -4909,7 +5112,7 @@ THE SOFTWARE.
    * Negates the components of a vec4
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a vector to negate
+   * @param {ReadonlyVec4} a vector to negate
    * @returns {vec4} out
    */
 
@@ -4924,7 +5127,7 @@ THE SOFTWARE.
    * Returns the inverse of the components of a vec4
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a vector to invert
+   * @param {ReadonlyVec4} a vector to invert
    * @returns {vec4} out
    */
 
@@ -4939,11 +5142,11 @@ THE SOFTWARE.
    * Normalize a vec4
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a vector to normalize
+   * @param {ReadonlyVec4} a vector to normalize
    * @returns {vec4} out
    */
 
-  function normalize$1(out, a) {
+  function normalize$3(out, a) {
     var x = a[0];
     var y = a[1];
     var z = a[2];
@@ -4963,21 +5166,21 @@ THE SOFTWARE.
   /**
    * Calculates the dot product of two vec4's
    *
-   * @param {vec4} a the first operand
-   * @param {vec4} b the second operand
+   * @param {ReadonlyVec4} a the first operand
+   * @param {ReadonlyVec4} b the second operand
    * @returns {Number} dot product of a and b
    */
 
-  function dot$1(a, b) {
+  function dot$3(a, b) {
     return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
   }
   /**
    * Returns the cross-product of three vectors in a 4-dimensional space
    *
-   * @param {vec4} result the receiving vector
-   * @param {vec4} U the first vector
-   * @param {vec4} V the second vector
-   * @param {vec4} W the third vector
+   * @param {ReadonlyVec4} result the receiving vector
+   * @param {ReadonlyVec4} U the first vector
+   * @param {ReadonlyVec4} V the second vector
+   * @param {ReadonlyVec4} W the third vector
    * @returns {vec4} result
    */
 
@@ -5002,13 +5205,13 @@ THE SOFTWARE.
    * Performs a linear interpolation between two vec4's
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a the first operand
-   * @param {vec4} b the second operand
+   * @param {ReadonlyVec4} a the first operand
+   * @param {ReadonlyVec4} b the second operand
    * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
    * @returns {vec4} out
    */
 
-  function lerp$1(out, a, b, t) {
+  function lerp$3(out, a, b, t) {
     var ax = a[0];
     var ay = a[1];
     var az = a[2];
@@ -5023,12 +5226,12 @@ THE SOFTWARE.
    * Generates a random vector with the given scale
    *
    * @param {vec4} out the receiving vector
-   * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
+   * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned
    * @returns {vec4} out
    */
 
-  function random$1(out, scale) {
-    scale = scale || 1.0; // Marsaglia, George. Choosing a Point from the Surface of a
+  function random$2(out, scale) {
+    scale = scale === undefined ? 1.0 : scale; // Marsaglia, George. Choosing a Point from the Surface of a
     // Sphere. Ann. Math. Statist. 43 (1972), no. 2, 645--646.
     // http://projecteuclid.org/euclid.aoms/1177692644;
 
@@ -5058,8 +5261,8 @@ THE SOFTWARE.
    * Transforms the vec4 with a mat4.
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a the vector to transform
-   * @param {mat4} m matrix to transform with
+   * @param {ReadonlyVec4} a the vector to transform
+   * @param {ReadonlyMat4} m matrix to transform with
    * @returns {vec4} out
    */
 
@@ -5078,12 +5281,12 @@ THE SOFTWARE.
    * Transforms the vec4 with a quat
    *
    * @param {vec4} out the receiving vector
-   * @param {vec4} a the vector to transform
-   * @param {quat} q quaternion to transform with
+   * @param {ReadonlyVec4} a the vector to transform
+   * @param {ReadonlyQuat} q quaternion to transform with
    * @returns {vec4} out
    */
 
-  function transformQuat$1(out, a, q) {
+  function transformQuat(out, a, q) {
     var x = a[0],
         y = a[1],
         z = a[2];
@@ -5120,33 +5323,33 @@ THE SOFTWARE.
   /**
    * Returns a string representation of a vector
    *
-   * @param {vec4} a vector to represent as a string
+   * @param {ReadonlyVec4} a vector to represent as a string
    * @returns {String} string representation of the vector
    */
 
-  function str$5(a) {
-    return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
+  function str$3(a) {
+    return "vec4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")";
   }
   /**
    * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)
    *
-   * @param {vec4} a The first vector.
-   * @param {vec4} b The second vector.
+   * @param {ReadonlyVec4} a The first vector.
+   * @param {ReadonlyVec4} b The second vector.
    * @returns {Boolean} True if the vectors are equal, false otherwise.
    */
 
-  function exactEquals$5(a, b) {
+  function exactEquals$3(a, b) {
     return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3];
   }
   /**
    * Returns whether or not the vectors have approximately the same elements in the same position.
    *
-   * @param {vec4} a The first vector.
-   * @param {vec4} b The second vector.
+   * @param {ReadonlyVec4} a The first vector.
+   * @param {ReadonlyVec4} b The second vector.
    * @returns {Boolean} True if the vectors are equal, false otherwise.
    */
 
-  function equals$6(a, b) {
+  function equals$3(a, b) {
     var a0 = a[0],
         a1 = a[1],
         a2 = a[2],
@@ -5162,13 +5365,13 @@ THE SOFTWARE.
    * @function
    */
 
-  var sub$5 = subtract$5;
+  var sub$1 = subtract$1;
   /**
    * Alias for {@link vec4.multiply}
    * @function
    */
 
-  var mul$5 = multiply$5;
+  var mul$3 = multiply$3;
   /**
    * Alias for {@link vec4.divide}
    * @function
@@ -5192,13 +5395,13 @@ THE SOFTWARE.
    * @function
    */
 
-  var len$1 = length$1;
+  var len$3 = length$3;
   /**
    * Alias for {@link vec4.squaredLength}
    * @function
    */
 
-  var sqrLen$1 = squaredLength$1;
+  var sqrLen$3 = squaredLength$3;
   /**
    * Perform some operation over an array of vec4s.
    *
@@ -5213,7 +5416,7 @@ THE SOFTWARE.
    */
 
   var forEach$1 = function () {
-    var vec = create$5();
+    var vec = create$3();
     return function (a, stride, offset, count, fn, arg) {
       var i, l;
 
@@ -5248,51 +5451,52 @@ THE SOFTWARE.
   }();
 
   var vec4 = /*#__PURE__*/Object.freeze({
-    create: create$5,
-    clone: clone$5,
-    fromValues: fromValues$5,
-    copy: copy$5,
-    set: set$5,
-    add: add$5,
-    subtract: subtract$5,
-    multiply: multiply$5,
+    __proto__: null,
+    create: create$3,
+    clone: clone$3,
+    fromValues: fromValues$3,
+    copy: copy$3,
+    set: set$3,
+    add: add$3,
+    subtract: subtract$1,
+    multiply: multiply$3,
     divide: divide$1,
     ceil: ceil$1,
     floor: floor$1,
     min: min$1,
     max: max$1,
     round: round$1,
-    scale: scale$5,
+    scale: scale$3,
     scaleAndAdd: scaleAndAdd$1,
     distance: distance$1,
     squaredDistance: squaredDistance$1,
-    length: length$1,
-    squaredLength: squaredLength$1,
+    length: length$3,
+    squaredLength: squaredLength$3,
     negate: negate$1,
     inverse: inverse$1,
-    normalize: normalize$1,
-    dot: dot$1,
+    normalize: normalize$3,
+    dot: dot$3,
     cross: cross$1,
-    lerp: lerp$1,
-    random: random$1,
+    lerp: lerp$3,
+    random: random$2,
     transformMat4: transformMat4$1,
-    transformQuat: transformQuat$1,
+    transformQuat: transformQuat,
     zero: zero$1,
-    str: str$5,
-    exactEquals: exactEquals$5,
-    equals: equals$6,
-    sub: sub$5,
-    mul: mul$5,
+    str: str$3,
+    exactEquals: exactEquals$3,
+    equals: equals$3,
+    sub: sub$1,
+    mul: mul$3,
     div: div$1,
     dist: dist$1,
     sqrDist: sqrDist$1,
-    len: len$1,
-    sqrLen: sqrLen$1,
+    len: len$3,
+    sqrLen: sqrLen$3,
     forEach: forEach$1
   });
 
   /**
-   * Quaternion
+   * Quaternion in the format XYZW
    * @module quat
    */
 
@@ -5302,7 +5506,7 @@ THE SOFTWARE.
    * @returns {quat} a new quaternion
    */
 
-  function create$6() {
+  function create$2() {
     var out = new ARRAY_TYPE(4);
 
     if (ARRAY_TYPE != Float32Array) {
@@ -5321,7 +5525,7 @@ THE SOFTWARE.
    * @returns {quat} out
    */
 
-  function identity$4(out) {
+  function identity$1(out) {
     out[0] = 0;
     out[1] = 0;
     out[2] = 0;
@@ -5333,7 +5537,7 @@ THE SOFTWARE.
    * then returns it.
    *
    * @param {quat} out the receiving quaternion
-   * @param {vec3} axis the axis around which to rotate
+   * @param {ReadonlyVec3} axis the axis around which to rotate
    * @param {Number} rad the angle in radians
    * @returns {quat} out
    **/
@@ -5357,7 +5561,7 @@ THE SOFTWARE.
    *  angle -90 is the same as the quaternion formed by
    *  [0, 0, 1] and 270. This method favors the latter.
    * @param  {vec3} out_axis  Vector receiving the axis of rotation
-   * @param  {quat} q     Quaternion to be decomposed
+   * @param  {ReadonlyQuat} q     Quaternion to be decomposed
    * @return {Number}     Angle, in radians, of the rotation
    */
 
@@ -5381,8 +5585,8 @@ THE SOFTWARE.
   /**
    * Gets the angular distance between two unit quaternions
    *
-   * @param  {quat} a     Origin unit quaternion
-   * @param  {quat} b     Destination unit quaternion
+   * @param  {ReadonlyQuat} a     Origin unit quaternion
+   * @param  {ReadonlyQuat} b     Destination unit quaternion
    * @return {Number}     Angle, in radians, between the two quaternions
    */
 
@@ -5394,12 +5598,12 @@ THE SOFTWARE.
    * Multiplies two quat's
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a the first operand
-   * @param {quat} b the second operand
+   * @param {ReadonlyQuat} a the first operand
+   * @param {ReadonlyQuat} b the second operand
    * @returns {quat} out
    */
 
-  function multiply$6(out, a, b) {
+  function multiply$2(out, a, b) {
     var ax = a[0],
         ay = a[1],
         az = a[2],
@@ -5418,12 +5622,12 @@ THE SOFTWARE.
    * Rotates a quaternion by the given angle about the X axis
    *
    * @param {quat} out quat receiving operation result
-   * @param {quat} a quat to rotate
+   * @param {ReadonlyQuat} a quat to rotate
    * @param {number} rad angle (in radians) to rotate
    * @returns {quat} out
    */
 
-  function rotateX$2(out, a, rad) {
+  function rotateX$1(out, a, rad) {
     rad *= 0.5;
     var ax = a[0],
         ay = a[1],
@@ -5441,12 +5645,12 @@ THE SOFTWARE.
    * Rotates a quaternion by the given angle about the Y axis
    *
    * @param {quat} out quat receiving operation result
-   * @param {quat} a quat to rotate
+   * @param {ReadonlyQuat} a quat to rotate
    * @param {number} rad angle (in radians) to rotate
    * @returns {quat} out
    */
 
-  function rotateY$2(out, a, rad) {
+  function rotateY$1(out, a, rad) {
     rad *= 0.5;
     var ax = a[0],
         ay = a[1],
@@ -5464,12 +5668,12 @@ THE SOFTWARE.
    * Rotates a quaternion by the given angle about the Z axis
    *
    * @param {quat} out quat receiving operation result
-   * @param {quat} a quat to rotate
+   * @param {ReadonlyQuat} a quat to rotate
    * @param {number} rad angle (in radians) to rotate
    * @returns {quat} out
    */
 
-  function rotateZ$2(out, a, rad) {
+  function rotateZ$1(out, a, rad) {
     rad *= 0.5;
     var ax = a[0],
         ay = a[1],
@@ -5489,7 +5693,7 @@ THE SOFTWARE.
    * Any existing W component will be ignored.
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a quat to calculate W component of
+   * @param {ReadonlyQuat} a quat to calculate W component of
    * @returns {quat} out
    */
 
@@ -5507,7 +5711,7 @@ THE SOFTWARE.
    * Calculate the exponential of a unit quaternion.
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a quat to calculate the exponential of
+   * @param {ReadonlyQuat} a quat to calculate the exponential of
    * @returns {quat} out
    */
 
@@ -5529,7 +5733,7 @@ THE SOFTWARE.
    * Calculate the natural logarithm of a unit quaternion.
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a quat to calculate the exponential of
+   * @param {ReadonlyQuat} a quat to calculate the exponential of
    * @returns {quat} out
    */
 
@@ -5550,14 +5754,14 @@ THE SOFTWARE.
    * Calculate the scalar power of a unit quaternion.
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a quat to calculate the exponential of
+   * @param {ReadonlyQuat} a quat to calculate the exponential of
    * @param {Number} b amount to scale the quaternion by
    * @returns {quat} out
    */
 
   function pow(out, a, b) {
     ln(out, a);
-    scale$6(out, out, b);
+    scale$2(out, out, b);
     exp(out, out);
     return out;
   }
@@ -5565,8 +5769,8 @@ THE SOFTWARE.
    * Performs a spherical linear interpolation between two quat
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a the first operand
-   * @param {quat} b the second operand
+   * @param {ReadonlyQuat} a the first operand
+   * @param {ReadonlyQuat} b the second operand
    * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
    * @returns {quat} out
    */
@@ -5622,7 +5826,7 @@ THE SOFTWARE.
    * @returns {quat} out
    */
 
-  function random$2(out) {
+  function random$1(out) {
     // Implementation of http://planning.cs.uiuc.edu/node198.html
     // TODO: Calling random 3 times is probably not the fastest solution
     var u1 = RANDOM();
@@ -5640,11 +5844,11 @@ THE SOFTWARE.
    * Calculates the inverse of a quat
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a quat to calculate inverse of
+   * @param {ReadonlyQuat} a quat to calculate inverse of
    * @returns {quat} out
    */
 
-  function invert$4(out, a) {
+  function invert$1(out, a) {
     var a0 = a[0],
         a1 = a[1],
         a2 = a[2],
@@ -5663,11 +5867,11 @@ THE SOFTWARE.
    * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a quat to calculate conjugate of
+   * @param {ReadonlyQuat} a quat to calculate conjugate of
    * @returns {quat} out
    */
 
-  function conjugate(out, a) {
+  function conjugate$1(out, a) {
     out[0] = -a[0];
     out[1] = -a[1];
     out[2] = -a[2];
@@ -5681,7 +5885,7 @@ THE SOFTWARE.
    * to renormalize the quaternion yourself where necessary.
    *
    * @param {quat} out the receiving quaternion
-   * @param {mat3} m rotation matrix
+   * @param {ReadonlyMat3} m rotation matrix
    * @returns {quat} out
    * @function
    */
@@ -5720,52 +5924,98 @@ THE SOFTWARE.
     return out;
   }
   /**
-   * Creates a quaternion from the given euler angle x, y, z.
+   * Creates a quaternion from the given euler angle x, y, z using the provided intrinsic order for the conversion.
    *
    * @param {quat} out the receiving quaternion
-   * @param {x} Angle to rotate around X axis in degrees.
-   * @param {y} Angle to rotate around Y axis in degrees.
-   * @param {z} Angle to rotate around Z axis in degrees.
+   * @param {x} x Angle to rotate around X axis in degrees.
+   * @param {y} y Angle to rotate around Y axis in degrees.
+   * @param {z} z Angle to rotate around Z axis in degrees.
+   * @param {'zyx'|'xyz'|'yxz'|'yzx'|'zxy'|'zyx'} order Intrinsic order for conversion, default is zyx.
    * @returns {quat} out
    * @function
    */
 
   function fromEuler(out, x, y, z) {
-    var halfToRad = 0.5 * Math.PI / 180.0;
+    var order = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : ANGLE_ORDER;
+    var halfToRad = Math.PI / 360;
     x *= halfToRad;
-    y *= halfToRad;
     z *= halfToRad;
+    y *= halfToRad;
     var sx = Math.sin(x);
     var cx = Math.cos(x);
     var sy = Math.sin(y);
     var cy = Math.cos(y);
     var sz = Math.sin(z);
     var cz = Math.cos(z);
-    out[0] = sx * cy * cz - cx * sy * sz;
-    out[1] = cx * sy * cz + sx * cy * sz;
-    out[2] = cx * cy * sz - sx * sy * cz;
-    out[3] = cx * cy * cz + sx * sy * sz;
+
+    switch (order) {
+      case "xyz":
+        out[0] = sx * cy * cz + cx * sy * sz;
+        out[1] = cx * sy * cz - sx * cy * sz;
+        out[2] = cx * cy * sz + sx * sy * cz;
+        out[3] = cx * cy * cz - sx * sy * sz;
+        break;
+
+      case "xzy":
+        out[0] = sx * cy * cz - cx * sy * sz;
+        out[1] = cx * sy * cz - sx * cy * sz;
+        out[2] = cx * cy * sz + sx * sy * cz;
+        out[3] = cx * cy * cz + sx * sy * sz;
+        break;
+
+      case "yxz":
+        out[0] = sx * cy * cz + cx * sy * sz;
+        out[1] = cx * sy * cz - sx * cy * sz;
+        out[2] = cx * cy * sz - sx * sy * cz;
+        out[3] = cx * cy * cz + sx * sy * sz;
+        break;
+
+      case "yzx":
+        out[0] = sx * cy * cz + cx * sy * sz;
+        out[1] = cx * sy * cz + sx * cy * sz;
+        out[2] = cx * cy * sz - sx * sy * cz;
+        out[3] = cx * cy * cz - sx * sy * sz;
+        break;
+
+      case "zxy":
+        out[0] = sx * cy * cz - cx * sy * sz;
+        out[1] = cx * sy * cz + sx * cy * sz;
+        out[2] = cx * cy * sz + sx * sy * cz;
+        out[3] = cx * cy * cz - sx * sy * sz;
+        break;
+
+      case "zyx":
+        out[0] = sx * cy * cz - cx * sy * sz;
+        out[1] = cx * sy * cz + sx * cy * sz;
+        out[2] = cx * cy * sz - sx * sy * cz;
+        out[3] = cx * cy * cz + sx * sy * sz;
+        break;
+
+      default:
+        throw new Error('Unknown angle order ' + order);
+    }
+
     return out;
   }
   /**
-   * Returns a string representation of a quatenion
+   * Returns a string representation of a quaternion
    *
-   * @param {quat} a vector to represent as a string
+   * @param {ReadonlyQuat} a vector to represent as a string
    * @returns {String} string representation of the vector
    */
 
-  function str$6(a) {
-    return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
+  function str$2(a) {
+    return "quat(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")";
   }
   /**
    * Creates a new quat initialized with values from an existing quaternion
    *
-   * @param {quat} a quaternion to clone
+   * @param {ReadonlyQuat} a quaternion to clone
    * @returns {quat} a new quaternion
    * @function
    */
 
-  var clone$6 = clone$5;
+  var clone$2 = clone$3;
   /**
    * Creates a new quat initialized with the given values
    *
@@ -5777,17 +6027,17 @@ THE SOFTWARE.
    * @function
    */
 
-  var fromValues$6 = fromValues$5;
+  var fromValues$2 = fromValues$3;
   /**
    * Copy the values from one quat to another
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a the source quaternion
+   * @param {ReadonlyQuat} a the source quaternion
    * @returns {quat} out
    * @function
    */
 
-  var copy$6 = copy$5;
+  var copy$2 = copy$3;
   /**
    * Set the components of a quat to the given values
    *
@@ -5800,65 +6050,65 @@ THE SOFTWARE.
    * @function
    */
 
-  var set$6 = set$5;
+  var set$2 = set$3;
   /**
    * Adds two quat's
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a the first operand
-   * @param {quat} b the second operand
+   * @param {ReadonlyQuat} a the first operand
+   * @param {ReadonlyQuat} b the second operand
    * @returns {quat} out
    * @function
    */
 
-  var add$6 = add$5;
+  var add$2 = add$3;
   /**
    * Alias for {@link quat.multiply}
    * @function
    */
 
-  var mul$6 = multiply$6;
+  var mul$2 = multiply$2;
   /**
    * Scales a quat by a scalar number
    *
    * @param {quat} out the receiving vector
-   * @param {quat} a the vector to scale
+   * @param {ReadonlyQuat} a the vector to scale
    * @param {Number} b amount to scale the vector by
    * @returns {quat} out
    * @function
    */
 
-  var scale$6 = scale$5;
+  var scale$2 = scale$3;
   /**
    * Calculates the dot product of two quat's
    *
-   * @param {quat} a the first operand
-   * @param {quat} b the second operand
+   * @param {ReadonlyQuat} a the first operand
+   * @param {ReadonlyQuat} b the second operand
    * @returns {Number} dot product of a and b
    * @function
    */
 
-  var dot$2 = dot$1;
+  var dot$2 = dot$3;
   /**
    * Performs a linear interpolation between two quat's
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a the first operand
-   * @param {quat} b the second operand
+   * @param {ReadonlyQuat} a the first operand
+   * @param {ReadonlyQuat} b the second operand
    * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
    * @returns {quat} out
    * @function
    */
 
-  var lerp$2 = lerp$1;
+  var lerp$2 = lerp$3;
   /**
    * Calculates the length of a quat
    *
-   * @param {quat} a vector to calculate length of
+   * @param {ReadonlyQuat} a vector to calculate length of
    * @returns {Number} length of a
    */
 
-  var length$2 = length$1;
+  var length$2 = length$3;
   /**
    * Alias for {@link quat.length}
    * @function
@@ -5868,12 +6118,12 @@ THE SOFTWARE.
   /**
    * Calculates the squared length of a quat
    *
-   * @param {quat} a vector to calculate squared length of
+   * @param {ReadonlyQuat} a vector to calculate squared length of
    * @returns {Number} squared length of a
    * @function
    */
 
-  var squaredLength$2 = squaredLength$1;
+  var squaredLength$2 = squaredLength$3;
   /**
    * Alias for {@link quat.squaredLength}
    * @function
@@ -5884,30 +6134,34 @@ THE SOFTWARE.
    * Normalize a quat
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a quaternion to normalize
+   * @param {ReadonlyQuat} a quaternion to normalize
    * @returns {quat} out
    * @function
    */
 
-  var normalize$2 = normalize$1;
+  var normalize$2 = normalize$3;
   /**
    * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===)
    *
-   * @param {quat} a The first quaternion.
-   * @param {quat} b The second quaternion.
+   * @param {ReadonlyQuat} a The first quaternion.
+   * @param {ReadonlyQuat} b The second quaternion.
    * @returns {Boolean} True if the vectors are equal, false otherwise.
    */
 
-  var exactEquals$6 = exactEquals$5;
+  var exactEquals$2 = exactEquals$3;
   /**
-   * Returns whether or not the quaternions have approximately the same elements in the same position.
+   * Returns whether or not the quaternions point approximately to the same direction.
    *
-   * @param {quat} a The first vector.
-   * @param {quat} b The second vector.
-   * @returns {Boolean} True if the vectors are equal, false otherwise.
+   * Both quaternions are assumed to be unit length.
+   *
+   * @param {ReadonlyQuat} a The first unit quaternion.
+   * @param {ReadonlyQuat} b The second unit quaternion.
+   * @returns {Boolean} True if the quaternions are equal, false otherwise.
    */
 
-  var equals$7 = equals$6;
+  function equals$2(a, b) {
+    return Math.abs(dot$3(a, b)) >= 1 - EPSILON;
+  }
   /**
    * Sets a quaternion to represent the shortest rotation from one
    * vector to another.
@@ -5915,8 +6169,8 @@ THE SOFTWARE.
    * Both vectors are assumed to be unit length.
    *
    * @param {quat} out the receiving quaternion.
-   * @param {vec3} a the initial vector
-   * @param {vec3} b the destination vector
+   * @param {ReadonlyVec3} a the initial vector
+   * @param {ReadonlyVec3} b the destination vector
    * @returns {quat} out
    */
 
@@ -5925,26 +6179,26 @@ THE SOFTWARE.
     var xUnitVec3 = fromValues$4(1, 0, 0);
     var yUnitVec3 = fromValues$4(0, 1, 0);
     return function (out, a, b) {
-      var dot$1 = dot(a, b);
+      var dot = dot$4(a, b);
 
-      if (dot$1 < -0.999999) {
-        cross(tmpvec3, xUnitVec3, a);
-        if (len(tmpvec3) < 0.000001) cross(tmpvec3, yUnitVec3, a);
-        normalize(tmpvec3, tmpvec3);
+      if (dot < -0.999999) {
+        cross$2(tmpvec3, xUnitVec3, a);
+        if (len$4(tmpvec3) < 0.000001) cross$2(tmpvec3, yUnitVec3, a);
+        normalize$4(tmpvec3, tmpvec3);
         setAxisAngle(out, tmpvec3, Math.PI);
         return out;
-      } else if (dot$1 > 0.999999) {
+      } else if (dot > 0.999999) {
         out[0] = 0;
         out[1] = 0;
         out[2] = 0;
         out[3] = 1;
         return out;
       } else {
-        cross(tmpvec3, a, b);
+        cross$2(tmpvec3, a, b);
         out[0] = tmpvec3[0];
         out[1] = tmpvec3[1];
         out[2] = tmpvec3[2];
-        out[3] = 1 + dot$1;
+        out[3] = 1 + dot;
         return normalize$2(out, out);
       }
     };
@@ -5953,17 +6207,17 @@ THE SOFTWARE.
    * Performs a spherical linear interpolation with two control points
    *
    * @param {quat} out the receiving quaternion
-   * @param {quat} a the first operand
-   * @param {quat} b the second operand
-   * @param {quat} c the third operand
-   * @param {quat} d the fourth operand
+   * @param {ReadonlyQuat} a the first operand
+   * @param {ReadonlyQuat} b the second operand
+   * @param {ReadonlyQuat} c the third operand
+   * @param {ReadonlyQuat} d the fourth operand
    * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
    * @returns {quat} out
    */
 
   var sqlerp = function () {
-    var temp1 = create$6();
-    var temp2 = create$6();
+    var temp1 = create$2();
+    var temp2 = create$2();
     return function (out, a, b, c, d, t) {
       slerp(temp1, a, d, t);
       slerp(temp2, b, c, t);
@@ -5976,14 +6230,14 @@ THE SOFTWARE.
    * axes. Each axis is a vec3 and is expected to be unit length and
    * perpendicular to all other specified axes.
    *
-   * @param {vec3} view  the vector representing the viewing direction
-   * @param {vec3} right the vector representing the local "right" direction
-   * @param {vec3} up    the vector representing the local "up" direction
+   * @param {ReadonlyVec3} view  the vector representing the viewing direction
+   * @param {ReadonlyVec3} right the vector representing the local "right" direction
+   * @param {ReadonlyVec3} up    the vector representing the local "up" direction
    * @returns {quat} out
    */
 
   var setAxes = function () {
-    var matr = create$2();
+    var matr = create$6();
     return function (out, view, right, up) {
       matr[0] = right[0];
       matr[3] = right[1];
@@ -5999,33 +6253,34 @@ THE SOFTWARE.
   }();
 
   var quat = /*#__PURE__*/Object.freeze({
-    create: create$6,
-    identity: identity$4,
+    __proto__: null,
+    create: create$2,
+    identity: identity$1,
     setAxisAngle: setAxisAngle,
     getAxisAngle: getAxisAngle,
     getAngle: getAngle,
-    multiply: multiply$6,
-    rotateX: rotateX$2,
-    rotateY: rotateY$2,
-    rotateZ: rotateZ$2,
+    multiply: multiply$2,
+    rotateX: rotateX$1,
+    rotateY: rotateY$1,
+    rotateZ: rotateZ$1,
     calculateW: calculateW,
     exp: exp,
     ln: ln,
     pow: pow,
     slerp: slerp,
-    random: random$2,
-    invert: invert$4,
-    conjugate: conjugate,
+    random: random$1,
+    invert: invert$1,
+    conjugate: conjugate$1,
     fromMat3: fromMat3,
     fromEuler: fromEuler,
-    str: str$6,
-    clone: clone$6,
-    fromValues: fromValues$6,
-    copy: copy$6,
-    set: set$6,
-    add: add$6,
-    mul: mul$6,
-    scale: scale$6,
+    str: str$2,
+    clone: clone$2,
+    fromValues: fromValues$2,
+    copy: copy$2,
+    set: set$2,
+    add: add$2,
+    mul: mul$2,
+    scale: scale$2,
     dot: dot$2,
     lerp: lerp$2,
     length: length$2,
@@ -6033,8 +6288,8 @@ THE SOFTWARE.
     squaredLength: squaredLength$2,
     sqrLen: sqrLen$2,
     normalize: normalize$2,
-    exactEquals: exactEquals$6,
-    equals: equals$7,
+    exactEquals: exactEquals$2,
+    equals: equals$2,
     rotationTo: rotationTo,
     sqlerp: sqlerp,
     setAxes: setAxes
@@ -6054,7 +6309,7 @@ THE SOFTWARE.
    * @returns {quat2} a new dual quaternion [real -> rotation, dual -> translation]
    */
 
-  function create$7() {
+  function create$1() {
     var dq = new ARRAY_TYPE(8);
 
     if (ARRAY_TYPE != Float32Array) {
@@ -6073,12 +6328,12 @@ THE SOFTWARE.
   /**
    * Creates a new quat initialized with values from an existing quaternion
    *
-   * @param {quat2} a dual quaternion to clone
+   * @param {ReadonlyQuat2} a dual quaternion to clone
    * @returns {quat2} new dual quaternion
    * @function
    */
 
-  function clone$7(a) {
+  function clone$1(a) {
     var dq = new ARRAY_TYPE(8);
     dq[0] = a[0];
     dq[1] = a[1];
@@ -6105,7 +6360,7 @@ THE SOFTWARE.
    * @function
    */
 
-  function fromValues$7(x1, y1, z1, w1, x2, y2, z2, w2) {
+  function fromValues$1(x1, y1, z1, w1, x2, y2, z2, w2) {
     var dq = new ARRAY_TYPE(8);
     dq[0] = x1;
     dq[1] = y1;
@@ -6149,14 +6404,14 @@ THE SOFTWARE.
   /**
    * Creates a dual quat from a quaternion and a translation
    *
-   * @param {quat2} dual quaternion receiving operation result
-   * @param {quat} q a normalized quaternion
-   * @param {vec3} t tranlation vector
+   * @param {ReadonlyQuat2} dual quaternion receiving operation result
+   * @param {ReadonlyQuat} q a normalized quaternion
+   * @param {ReadonlyVec3} t translation vector
    * @returns {quat2} dual quaternion receiving operation result
    * @function
    */
 
-  function fromRotationTranslation$1(out, q, t) {
+  function fromRotationTranslation(out, q, t) {
     var ax = t[0] * 0.5,
         ay = t[1] * 0.5,
         az = t[2] * 0.5,
@@ -6177,13 +6432,13 @@ THE SOFTWARE.
   /**
    * Creates a dual quat from a translation
    *
-   * @param {quat2} dual quaternion receiving operation result
-   * @param {vec3} t translation vector
+   * @param {ReadonlyQuat2} dual quaternion receiving operation result
+   * @param {ReadonlyVec3} t translation vector
    * @returns {quat2} dual quaternion receiving operation result
    * @function
    */
 
-  function fromTranslation$3(out, t) {
+  function fromTranslation(out, t) {
     out[0] = 0;
     out[1] = 0;
     out[2] = 0;
@@ -6197,13 +6452,13 @@ THE SOFTWARE.
   /**
    * Creates a dual quat from a quaternion
    *
-   * @param {quat2} dual quaternion receiving operation result
-   * @param {quat} q the quaternion
+   * @param {ReadonlyQuat2} dual quaternion receiving operation result
+   * @param {ReadonlyQuat} q the quaternion
    * @returns {quat2} dual quaternion receiving operation result
    * @function
    */
 
-  function fromRotation$4(out, q) {
+  function fromRotation(out, q) {
     out[0] = q[0];
     out[1] = q[1];
     out[2] = q[2];
@@ -6218,30 +6473,30 @@ THE SOFTWARE.
    * Creates a new dual quat from a matrix (4x4)
    *
    * @param {quat2} out the dual quaternion
-   * @param {mat4} a the matrix
+   * @param {ReadonlyMat4} a the matrix
    * @returns {quat2} dual quat receiving operation result
    * @function
    */
 
-  function fromMat4$1(out, a) {
+  function fromMat4(out, a) {
     //TODO Optimize this
-    var outer = create$6();
+    var outer = create$2();
     getRotation(outer, a);
     var t = new ARRAY_TYPE(3);
-    getTranslation(t, a);
-    fromRotationTranslation$1(out, outer, t);
+    getTranslation$1(t, a);
+    fromRotationTranslation(out, outer, t);
     return out;
   }
   /**
    * Copy the values from one dual quat to another
    *
    * @param {quat2} out the receiving dual quaternion
-   * @param {quat2} a the source dual quaternion
+   * @param {ReadonlyQuat2} a the source dual quaternion
    * @returns {quat2} out
    * @function
    */
 
-  function copy$7(out, a) {
+  function copy$1(out, a) {
     out[0] = a[0];
     out[1] = a[1];
     out[2] = a[2];
@@ -6259,7 +6514,7 @@ THE SOFTWARE.
    * @returns {quat2} out
    */
 
-  function identity$5(out) {
+  function identity(out) {
     out[0] = 0;
     out[1] = 0;
     out[2] = 0;
@@ -6286,7 +6541,7 @@ THE SOFTWARE.
    * @function
    */
 
-  function set$7(out, x1, y1, z1, w1, x2, y2, z2, w2) {
+  function set$1(out, x1, y1, z1, w1, x2, y2, z2, w2) {
     out[0] = x1;
     out[1] = y1;
     out[2] = z1;
@@ -6300,15 +6555,15 @@ THE SOFTWARE.
   /**
    * Gets the real part of a dual quat
    * @param  {quat} out real part
-   * @param  {quat2} a Dual Quaternion
+   * @param  {ReadonlyQuat2} a Dual Quaternion
    * @return {quat} real part
    */
 
-  var getReal = copy$6;
+  var getReal = copy$2;
   /**
    * Gets the dual part of a dual quat
    * @param  {quat} out dual part
-   * @param  {quat2} a Dual Quaternion
+   * @param  {ReadonlyQuat2} a Dual Quaternion
    * @return {quat} dual part
    */
 
@@ -6323,17 +6578,17 @@ THE SOFTWARE.
    * Set the real component of a dual quat to the given quaternion
    *
    * @param {quat2} out the receiving quaternion
-   * @param {quat} q a quaternion representing the real part
+   * @param {ReadonlyQuat} q a quaternion representing the real part
    * @returns {quat2} out
    * @function
    */
 
-  var setReal = copy$6;
+  var setReal = copy$2;
   /**
    * Set the dual component of a dual quat to the given quaternion
    *
    * @param {quat2} out the receiving quaternion
-   * @param {quat} q a quaternion representing the dual part
+   * @param {ReadonlyQuat} q a quaternion representing the dual part
    * @returns {quat2} out
    * @function
    */
@@ -6348,11 +6603,11 @@ THE SOFTWARE.
   /**
    * Gets the translation of a normalized dual quat
    * @param  {vec3} out translation
-   * @param  {quat2} a Dual Quaternion to be decomposed
+   * @param  {ReadonlyQuat2} a Dual Quaternion to be decomposed
    * @return {vec3} translation
    */
 
-  function getTranslation$1(out, a) {
+  function getTranslation(out, a) {
     var ax = a[4],
         ay = a[5],
         az = a[6],
@@ -6370,12 +6625,12 @@ THE SOFTWARE.
    * Translates a dual quat by the given vector
    *
    * @param {quat2} out the receiving dual quaternion
-   * @param {quat2} a the dual quaternion to translate
-   * @param {vec3} v vector to translate by
+   * @param {ReadonlyQuat2} a the dual quaternion to translate
+   * @param {ReadonlyVec3} v vector to translate by
    * @returns {quat2} out
    */
 
-  function translate$3(out, a, v) {
+  function translate(out, a, v) {
     var ax1 = a[0],
         ay1 = a[1],
         az1 = a[2],
@@ -6401,12 +6656,12 @@ THE SOFTWARE.
    * Rotates a dual quat around the X axis
    *
    * @param {quat2} out the receiving dual quaternion
-   * @param {quat2} a the dual quaternion to rotate
+   * @param {ReadonlyQuat2} a the dual quaternion to rotate
    * @param {number} rad how far should the rotation be
    * @returns {quat2} out
    */
 
-  function rotateX$3(out, a, rad) {
+  function rotateX(out, a, rad) {
     var bx = -a[0],
         by = -a[1],
         bz = -a[2],
@@ -6419,7 +6674,7 @@ THE SOFTWARE.
         ay1 = ay * bw + aw * by + az * bx - ax * bz,
         az1 = az * bw + aw * bz + ax * by - ay * bx,
         aw1 = aw * bw - ax * bx - ay * by - az * bz;
-    rotateX$2(out, a, rad);
+    rotateX$1(out, a, rad);
     bx = out[0];
     by = out[1];
     bz = out[2];
@@ -6434,12 +6689,12 @@ THE SOFTWARE.
    * Rotates a dual quat around the Y axis
    *
    * @param {quat2} out the receiving dual quaternion
-   * @param {quat2} a the dual quaternion to rotate
+   * @param {ReadonlyQuat2} a the dual quaternion to rotate
    * @param {number} rad how far should the rotation be
    * @returns {quat2} out
    */
 
-  function rotateY$3(out, a, rad) {
+  function rotateY(out, a, rad) {
     var bx = -a[0],
         by = -a[1],
         bz = -a[2],
@@ -6452,7 +6707,7 @@ THE SOFTWARE.
         ay1 = ay * bw + aw * by + az * bx - ax * bz,
         az1 = az * bw + aw * bz + ax * by - ay * bx,
         aw1 = aw * bw - ax * bx - ay * by - az * bz;
-    rotateY$2(out, a, rad);
+    rotateY$1(out, a, rad);
     bx = out[0];
     by = out[1];
     bz = out[2];
@@ -6467,12 +6722,12 @@ THE SOFTWARE.
    * Rotates a dual quat around the Z axis
    *
    * @param {quat2} out the receiving dual quaternion
-   * @param {quat2} a the dual quaternion to rotate
+   * @param {ReadonlyQuat2} a the dual quaternion to rotate
    * @param {number} rad how far should the rotation be
    * @returns {quat2} out
    */
 
-  function rotateZ$3(out, a, rad) {
+  function rotateZ(out, a, rad) {
     var bx = -a[0],
         by = -a[1],
         bz = -a[2],
@@ -6485,7 +6740,7 @@ THE SOFTWARE.
         ay1 = ay * bw + aw * by + az * bx - ax * bz,
         az1 = az * bw + aw * bz + ax * by - ay * bx,
         aw1 = aw * bw - ax * bx - ay * by - az * bz;
-    rotateZ$2(out, a, rad);
+    rotateZ$1(out, a, rad);
     bx = out[0];
     by = out[1];
     bz = out[2];
@@ -6500,8 +6755,8 @@ THE SOFTWARE.
    * Rotates a dual quat by a given quaternion (a * q)
    *
    * @param {quat2} out the receiving dual quaternion
-   * @param {quat2} a the dual quaternion to rotate
-   * @param {quat} q quaternion to rotate by
+   * @param {ReadonlyQuat2} a the dual quaternion to rotate
+   * @param {ReadonlyQuat} q quaternion to rotate by
    * @returns {quat2} out
    */
 
@@ -6532,8 +6787,8 @@ THE SOFTWARE.
    * Rotates a dual quat by a given quaternion (q * a)
    *
    * @param {quat2} out the receiving dual quaternion
-   * @param {quat} q quaternion to rotate by
-   * @param {quat2} a the dual quaternion to rotate
+   * @param {ReadonlyQuat} q quaternion to rotate by
+   * @param {ReadonlyQuat2} a the dual quaternion to rotate
    * @returns {quat2} out
    */
 
@@ -6564,8 +6819,8 @@ THE SOFTWARE.
    * Rotates a dual quat around a given axis. Does the normalisation automatically
    *
    * @param {quat2} out the receiving dual quaternion
-   * @param {quat2} a the dual quaternion to rotate
-   * @param {vec3} axis the axis to rotate around
+   * @param {ReadonlyQuat2} a the dual quaternion to rotate
+   * @param {ReadonlyVec3} axis the axis to rotate around
    * @param {Number} rad how far the rotation should be
    * @returns {quat2} out
    */
@@ -6573,7 +6828,7 @@ THE SOFTWARE.
   function rotateAroundAxis(out, a, axis, rad) {
     //Special case for rad = 0
     if (Math.abs(rad) < EPSILON) {
-      return copy$7(out, a);
+      return copy$1(out, a);
     }
 
     var axisLength = Math.hypot(axis[0], axis[1], axis[2]);
@@ -6605,13 +6860,13 @@ THE SOFTWARE.
    * Adds two dual quat's
    *
    * @param {quat2} out the receiving dual quaternion
-   * @param {quat2} a the first operand
-   * @param {quat2} b the second operand
+   * @param {ReadonlyQuat2} a the first operand
+   * @param {ReadonlyQuat2} b the second operand
    * @returns {quat2} out
    * @function
    */
 
-  function add$7(out, a, b) {
+  function add$1(out, a, b) {
     out[0] = a[0] + b[0];
     out[1] = a[1] + b[1];
     out[2] = a[2] + b[2];
@@ -6626,12 +6881,12 @@ THE SOFTWARE.
    * Multiplies two dual quat's
    *
    * @param {quat2} out the receiving dual quaternion
-   * @param {quat2} a the first operand
-   * @param {quat2} b the second operand
+   * @param {ReadonlyQuat2} a the first operand
+   * @param {ReadonlyQuat2} b the second operand
    * @returns {quat2} out
    */
 
-  function multiply$7(out, a, b) {
+  function multiply$1(out, a, b) {
     var ax0 = a[0],
         ay0 = a[1],
         az0 = a[2],
@@ -6663,18 +6918,18 @@ THE SOFTWARE.
    * @function
    */
 
-  var mul$7 = multiply$7;
+  var mul$1 = multiply$1;
   /**
    * Scales a dual quat by a scalar number
    *
    * @param {quat2} out the receiving dual quat
-   * @param {quat2} a the dual quat to scale
+   * @param {ReadonlyQuat2} a the dual quat to scale
    * @param {Number} b amount to scale the dual quat by
    * @returns {quat2} out
    * @function
    */
 
-  function scale$7(out, a, b) {
+  function scale$1(out, a, b) {
     out[0] = a[0] * b;
     out[1] = a[1] * b;
     out[2] = a[2] * b;
@@ -6688,27 +6943,27 @@ THE SOFTWARE.
   /**
    * Calculates the dot product of two dual quat's (The dot product of the real parts)
    *
-   * @param {quat2} a the first operand
-   * @param {quat2} b the second operand
+   * @param {ReadonlyQuat2} a the first operand
+   * @param {ReadonlyQuat2} b the second operand
    * @returns {Number} dot product of a and b
    * @function
    */
 
-  var dot$3 = dot$2;
+  var dot$1 = dot$2;
   /**
    * Performs a linear interpolation between two dual quats's
    * NOTE: The resulting dual quaternions won't always be normalized (The error is most noticeable when t = 0.5)
    *
    * @param {quat2} out the receiving dual quat
-   * @param {quat2} a the first operand
-   * @param {quat2} b the second operand
+   * @param {ReadonlyQuat2} a the first operand
+   * @param {ReadonlyQuat2} b the second operand
    * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
    * @returns {quat2} out
    */
 
-  function lerp$3(out, a, b, t) {
+  function lerp$1(out, a, b, t) {
     var mt = 1 - t;
-    if (dot$3(a, b) < 0) t = -t;
+    if (dot$1(a, b) < 0) t = -t;
     out[0] = a[0] * mt + b[0] * t;
     out[1] = a[1] * mt + b[1] * t;
     out[2] = a[2] * mt + b[2] * t;
@@ -6723,12 +6978,12 @@ THE SOFTWARE.
    * Calculates the inverse of a dual quat. If they are normalized, conjugate is cheaper
    *
    * @param {quat2} out the receiving dual quaternion
-   * @param {quat2} a dual quat to calculate inverse of
+   * @param {ReadonlyQuat2} a dual quat to calculate inverse of
    * @returns {quat2} out
    */
 
-  function invert$5(out, a) {
-    var sqlen = squaredLength$3(a);
+  function invert(out, a) {
+    var sqlen = squaredLength$1(a);
     out[0] = -a[0] / sqlen;
     out[1] = -a[1] / sqlen;
     out[2] = -a[2] / sqlen;
@@ -6744,11 +6999,11 @@ THE SOFTWARE.
    * If the dual quaternion is normalized, this function is faster than quat2.inverse and produces the same result.
    *
    * @param {quat2} out the receiving quaternion
-   * @param {quat2} a quat to calculate conjugate of
+   * @param {ReadonlyQuat2} a quat to calculate conjugate of
    * @returns {quat2} out
    */
 
-  function conjugate$1(out, a) {
+  function conjugate(out, a) {
     out[0] = -a[0];
     out[1] = -a[1];
     out[2] = -a[2];
@@ -6762,44 +7017,44 @@ THE SOFTWARE.
   /**
    * Calculates the length of a dual quat
    *
-   * @param {quat2} a dual quat to calculate length of
+   * @param {ReadonlyQuat2} a dual quat to calculate length of
    * @returns {Number} length of a
    * @function
    */
 
-  var length$3 = length$2;
+  var length$1 = length$2;
   /**
    * Alias for {@link quat2.length}
    * @function
    */
 
-  var len$3 = length$3;
+  var len$1 = length$1;
   /**
    * Calculates the squared length of a dual quat
    *
-   * @param {quat2} a dual quat to calculate squared length of
+   * @param {ReadonlyQuat2} a dual quat to calculate squared length of
    * @returns {Number} squared length of a
    * @function
    */
 
-  var squaredLength$3 = squaredLength$2;
+  var squaredLength$1 = squaredLength$2;
   /**
    * Alias for {@link quat2.squaredLength}
    * @function
    */
 
-  var sqrLen$3 = squaredLength$3;
+  var sqrLen$1 = squaredLength$1;
   /**
    * Normalize a dual quat
    *
    * @param {quat2} out the receiving dual quaternion
-   * @param {quat2} a dual quaternion to normalize
+   * @param {ReadonlyQuat2} a dual quaternion to normalize
    * @returns {quat2} out
    * @function
    */
 
-  function normalize$3(out, a) {
-    var magnitude = squaredLength$3(a);
+  function normalize$1(out, a) {
+    var magnitude = squaredLength$1(a);
 
     if (magnitude > 0) {
       magnitude = Math.sqrt(magnitude);
@@ -6825,35 +7080,35 @@ THE SOFTWARE.
     return out;
   }
   /**
-   * Returns a string representation of a dual quatenion
+   * Returns a string representation of a dual quaternion
    *
-   * @param {quat2} a dual quaternion to represent as a string
+   * @param {ReadonlyQuat2} a dual quaternion to represent as a string
    * @returns {String} string representation of the dual quat
    */
 
-  function str$7(a) {
-    return 'quat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ')';
+  function str$1(a) {
+    return "quat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ")";
   }
   /**
    * Returns whether or not the dual quaternions have exactly the same elements in the same position (when compared with ===)
    *
-   * @param {quat2} a the first dual quaternion.
-   * @param {quat2} b the second dual quaternion.
+   * @param {ReadonlyQuat2} a the first dual quaternion.
+   * @param {ReadonlyQuat2} b the second dual quaternion.
    * @returns {Boolean} true if the dual quaternions are equal, false otherwise.
    */
 
-  function exactEquals$7(a, b) {
+  function exactEquals$1(a, b) {
     return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7];
   }
   /**
    * Returns whether or not the dual quaternions have approximately the same elements in the same position.
    *
-   * @param {quat2} a the first dual quat.
-   * @param {quat2} b the second dual quat.
+   * @param {ReadonlyQuat2} a the first dual quat.
+   * @param {ReadonlyQuat2} b the second dual quat.
    * @returns {Boolean} true if the dual quats are equal, false otherwise.
    */
 
-  function equals$8(a, b) {
+  function equals$1(a, b) {
     var a0 = a[0],
         a1 = a[1],
         a2 = a[2],
@@ -6874,45 +7129,46 @@ THE SOFTWARE.
   }
 
   var quat2 = /*#__PURE__*/Object.freeze({
-    create: create$7,
-    clone: clone$7,
-    fromValues: fromValues$7,
+    __proto__: null,
+    create: create$1,
+    clone: clone$1,
+    fromValues: fromValues$1,
     fromRotationTranslationValues: fromRotationTranslationValues,
-    fromRotationTranslation: fromRotationTranslation$1,
-    fromTranslation: fromTranslation$3,
-    fromRotation: fromRotation$4,
-    fromMat4: fromMat4$1,
-    copy: copy$7,
-    identity: identity$5,
-    set: set$7,
+    fromRotationTranslation: fromRotationTranslation,
+    fromTranslation: fromTranslation,
+    fromRotation: fromRotation,
+    fromMat4: fromMat4,
+    copy: copy$1,
+    identity: identity,
+    set: set$1,
     getReal: getReal,
     getDual: getDual,
     setReal: setReal,
     setDual: setDual,
-    getTranslation: getTranslation$1,
-    translate: translate$3,
-    rotateX: rotateX$3,
-    rotateY: rotateY$3,
-    rotateZ: rotateZ$3,
+    getTranslation: getTranslation,
+    translate: translate,
+    rotateX: rotateX,
+    rotateY: rotateY,
+    rotateZ: rotateZ,
     rotateByQuatAppend: rotateByQuatAppend,
     rotateByQuatPrepend: rotateByQuatPrepend,
     rotateAroundAxis: rotateAroundAxis,
-    add: add$7,
-    multiply: multiply$7,
-    mul: mul$7,
-    scale: scale$7,
-    dot: dot$3,
-    lerp: lerp$3,
-    invert: invert$5,
-    conjugate: conjugate$1,
-    length: length$3,
-    len: len$3,
-    squaredLength: squaredLength$3,
-    sqrLen: sqrLen$3,
-    normalize: normalize$3,
-    str: str$7,
-    exactEquals: exactEquals$7,
-    equals: equals$8
+    add: add$1,
+    multiply: multiply$1,
+    mul: mul$1,
+    scale: scale$1,
+    dot: dot$1,
+    lerp: lerp$1,
+    invert: invert,
+    conjugate: conjugate,
+    length: length$1,
+    len: len$1,
+    squaredLength: squaredLength$1,
+    sqrLen: sqrLen$1,
+    normalize: normalize$1,
+    str: str$1,
+    exactEquals: exactEquals$1,
+    equals: equals$1
   });
 
   /**
@@ -6926,7 +7182,7 @@ THE SOFTWARE.
    * @returns {vec2} a new 2D vector
    */
 
-  function create$8() {
+  function create() {
     var out = new ARRAY_TYPE(2);
 
     if (ARRAY_TYPE != Float32Array) {
@@ -6939,11 +7195,11 @@ THE SOFTWARE.
   /**
    * Creates a new vec2 initialized with values from an existing vector
    *
-   * @param {vec2} a vector to clone
+   * @param {ReadonlyVec2} a vector to clone
    * @returns {vec2} a new 2D vector
    */
 
-  function clone$8(a) {
+  function clone(a) {
     var out = new ARRAY_TYPE(2);
     out[0] = a[0];
     out[1] = a[1];
@@ -6957,7 +7213,7 @@ THE SOFTWARE.
    * @returns {vec2} a new 2D vector
    */
 
-  function fromValues$8(x, y) {
+  function fromValues(x, y) {
     var out = new ARRAY_TYPE(2);
     out[0] = x;
     out[1] = y;
@@ -6967,11 +7223,11 @@ THE SOFTWARE.
    * Copy the values from one vec2 to another
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the source vector
+   * @param {ReadonlyVec2} a the source vector
    * @returns {vec2} out
    */
 
-  function copy$8(out, a) {
+  function copy(out, a) {
     out[0] = a[0];
     out[1] = a[1];
     return out;
@@ -6985,7 +7241,7 @@ THE SOFTWARE.
    * @returns {vec2} out
    */
 
-  function set$8(out, x, y) {
+  function set(out, x, y) {
     out[0] = x;
     out[1] = y;
     return out;
@@ -6994,12 +7250,12 @@ THE SOFTWARE.
    * Adds two vec2's
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the first operand
-   * @param {vec2} b the second operand
+   * @param {ReadonlyVec2} a the first operand
+   * @param {ReadonlyVec2} b the second operand
    * @returns {vec2} out
    */
 
-  function add$8(out, a, b) {
+  function add(out, a, b) {
     out[0] = a[0] + b[0];
     out[1] = a[1] + b[1];
     return out;
@@ -7008,12 +7264,12 @@ THE SOFTWARE.
    * Subtracts vector b from vector a
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the first operand
-   * @param {vec2} b the second operand
+   * @param {ReadonlyVec2} a the first operand
+   * @param {ReadonlyVec2} b the second operand
    * @returns {vec2} out
    */
 
-  function subtract$6(out, a, b) {
+  function subtract(out, a, b) {
     out[0] = a[0] - b[0];
     out[1] = a[1] - b[1];
     return out;
@@ -7022,12 +7278,12 @@ THE SOFTWARE.
    * Multiplies two vec2's
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the first operand
-   * @param {vec2} b the second operand
+   * @param {ReadonlyVec2} a the first operand
+   * @param {ReadonlyVec2} b the second operand
    * @returns {vec2} out
    */
 
-  function multiply$8(out, a, b) {
+  function multiply(out, a, b) {
     out[0] = a[0] * b[0];
     out[1] = a[1] * b[1];
     return out;
@@ -7036,12 +7292,12 @@ THE SOFTWARE.
    * Divides two vec2's
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the first operand
-   * @param {vec2} b the second operand
+   * @param {ReadonlyVec2} a the first operand
+   * @param {ReadonlyVec2} b the second operand
    * @returns {vec2} out
    */
 
-  function divide$2(out, a, b) {
+  function divide(out, a, b) {
     out[0] = a[0] / b[0];
     out[1] = a[1] / b[1];
     return out;
@@ -7050,11 +7306,11 @@ THE SOFTWARE.
    * Math.ceil the components of a vec2
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a vector to ceil
+   * @param {ReadonlyVec2} a vector to ceil
    * @returns {vec2} out
    */
 
-  function ceil$2(out, a) {
+  function ceil(out, a) {
     out[0] = Math.ceil(a[0]);
     out[1] = Math.ceil(a[1]);
     return out;
@@ -7063,11 +7319,11 @@ THE SOFTWARE.
    * Math.floor the components of a vec2
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a vector to floor
+   * @param {ReadonlyVec2} a vector to floor
    * @returns {vec2} out
    */
 
-  function floor$2(out, a) {
+  function floor(out, a) {
     out[0] = Math.floor(a[0]);
     out[1] = Math.floor(a[1]);
     return out;
@@ -7076,12 +7332,12 @@ THE SOFTWARE.
    * Returns the minimum of two vec2's
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the first operand
-   * @param {vec2} b the second operand
+   * @param {ReadonlyVec2} a the first operand
+   * @param {ReadonlyVec2} b the second operand
    * @returns {vec2} out
    */
 
-  function min$2(out, a, b) {
+  function min(out, a, b) {
     out[0] = Math.min(a[0], b[0]);
     out[1] = Math.min(a[1], b[1]);
     return out;
@@ -7090,12 +7346,12 @@ THE SOFTWARE.
    * Returns the maximum of two vec2's
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the first operand
-   * @param {vec2} b the second operand
+   * @param {ReadonlyVec2} a the first operand
+   * @param {ReadonlyVec2} b the second operand
    * @returns {vec2} out
    */
 
-  function max$2(out, a, b) {
+  function max(out, a, b) {
     out[0] = Math.max(a[0], b[0]);
     out[1] = Math.max(a[1], b[1]);
     return out;
@@ -7104,11 +7360,11 @@ THE SOFTWARE.
    * Math.round the components of a vec2
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a vector to round
+   * @param {ReadonlyVec2} a vector to round
    * @returns {vec2} out
    */
 
-  function round$2(out, a) {
+  function round(out, a) {
     out[0] = Math.round(a[0]);
     out[1] = Math.round(a[1]);
     return out;
@@ -7117,12 +7373,12 @@ THE SOFTWARE.
    * Scales a vec2 by a scalar number
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the vector to scale
+   * @param {ReadonlyVec2} a the vector to scale
    * @param {Number} b amount to scale the vector by
    * @returns {vec2} out
    */
 
-  function scale$8(out, a, b) {
+  function scale(out, a, b) {
     out[0] = a[0] * b;
     out[1] = a[1] * b;
     return out;
@@ -7131,13 +7387,13 @@ THE SOFTWARE.
    * Adds two vec2's after scaling the second operand by a scalar value
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the first operand
-   * @param {vec2} b the second operand
+   * @param {ReadonlyVec2} a the first operand
+   * @param {ReadonlyVec2} b the second operand
    * @param {Number} scale the amount to scale b by before adding
    * @returns {vec2} out
    */
 
-  function scaleAndAdd$2(out, a, b, scale) {
+  function scaleAndAdd(out, a, b, scale) {
     out[0] = a[0] + b[0] * scale;
     out[1] = a[1] + b[1] * scale;
     return out;
@@ -7145,12 +7401,12 @@ THE SOFTWARE.
   /**
    * Calculates the euclidian distance between two vec2's
    *
-   * @param {vec2} a the first operand
-   * @param {vec2} b the second operand
+   * @param {ReadonlyVec2} a the first operand
+   * @param {ReadonlyVec2} b the second operand
    * @returns {Number} distance between a and b
    */
 
-  function distance$2(a, b) {
+  function distance(a, b) {
     var x = b[0] - a[0],
         y = b[1] - a[1];
     return Math.hypot(x, y);
@@ -7158,12 +7414,12 @@ THE SOFTWARE.
   /**
    * Calculates the squared euclidian distance between two vec2's
    *
-   * @param {vec2} a the first operand
-   * @param {vec2} b the second operand
+   * @param {ReadonlyVec2} a the first operand
+   * @param {ReadonlyVec2} b the second operand
    * @returns {Number} squared distance between a and b
    */
 
-  function squaredDistance$2(a, b) {
+  function squaredDistance(a, b) {
     var x = b[0] - a[0],
         y = b[1] - a[1];
     return x * x + y * y;
@@ -7171,11 +7427,11 @@ THE SOFTWARE.
   /**
    * Calculates the length of a vec2
    *
-   * @param {vec2} a vector to calculate length of
+   * @param {ReadonlyVec2} a vector to calculate length of
    * @returns {Number} length of a
    */
 
-  function length$4(a) {
+  function length(a) {
     var x = a[0],
         y = a[1];
     return Math.hypot(x, y);
@@ -7183,11 +7439,11 @@ THE SOFTWARE.
   /**
    * Calculates the squared length of a vec2
    *
-   * @param {vec2} a vector to calculate squared length of
+   * @param {ReadonlyVec2} a vector to calculate squared length of
    * @returns {Number} squared length of a
    */
 
-  function squaredLength$4(a) {
+  function squaredLength(a) {
     var x = a[0],
         y = a[1];
     return x * x + y * y;
@@ -7196,11 +7452,11 @@ THE SOFTWARE.
    * Negates the components of a vec2
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a vector to negate
+   * @param {ReadonlyVec2} a vector to negate
    * @returns {vec2} out
    */
 
-  function negate$2(out, a) {
+  function negate(out, a) {
     out[0] = -a[0];
     out[1] = -a[1];
     return out;
@@ -7209,11 +7465,11 @@ THE SOFTWARE.
    * Returns the inverse of the components of a vec2
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a vector to invert
+   * @param {ReadonlyVec2} a vector to invert
    * @returns {vec2} out
    */
 
-  function inverse$2(out, a) {
+  function inverse(out, a) {
     out[0] = 1.0 / a[0];
     out[1] = 1.0 / a[1];
     return out;
@@ -7222,11 +7478,11 @@ THE SOFTWARE.
    * Normalize a vec2
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a vector to normalize
+   * @param {ReadonlyVec2} a vector to normalize
    * @returns {vec2} out
    */
 
-  function normalize$4(out, a) {
+  function normalize(out, a) {
     var x = a[0],
         y = a[1];
     var len = x * x + y * y;
@@ -7243,12 +7499,12 @@ THE SOFTWARE.
   /**
    * Calculates the dot product of two vec2's
    *
-   * @param {vec2} a the first operand
-   * @param {vec2} b the second operand
+   * @param {ReadonlyVec2} a the first operand
+   * @param {ReadonlyVec2} b the second operand
    * @returns {Number} dot product of a and b
    */
 
-  function dot$4(a, b) {
+  function dot(a, b) {
     return a[0] * b[0] + a[1] * b[1];
   }
   /**
@@ -7256,12 +7512,12 @@ THE SOFTWARE.
    * Note that the cross product must by definition produce a 3D vector
    *
    * @param {vec3} out the receiving vector
-   * @param {vec2} a the first operand
-   * @param {vec2} b the second operand
+   * @param {ReadonlyVec2} a the first operand
+   * @param {ReadonlyVec2} b the second operand
    * @returns {vec3} out
    */
 
-  function cross$2(out, a, b) {
+  function cross(out, a, b) {
     var z = a[0] * b[1] - a[1] * b[0];
     out[0] = out[1] = 0;
     out[2] = z;
@@ -7271,13 +7527,13 @@ THE SOFTWARE.
    * Performs a linear interpolation between two vec2's
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the first operand
-   * @param {vec2} b the second operand
+   * @param {ReadonlyVec2} a the first operand
+   * @param {ReadonlyVec2} b the second operand
    * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
    * @returns {vec2} out
    */
 
-  function lerp$4(out, a, b, t) {
+  function lerp(out, a, b, t) {
     var ax = a[0],
         ay = a[1];
     out[0] = ax + t * (b[0] - ax);
@@ -7288,12 +7544,12 @@ THE SOFTWARE.
    * Generates a random vector with the given scale
    *
    * @param {vec2} out the receiving vector
-   * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
+   * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned
    * @returns {vec2} out
    */
 
-  function random$3(out, scale) {
-    scale = scale || 1.0;
+  function random(out, scale) {
+    scale = scale === undefined ? 1.0 : scale;
     var r = RANDOM() * 2.0 * Math.PI;
     out[0] = Math.cos(r) * scale;
     out[1] = Math.sin(r) * scale;
@@ -7303,8 +7559,8 @@ THE SOFTWARE.
    * Transforms the vec2 with a mat2
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the vector to transform
-   * @param {mat2} m matrix to transform with
+   * @param {ReadonlyVec2} a the vector to transform
+   * @param {ReadonlyMat2} m matrix to transform with
    * @returns {vec2} out
    */
 
@@ -7319,8 +7575,8 @@ THE SOFTWARE.
    * Transforms the vec2 with a mat2d
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the vector to transform
-   * @param {mat2d} m matrix to transform with
+   * @param {ReadonlyVec2} a the vector to transform
+   * @param {ReadonlyMat2d} m matrix to transform with
    * @returns {vec2} out
    */
 
@@ -7336,12 +7592,12 @@ THE SOFTWARE.
    * 3rd vector component is implicitly '1'
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the vector to transform
-   * @param {mat3} m matrix to transform with
+   * @param {ReadonlyVec2} a the vector to transform
+   * @param {ReadonlyMat3} m matrix to transform with
    * @returns {vec2} out
    */
 
-  function transformMat3$1(out, a, m) {
+  function transformMat3(out, a, m) {
     var x = a[0],
         y = a[1];
     out[0] = m[0] * x + m[3] * y + m[6];
@@ -7354,12 +7610,12 @@ THE SOFTWARE.
    * 4th vector component is implicitly '1'
    *
    * @param {vec2} out the receiving vector
-   * @param {vec2} a the vector to transform
-   * @param {mat4} m matrix to transform with
+   * @param {ReadonlyVec2} a the vector to transform
+   * @param {ReadonlyMat4} m matrix to transform with
    * @returns {vec2} out
    */
 
-  function transformMat4$2(out, a, m) {
+  function transformMat4(out, a, m) {
     var x = a[0];
     var y = a[1];
     out[0] = m[0] * x + m[4] * y + m[12];
@@ -7369,18 +7625,18 @@ THE SOFTWARE.
   /**
    * Rotate a 2D vector
    * @param {vec2} out The receiving vec2
-   * @param {vec2} a The vec2 point to rotate
-   * @param {vec2} b The origin of the rotation
-   * @param {Number} c The angle of rotation
+   * @param {ReadonlyVec2} a The vec2 point to rotate
+   * @param {ReadonlyVec2} b The origin of the rotation
+   * @param {Number} rad The angle of rotation in radians
    * @returns {vec2} out
    */
 
-  function rotate$4(out, a, b, c) {
+  function rotate(out, a, b, rad) {
     //Translate point to the origin
     var p0 = a[0] - b[0],
         p1 = a[1] - b[1],
-        sinC = Math.sin(c),
-        cosC = Math.cos(c); //perform rotation and translate to correct position
+        sinC = Math.sin(rad),
+        cosC = Math.cos(rad); //perform rotation and translate to correct position
 
     out[0] = p0 * cosC - p1 * sinC + b[0];
     out[1] = p0 * sinC + p1 * cosC + b[1];
@@ -7388,39 +7644,22 @@ THE SOFTWARE.
   }
   /**
    * Get the angle between two 2D vectors
-   * @param {vec2} a The first operand
-   * @param {vec2} b The second operand
+   * @param {ReadonlyVec2} a The first operand
+   * @param {ReadonlyVec2} b The second operand
    * @returns {Number} The angle in radians
    */
 
-  function angle$1(a, b) {
+  function angle(a, b) {
     var x1 = a[0],
         y1 = a[1],
         x2 = b[0],
-        y2 = b[1];
-    var len1 = x1 * x1 + y1 * y1;
+        y2 = b[1],
+        // mag is the product of the magnitudes of a and b
+    mag = Math.sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2)),
+        // mag &&.. short circuits if mag == 0
+    cosine = mag && (x1 * x2 + y1 * y2) / mag; // Math.min(Math.max(cosine, -1), 1) clamps the cosine between -1 and 1
 
-    if (len1 > 0) {
-      //TODO: evaluate use of glm_invsqrt here?
-      len1 = 1 / Math.sqrt(len1);
-    }
-
-    var len2 = x2 * x2 + y2 * y2;
-
-    if (len2 > 0) {
-      //TODO: evaluate use of glm_invsqrt here?
-      len2 = 1 / Math.sqrt(len2);
-    }
-
-    var cosine = (x1 * x2 + y1 * y2) * len1 * len2;
-
-    if (cosine > 1.0) {
-      return 0;
-    } else if (cosine < -1.0) {
-      return Math.PI;
-    } else {
-      return Math.acos(cosine);
-    }
+    return Math.acos(Math.min(Math.max(cosine, -1), 1));
   }
   /**
    * Set the components of a vec2 to zero
@@ -7429,7 +7668,7 @@ THE SOFTWARE.
    * @returns {vec2} out
    */
 
-  function zero$2(out) {
+  function zero(out) {
     out[0] = 0.0;
     out[1] = 0.0;
     return out;
@@ -7437,33 +7676,33 @@ THE SOFTWARE.
   /**
    * Returns a string representation of a vector
    *
-   * @param {vec2} a vector to represent as a string
+   * @param {ReadonlyVec2} a vector to represent as a string
    * @returns {String} string representation of the vector
    */
 
-  function str$8(a) {
-    return 'vec2(' + a[0] + ', ' + a[1] + ')';
+  function str(a) {
+    return "vec2(" + a[0] + ", " + a[1] + ")";
   }
   /**
    * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===)
    *
-   * @param {vec2} a The first vector.
-   * @param {vec2} b The second vector.
+   * @param {ReadonlyVec2} a The first vector.
+   * @param {ReadonlyVec2} b The second vector.
    * @returns {Boolean} True if the vectors are equal, false otherwise.
    */
 
-  function exactEquals$8(a, b) {
+  function exactEquals(a, b) {
     return a[0] === b[0] && a[1] === b[1];
   }
   /**
    * Returns whether or not the vectors have approximately the same elements in the same position.
    *
-   * @param {vec2} a The first vector.
-   * @param {vec2} b The second vector.
+   * @param {ReadonlyVec2} a The first vector.
+   * @param {ReadonlyVec2} b The second vector.
    * @returns {Boolean} True if the vectors are equal, false otherwise.
    */
 
-  function equals$9(a, b) {
+  function equals(a, b) {
     var a0 = a[0],
         a1 = a[1];
     var b0 = b[0],
@@ -7475,43 +7714,43 @@ THE SOFTWARE.
    * @function
    */
 
-  var len$4 = length$4;
+  var len = length;
   /**
    * Alias for {@link vec2.subtract}
    * @function
    */
 
-  var sub$6 = subtract$6;
+  var sub = subtract;
   /**
    * Alias for {@link vec2.multiply}
    * @function
    */
 
-  var mul$8 = multiply$8;
+  var mul = multiply;
   /**
    * Alias for {@link vec2.divide}
    * @function
    */
 
-  var div$2 = divide$2;
+  var div = divide;
   /**
    * Alias for {@link vec2.distance}
    * @function
    */
 
-  var dist$2 = distance$2;
+  var dist = distance;
   /**
    * Alias for {@link vec2.squaredDistance}
    * @function
    */
 
-  var sqrDist$2 = squaredDistance$2;
+  var sqrDist = squaredDistance;
   /**
    * Alias for {@link vec2.squaredLength}
    * @function
    */
 
-  var sqrLen$4 = squaredLength$4;
+  var sqrLen = squaredLength;
   /**
    * Perform some operation over an array of vec2s.
    *
@@ -7525,8 +7764,8 @@ THE SOFTWARE.
    * @function
    */
 
-  var forEach$2 = function () {
-    var vec = create$8();
+  var forEach = function () {
+    var vec = create();
     return function (a, stride, offset, count, fn, arg) {
       var i, l;
 
@@ -7557,51 +7796,52 @@ THE SOFTWARE.
   }();
 
   var vec2 = /*#__PURE__*/Object.freeze({
-    create: create$8,
-    clone: clone$8,
-    fromValues: fromValues$8,
-    copy: copy$8,
-    set: set$8,
-    add: add$8,
-    subtract: subtract$6,
-    multiply: multiply$8,
-    divide: divide$2,
-    ceil: ceil$2,
-    floor: floor$2,
-    min: min$2,
-    max: max$2,
-    round: round$2,
-    scale: scale$8,
-    scaleAndAdd: scaleAndAdd$2,
-    distance: distance$2,
-    squaredDistance: squaredDistance$2,
-    length: length$4,
-    squaredLength: squaredLength$4,
-    negate: negate$2,
-    inverse: inverse$2,
-    normalize: normalize$4,
-    dot: dot$4,
-    cross: cross$2,
-    lerp: lerp$4,
-    random: random$3,
+    __proto__: null,
+    create: create,
+    clone: clone,
+    fromValues: fromValues,
+    copy: copy,
+    set: set,
+    add: add,
+    subtract: subtract,
+    multiply: multiply,
+    divide: divide,
+    ceil: ceil,
+    floor: floor,
+    min: min,
+    max: max,
+    round: round,
+    scale: scale,
+    scaleAndAdd: scaleAndAdd,
+    distance: distance,
+    squaredDistance: squaredDistance,
+    length: length,
+    squaredLength: squaredLength,
+    negate: negate,
+    inverse: inverse,
+    normalize: normalize,
+    dot: dot,
+    cross: cross,
+    lerp: lerp,
+    random: random,
     transformMat2: transformMat2,
     transformMat2d: transformMat2d,
-    transformMat3: transformMat3$1,
-    transformMat4: transformMat4$2,
-    rotate: rotate$4,
-    angle: angle$1,
-    zero: zero$2,
-    str: str$8,
-    exactEquals: exactEquals$8,
-    equals: equals$9,
-    len: len$4,
-    sub: sub$6,
-    mul: mul$8,
-    div: div$2,
-    dist: dist$2,
-    sqrDist: sqrDist$2,
-    sqrLen: sqrLen$4,
-    forEach: forEach$2
+    transformMat3: transformMat3,
+    transformMat4: transformMat4,
+    rotate: rotate,
+    angle: angle,
+    zero: zero,
+    str: str,
+    exactEquals: exactEquals,
+    equals: equals,
+    len: len,
+    sub: sub,
+    mul: mul,
+    div: div,
+    dist: dist,
+    sqrDist: sqrDist,
+    sqrLen: sqrLen,
+    forEach: forEach
   });
 
   exports.glMatrix = common;