diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml new file mode 100644 index 0000000..660edaf --- /dev/null +++ b/.github/workflows/build-and-deploy.yml @@ -0,0 +1,34 @@ +name: Build and Deploy +on: + push: + tags: + - v* +permissions: + contents: write +jobs: + build-and-deploy: + runs-on: ubuntu-latest + environment: deploy + steps: + - name: Checkout 🛎️ + uses: actions/checkout@v3 + + - name: Use Node.js 😂 + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install and Build 🔧 + run: | + npm ci + npm run build-ci + + - name: Deploy 🚀 + uses: JamesIves/github-pages-deploy-action@v4 + with: + folder: . + + - name: Publish to NPM 📖 + uses: JS-DevTools/npm-publish@v2 + with: + token: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index e9d30d7..07905bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,26 @@ + +# -- clip-for-deploy-start -- + +/docs +/dist +index.html + +# -- clip-for-deploy-end -- + + +/.pnp +.pnp.js + *.pyc .DS_Store node_modules +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + + diff --git a/build/templates/index.template b/build/templates/index.template new file mode 100644 index 0000000..4dbb864 --- /dev/null +++ b/build/templates/index.template @@ -0,0 +1,113 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + +Generated using TypeDoc
Generated using TypeDoc
Create a Mat3 from values
-Note: Since passing in a raw JavaScript array -is valid in all circumstances, if you want to -force a JavaScript array into a Mat3's specified type -it would be faster to use
-const m = mat3.clone(someJSArray);
-
-Note: a consequence of the implementation is if your Mat3Type = Array
-instead of Float32Array
or Float64Array
then any values you
-don't pass in will be undefined. Usually this is not an issue since
-(a) using Array
is rare and (b) using mat3.create
is usually used
-to create a Mat3 to be filled out as in
const m = mat3.create();
mat3.perspective(fov, aspect, near, far, m);
-
-
-matrix created from values.
-Optional
v0: numbervalue for element 0
-Optional
v1: numbervalue for element 1
-Optional
v2: numbervalue for element 2
-Optional
v3: numbervalue for element 3
-Optional
v4: numbervalue for element 4
-Optional
v5: numbervalue for element 5
-Optional
v6: numbervalue for element 6
-Optional
v7: numbervalue for element 7
-Optional
v8: numbervalue for element 8
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Creates a 3-by-3 matrix which rotates by the given angle.
- -The rotation matrix.
-The angle by which to rotate (in radians).
-Optional
dst: Mat3matrix to hold result. If not passed a new one is created.
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
value for element 0
-value for element 1
-value for element 2
-value for element 3
-value for element 4
-value for element 5
-value for element 6
-value for element 7
-value for element 8
-Optional
dst: Mat3matrix to hold result. If not passed a new one is created.
-Generated using TypeDoc
Generated using TypeDoc
Sets the type this library creates for a Mat3
- -previous constructor for Mat3
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Computes a 4-by-4 aim transformation.
-This is a matrix which positions an object aiming down positive Z. -toward the target.
-Note: this is NOT the inverse of lookAt as lookAt looks at negative Z.
- -The aim matrix.
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Create a Mat4 from values
-Note: Since passing in a raw JavaScript array -is valid in all circumstances, if you want to -force a JavaScript array into a Mat4's specified type -it would be faster to use
-const m = mat4.clone(someJSArray);
-
-Note: a consequence of the implementation is if your Mat4Type = Array
-instead of Float32Array
or Float64Array
then any values you
-don't pass in will be undefined. Usually this is not an issue since
-(a) using Array
is rare and (b) using mat4.create
is usually used
-to create a Mat4 to be filled out as in
const m = mat4.create();
mat4.perspective(fov, aspect, near, far, m);
-
-
-created from values.
-Optional
v0: numbervalue for element 0
-Optional
v1: numbervalue for element 1
-Optional
v2: numbervalue for element 2
-Optional
v3: numbervalue for element 3
-Optional
v4: numbervalue for element 4
-Optional
v5: numbervalue for element 5
-Optional
v6: numbervalue for element 6
-Optional
v7: numbervalue for element 7
-Optional
v8: numbervalue for element 8
-Optional
v9: numbervalue for element 9
-Optional
v10: numbervalue for element 10
-Optional
v11: numbervalue for element 11
-Optional
v12: numbervalue for element 12
-Optional
v13: numbervalue for element 13
-Optional
v14: numbervalue for element 14
-Optional
v15: numbervalue for element 15
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Computes a 4-by-4 perspective transformation matrix given the left, right, -top, bottom, near and far clipping planes. The arguments define a frustum -extending in the negative z direction. The arguments near and far are the -distances to the near and far clipping planes. Note that near and far are not -z coordinates, but rather they are distances along the negative z-axis. The -matrix generated sends the viewing frustum to the unit box. We assume a unit -box extending from -1 to 1 in the x and y dimensions and from 0 to 1 in the z -dimension.
- -The perspective projection matrix.
-The x coordinate of the left plane of the box.
-The x coordinate of the right plane of the box.
-The y coordinate of the bottom plane of the box.
-The y coordinate of the right plane of the box.
-The negative z coordinate of the near plane of the box.
-The negative z coordinate of the far plane of the box.
-Optional
dst: Mat4Output matrix. If not passed a new one is created.
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Computes a 4-by-4 orthogonal transformation matrix that transforms from -the given the left, right, bottom, and top dimensions to -1 +1 in x, and y -and 0 to +1 in z.
- -The orthographic projection matrix.
-Left side of the near clipping plane viewport.
-Right side of the near clipping plane viewport.
-Bottom of the near clipping plane viewport.
-Top of the near clipping plane viewport.
-The depth (negative z coordinate) - of the near clipping plane.
-The depth (negative z coordinate) - of the far clipping plane.
-Optional
dst: Mat4Output matrix. If not passed a new one is created.
-Generated using TypeDoc
Computes a 4-by-4 perspective transformation matrix given the angular height -of the frustum, the aspect ratio, and the near and far clipping planes. The -arguments define a frustum extending in the negative z direction. The given -angle is the vertical angle of the frustum, and the horizontal angle is -determined to produce the given aspect ratio. The arguments near and far are -the distances to the near and far clipping planes. Note that near and far -are not z coordinates, but rather they are distances along the negative -z-axis. The matrix generated sends the viewing frustum to the unit box. -We assume a unit box extending from -1 to 1 in the x and y dimensions and -from 0 to 1 in the z dimension.
-Note: If you pass Infinity
for zFar then it will produce a projection matrix
-returns -Infinity for Z when transforming coordinates with Z <= 0 and +Infinity for Z
-otherwise.
The perspective matrix.
-The camera angle from top to bottom (in radians).
-The aspect ratio width / height.
-The depth (negative z coordinate) - of the near clipping plane.
-The depth (negative z coordinate) - of the far clipping plane.
-Optional
dst: Mat4matrix to hold result. If not passed a new one is created.
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Creates a 4-by-4 matrix which rotates around the x-axis by the given angle.
- -The rotation matrix.
-The angle by which to rotate (in radians).
-Optional
dst: Mat4matrix to hold result. If not passed a new one is created.
-Generated using TypeDoc
Creates a 4-by-4 matrix which rotates around the y-axis by the given angle.
- -The rotation matrix.
-The angle by which to rotate (in radians).
-Optional
dst: Mat4matrix to hold result. If not passed a new one is created.
-Generated using TypeDoc
Creates a 4-by-4 matrix which rotates around the z-axis by the given angle.
- -The rotation matrix.
-The angle by which to rotate (in radians).
-Optional
dst: Mat4matrix to hold result. If not passed a new one is created.
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
value for element 0
-value for element 1
-value for element 2
-value for element 3
-value for element 4
-value for element 5
-value for element 6
-value for element 7
-value for element 8
-value for element 9
-value for element 10
-value for element 11
-value for element 12
-value for element 13
-value for element 14
-value for element 15
-Optional
dst: Mat4matrix to hold result. If not passed a new one is created.
-Generated using TypeDoc
Generated using TypeDoc
Sets the type this library creates for a Mat4
- -previous constructor for Mat4
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Creates a 4-by-4 matrix which scales a uniform amount in each dimension.
- -The scaling matrix.
-the amount to scale
-Optional
dst: Mat4matrix to hold result. If not passed a new one is created.
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Creates a quat4; may be called with x, y, z to set initial values.
- -the created vector
-Optional
x: numberInitial x value.
-Optional
y: numberInitial y value.
-Optional
z: numberInitial z value.
-Optional
w: numberInitial w value.
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Creates a quaternion from the given euler angle x, y, z using the provided intrinsic order for the conversion.
- -A quaternion representing the same rotation as the euler angles applied in the given order
-angle to rotate around X axis in radians.
-angle to rotate around Y axis in radians.
-angle to rotate around Z axis in radians.
-order to apply euler angles
-Optional
dst: Quatquaternion to hold result. If not passed in a new one is created.
-Generated using TypeDoc
Creates a quaternion from the given rotation matrix.
-The created quaternion is not normalized.
- -the result
-rotation matrix
-Optional
dst: Quatquaternion to hold result. If not passed in a new one is created.
-Generated using TypeDoc
Creates a Quat; may be called with x, y, z to set initial values. (same as create)
- -the created vector
-Optional
x: numberInitial x value.
-Optional
y: numberInitial y value.
-Optional
z: numberInitial z value.
-Optional
w: numberGenerated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
first value
-second value
-third value
-fourth value
-Optional
dst: Quatvector to hold result. If not passed in a new one is created.
-Generated using TypeDoc
Sets the type this library creates for a Quat4
- -previous constructor for Quat4
-Quat4 math functions.
-Almost all functions take an optional dst
argument. If it is not passed in the
-functions will create a new Quat4
. In other words you can do this
const v = quat4.cross(v1, v2); // Creates a new Quat4 with the cross product of v1 x v2.
-
-or
-const v = quat4.create();
quat4.cross(v1, v2, v); // Puts the cross product of v1 x v2 in v
-
-The first style is often easier but depending on where it's used it generates garbage where -as there is almost never allocation with the second style.
-It is always safe to pass any vector as the destination. So for example
-quat4.cross(v1, v2, v1); // Puts the cross product of v1 x v2 in v1
-
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Sets the type this library creates for all types
-example:
-setDefaultType(Float64Array);
-
-the constructor for the type. Either Float32Array
, Float64Array
, or Array
Generated using TypeDoc
Generated using TypeDoc
Compute the euclidean modulo
-// table for n / 3
-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 <- n
------------------------------------
-2 -1 -0 -2 -1 0, 1, 2, 0, 1, 2 <- n % 3
1 2 0 1 2 0, 1, 2, 0, 1, 2 <- euclideanModule(n, 3)
-
-
-the euclidean modulo of n / m
-dividend
-divisor
-Generated using TypeDoc
Compute the opposite of lerp. Given a and b and a value between -a and b returns a value between 0 and 1. 0 if a, 1 if b. -Note: no clamping is done.
- -(v - a) / (b - a)
-start value
-end value
-value between a and b
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Creates a Vec2; may be called with x, y, z to set initial values.
-Note: Since passing in a raw JavaScript array -is valid in all circumstances, if you want to -force a JavaScript array into a Vec2's specified type -it would be faster to use
-const v = vec2.clone(someJSArray);
-
-Note: a consequence of the implementation is if your Vec2Type = Array
-instead of Float32Array
or Float64Array
then any values you
-don't pass in will be undefined. Usually this is not an issue since
-(a) using Array
is rare and (b) using vec2.create
is usually used
-to create a Vec2 to be filled out as in
const sum = vec2.create();
vec2.add(v1, v2, sum);
-
-
-the created vector
-Initial x value.
-Initial y value.
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Sets the type this library creates for a Vec2
- -previous constructor for Vec2
-Vec2 math functions.
-Almost all functions take an optional dst
argument. If it is not passed in the
-functions will create a new Vec2. In other words you can do this
const v = vec2.cross(v1, v2); // Creates a new Vec2 with the cross product of v1 x v2.
-
-or
-const v = vec2.create();
vec2.cross(v1, v2, v); // Puts the cross product of v1 x v2 in v
-
-The first style is often easier but depending on where it's used it generates garbage where -as there is almost never allocation with the second style.
-It is always safe to pass any vector as the destination. So for example
-vec2.cross(v1, v2, v1); // Puts the cross product of v1 x v2 in v1
-
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Creates a vec3; may be called with x, y, z to set initial values.
- -the created vector
-Optional
x: numberInitial x value.
-Optional
y: numberInitial y value.
-Optional
z: numberInitial z value.
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Creates a vec3; may be called with x, y, z to set initial values. (same as create)
- -the created vector
-Optional
x: numberInitial x value.
-Optional
y: numberInitial y value.
-Optional
z: numberInitial z value.
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Sets the type this library creates for a Vec3
- -previous constructor for Vec3
-Vec3 math functions.
-Almost all functions take an optional dst
argument. If it is not passed in the
-functions will create a new Vec3
. In other words you can do this
const v = vec3.cross(v1, v2); // Creates a new Vec3 with the cross product of v1 x v2.
-
-or
-const v = vec3.create();
vec3.cross(v1, v2, v); // Puts the cross product of v1 x v2 in v
-
-The first style is often easier but depending on where it's used it generates garbage where -as there is almost never allocation with the second style.
-It is always safe to pass any vector as the destination. So for example
-vec3.cross(v1, v2, v1); // Puts the cross product of v1 x v2 in v1
-
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Creates a vec4; may be called with x, y, z to set initial values.
- -the created vector
-Optional
x: numberInitial x value.
-Optional
y: numberInitial y value.
-Optional
z: numberInitial z value.
-Optional
w: numberInitial w value.
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Creates a vec4; may be called with x, y, z to set initial values. (same as create)
- -the created vector
-Optional
x: numberInitial x value.
-Optional
y: numberInitial y value.
-Optional
z: numberInitial z value.
-Optional
w: numberGenerated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
first value
-second value
-third value
-fourth value
-Optional
dst: Vec4vector to hold result. If not passed in a new one is created.
-Generated using TypeDoc
Sets the type this library creates for a Vec4
- -previous constructor for Vec4
-Vec4 math functions.
-Almost all functions take an optional dst
argument. If it is not passed in the
-functions will create a new Vec4
. In other words you can do this
const v = vec4.cross(v1, v2); // Creates a new Vec4 with the cross product of v1 x v2.
-
-or
-const v = vec4.create();
vec4.cross(v1, v2, v); // Puts the cross product of v1 x v2 in v
-
-The first style is often easier but depending on where it's used it generates garbage where -as there is almost never allocation with the second style.
-It is always safe to pass any vector as the destination. So for example
-vec4.cross(v1, v2, v1); // Puts the cross product of v1 x v2 in v1
-
-Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Fast 3d math library for webgpu
- - - -ortho
, perspective
, frustum
are differentcompare
-// wgpu-matrix
const t = mat4.translation([x, y, z]);
const p = mat4.perspective(fov, aspect, near, far);
const r = mat4.rotationX(rad);
-
-// gl-matrix
const t = mat4.create();
mat4.fromTranslation(t, [x, y, z]);
const p = mat4.create();
mat4.perspective(p, fov, aspect, near, far);
const r = mat4.create();
mat4.fromXRotation(r, rad);
-
-note that if you want to pre-create matrices you can still do this in wgpu-matrix
-const t = mat4.create();
mat4.translation([x, y, z], t);
const p = mat4.create();
mat4.perspective(fov, aspect, near, far, p);
const r = mat4.create();
mat4.rotationX(rad, r);
-
-import {
vec3,
mat4,
} from 'https://wgpu-matrix.org/dist/2.x/wgpu-matrix.module.js';
const fov = 60 * Math.PI / 180
const aspect = width / height;
const near = 0.1;
const far = 1000;
const perspective = mat4.perspective(fov, aspect, near, far);
const eye = [3, 5, 10];
const target = [0, 4, 0];
const up = [0, 1, 0];
const view = mat4.lookAt(eye, target, up);
-
-Note: for translation, rotation, and scaling there are 2 versions -of each function. One generates a translation, rotation, or scaling matrix. -The other translates, rotates, or scales a matrix.
-const t = mat4.translation([1, 2, 3]); // a translation matrix
const r = mat4.rotationX(Math.PI * 0.5); // a rotation matrix
const s = mat4.scaling([1, 2, 3]); // a scaling matrix
-
-const m = mat4.identity();
const t = mat4.translate(m, [1, 2, 3]); // m * translation([1, 2, 3])
const r = mat4.rotateX(m, Math.PI * 0.5); // m * rotationX(Math.PI * 0.5)
const s = mat4.scale(m, [1, 2, 3]); // m * scaling([1, 2, 3])
-
-Functions take an optional destination to hold the result.
-const m = mat4.create(); // m = new mat4
mat4.identity(m); // m = identity
mat4.translate(m, [1, 2, 3], m); // m *= translation([1, 2, 3])
mat4.rotateX(m, Math.PI * 0.5, m); // m *= rotationX(Math.PI * 0.5)
mat4.scale(m, [1, 2, 3], m); // m *= scaling([1, 2, 3])
-
-There is also the minified version
-import {
vec3,
mat4,
} from 'https://wgpu-matrix.org/dist/2.x/wgpu-matrix.module.min.js';
// ... etc ...
-
-or via npm
-npm install --save wgpu-matrix
-
-then using a build process
-import {vec3, mat3} from 'wgpu-matrix';
// ... etc ...
-
-
-
-
- mat4.perspective
,
-mat4.ortho
, and
-mat4.frustum
-all return matrices with Z clip space from 0 to 1 (unlike most WebGL matrix libraries which return -1 to 1)
mat4.create
makes an all zero matrix if passed no parameters.
-If you want an identity matrix call mat4.identity
mat3
uses the space of 12 elements
// a mat3
[
xx, xy, xz, ?
yx, yy, yz, ?
zx, zy, zz, ?
]
-
-This is because WebGPU requires mat3s to be in this format and since -this library is for WebGPU it makes sense to match so you can manipulate -mat3s in TypeArrays directly.
-vec3
in this library uses 3 floats per but be aware that an array of
-vec3
in a Uniform Block or other structure in WGSL, each vec3 is
-padded to 4 floats! In other words, if you declare
struct Foo {
bar: vec3<f32>[3];
};
-
-then bar[0] is at byte offset 0, bar[1] at byte offset 16, bar[2] at byte offset 32.
-See the WGSL spec on alignment and size.
- - -WebGPU follows the same conventions as OpenGL, Vulkan, Metal for matrices. Some people call this "column major". The issue is the columns of -a traditional "math" matrix are stored as rows when declaring a matrix in code.
-[
x1, x2, x3, x4, // <- column 0
y1, y2, y3, y4, // <- column 1
z1, z2, z3, z4, // <- column 2
w1, w2, w3, w4, // <- column 3
]
-
-To put it another way, the translation vector is in elements 12, 13, 14
-[
xx, xy, xz, 0, // <- x-axis
yx, yy, yz, 0, // <- y-axis
zx, zy, zz, 0, // <- z-axis
tx, ty, tz, 1, // <- translation
]
-
-This issue has confused programmers since at least the early 90s 😌
- - -Most functions take an optional destination as the last argument. -If you don't supply it, a new one (vector, matrix) will be created -for you.
-// convenient usage
const persp = mat4.perspective(fov, aspect, near, far);
const camera = mat4.lookAt(eye, target, up);
const view = mat4.inverse(camera);
-
-// performant usage
// at init time
const persp = mat4.create();
const camera = mat4.create();
const view = mat4.create();
// at usage time
mat4.perspective(fov, aspect, near, far, persp);
mat4.lookAt(eye, target, up, camera);
mat4.inverse(camera, view);
-
-For me, most of the stuff I do in WebGPU, the supposed performance I might lose -from using the convenient style is so small as to be unmeasurable. I'd prefer to -stay convenient and then, if and only if I find a performance issue, then I -might bother to switch to the performant style.
-As the saying goes premature optimization is the root of all evil. 😉
- - -mat4.lookAt
-changed from a "camera matrix" to a "view matrix" (same as gluLookAt).
-If you want a matrix that orients an something in world space see
-mat4.aim
.
-Sorry about this change but people are used to lookAt making a a view matrix
-and it seemed prudent to make this change now and save more people from
-frustration going forward.git clone https://github.com/greggman/wgpu-matrix.git
cd wgpu-matrix
npm i
npm run build
npm test
-
-You can run tests in the browser by starting a local server
-npx servez
-
-Now go to wherever your server serves pages. In the case of servez
that's
-probably http://localhost:8080/test/.
By default the tests test the minified version. To test the source use src=true
-as in http://localhost:8080/test/?src=true.
To limit which tests are run use grep=<regex>
. For example
-http://localhost:8080/test/?src=true&grep=mat3.*?translate
-runs only tests with mat3
followed by translate
in the name of test.
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
A JavaScript array with 12 values, a Float32Array with 12 values, or a Float64Array with 12 values.
-When created by the library will create the default type which is Float32Array
-but can be set by calling setDefaultType.
Generated using TypeDoc
A JavaScript array with 16 values, a Float32Array with 16 values, or a Float64Array with 16 values.
-When created by the library will create the default type which is Float32Array
-but can be set by calling setDefaultType.
Generated using TypeDoc
A JavaScript array with 4 values, Float32Array with 4 values, or a Float64Array with 4 values.
-When created by the library will create the default type which is Float32Array
-but can be set by calling setDefaultType.
Generated using TypeDoc
A JavaScript array with 2 values, Float32Array with 2 values, or a Float64Array with 2 values.
-When created by the library will create the default type which is Float32Array
-but can be set by calling setDefaultType.
Generated using TypeDoc
A JavaScript array with 3 values, Float32Array with 3 values, or a Float64Array with 3 values.
-When created by the library will create the default type which is Float32Array
-but can be set by calling setDefaultType.
Generated using TypeDoc
A JavaScript array with 4 values, Float32Array with 4 values, or a Float64Array with 4 values.
-When created by the library will create the default type which is Float32Array
-but can be set by calling setDefaultType.
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
Generated using TypeDoc
+ * For a fairly comprehensive set of languages see the + * README + * file that came with this source. At a minimum, the lexer should work on a + * number of languages including C and friends, Java, Python, Bash, SQL, HTML, + * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk + * and a subset of Perl, but, because of commenting conventions, doesn't work on + * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. + *
+ * Usage:
} and {@code } tags in your source with
+ * {@code class=prettyprint.}
+ * You can also use the (html deprecated) {@code } tag, but the pretty
+ * printer needs to do more substantial DOM manipulations to support that, so
+ * some css styles may not be preserved.
+ *
} or {@code } element to specify the
+ * language, as in {@code }. Any class that
+ * starts with "lang-" followed by a file extension, specifies the file type.
+ * See the "lang-*.js" files in this directory for code that implements
+ * per-language file handlers.
+ *
+ * Change log:
+ * cbeust, 2006/08/22
+ *
+ * Java annotations (start with "@") are now captured as literals ("lit")
+ *
+ * @requires console
+ */
+
+// JSLint declarations
+/*global console, document, navigator, setTimeout, window, define */
+
+/** @define {boolean} */
+var IN_GLOBAL_SCOPE = true;
+
+/**
+ * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
+ * UI events.
+ * If set to {@code false}, {@code prettyPrint()} is synchronous.
+ */
+window['PR_SHOULD_USE_CONTINUATION'] = true;
+
+/**
+ * Pretty print a chunk of code.
+ * @param {string} sourceCodeHtml The HTML to pretty print.
+ * @param {string} opt_langExtension The language name to use.
+ * Typically, a filename extension like 'cpp' or 'java'.
+ * @param {number|boolean} opt_numberLines True to number lines,
+ * or the 1-indexed number of the first line in sourceCodeHtml.
+ * @return {string} code as html, but prettier
+ */
+var prettyPrintOne;
+/**
+ * Find all the {@code } and {@code } tags in the DOM with
+ * {@code class=prettyprint} and prettify them.
+ *
+ * @param {Function} opt_whenDone called when prettifying is done.
+ * @param {HTMLElement|HTMLDocument} opt_root an element or document
+ * containing all the elements to pretty print.
+ * Defaults to {@code document.body}.
+ */
+var prettyPrint;
+
+
+(function () {
+ var win = window;
+ // Keyword lists for various languages.
+ // We use things that coerce to strings to make them compact when minified
+ // and to defeat aggressive optimizers that fold large string constants.
+ var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
+ var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
+ "double,enum,extern,float,goto,inline,int,long,register,short,signed," +
+ "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
+ var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
+ "new,operator,private,protected,public,this,throw,true,try,typeof"];
+ var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
+ "concept,concept_map,const_cast,constexpr,decltype,delegate," +
+ "dynamic_cast,explicit,export,friend,generic,late_check," +
+ "mutable,namespace,nullptr,property,reinterpret_cast,static_assert," +
+ "static_cast,template,typeid,typename,using,virtual,where"];
+ var JAVA_KEYWORDS = [COMMON_KEYWORDS,
+ "abstract,assert,boolean,byte,extends,final,finally,implements,import," +
+ "instanceof,interface,null,native,package,strictfp,super,synchronized," +
+ "throws,transient"];
+ var CSHARP_KEYWORDS = [COMMON_KEYWORDS,
+ "abstract,as,base,bool,by,byte,checked,decimal,delegate,descending," +
+ "dynamic,event,finally,fixed,foreach,from,group,implicit,in,interface," +
+ "internal,into,is,let,lock,null,object,out,override,orderby,params," +
+ "partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong," +
+ "unchecked,unsafe,ushort,var,virtual,where"];
+ var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
+ "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
+ "throw,true,try,unless,until,when,while,yes";
+ var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
+ "debugger,eval,export,function,get,null,set,undefined,var,with," +
+ "Infinity,NaN"];
+ var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
+ "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
+ "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
+ var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
+ "elif,except,exec,finally,from,global,import,in,is,lambda," +
+ "nonlocal,not,or,pass,print,raise,try,with,yield," +
+ "False,True,None"];
+ var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
+ "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
+ "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
+ "BEGIN,END"];
+ var RUST_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "as,assert,const,copy,drop," +
+ "enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv," +
+ "pub,pure,ref,self,static,struct,true,trait,type,unsafe,use"];
+ var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
+ "function,in,local,set,then,until"];
+ var ALL_KEYWORDS = [
+ CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS,
+ PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
+ var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
+
+ // token style names. correspond to css classes
+ /**
+ * token style for a string literal
+ * @const
+ */
+ var PR_STRING = 'str';
+ /**
+ * token style for a keyword
+ * @const
+ */
+ var PR_KEYWORD = 'kwd';
+ /**
+ * token style for a comment
+ * @const
+ */
+ var PR_COMMENT = 'com';
+ /**
+ * token style for a type
+ * @const
+ */
+ var PR_TYPE = 'typ';
+ /**
+ * token style for a literal value. e.g. 1, null, true.
+ * @const
+ */
+ var PR_LITERAL = 'lit';
+ /**
+ * token style for a punctuation string.
+ * @const
+ */
+ var PR_PUNCTUATION = 'pun';
+ /**
+ * token style for plain text.
+ * @const
+ */
+ var PR_PLAIN = 'pln';
+
+ /**
+ * token style for an sgml tag.
+ * @const
+ */
+ var PR_TAG = 'tag';
+ /**
+ * token style for a markup declaration such as a DOCTYPE.
+ * @const
+ */
+ var PR_DECLARATION = 'dec';
+ /**
+ * token style for embedded source.
+ * @const
+ */
+ var PR_SOURCE = 'src';
+ /**
+ * token style for an sgml attribute name.
+ * @const
+ */
+ var PR_ATTRIB_NAME = 'atn';
+ /**
+ * token style for an sgml attribute value.
+ * @const
+ */
+ var PR_ATTRIB_VALUE = 'atv';
+
+ /**
+ * A class that indicates a section of markup that is not code, e.g. to allow
+ * embedding of line numbers within code listings.
+ * @const
+ */
+ var PR_NOCODE = 'nocode';
+
+
+
+ /**
+ * A set of tokens that can precede a regular expression literal in
+ * javascript
+ * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
+ * has the full list, but I've removed ones that might be problematic when
+ * seen in languages that don't support regular expression literals.
+ *
+ * Specifically, I've removed any keywords that can't precede a regexp
+ * literal in a syntactically legal javascript program, and I've removed the
+ * "in" keyword since it's not a keyword in many languages, and might be used
+ * as a count of inches.
+ *
+ *
The link above does not accurately describe EcmaScript rules since
+ * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
+ * very well in practice.
+ *
+ * @private
+ * @const
+ */
+ var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
+
+ // CAVEAT: this does not properly handle the case where a regular
+ // expression immediately follows another since a regular expression may
+ // have flags for case-sensitivity and the like. Having regexp tokens
+ // adjacent is not valid in any language I'm aware of, so I'm punting.
+ // TODO: maybe style special characters inside a regexp as punctuation.
+
+ /**
+ * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
+ * matches the union of the sets of strings matched by the input RegExp.
+ * Since it matches globally, if the input strings have a start-of-input
+ * anchor (/^.../), it is ignored for the purposes of unioning.
+ * @param {Array.} regexs non multiline, non-global regexs.
+ * @return {RegExp} a global regex.
+ */
+ function combinePrefixPatterns(regexs) {
+ var capturedGroupIndex = 0;
+
+ var needToFoldCase = false;
+ var ignoreCase = false;
+ for (var i = 0, n = regexs.length; i < n; ++i) {
+ var regex = regexs[i];
+ if (regex.ignoreCase) {
+ ignoreCase = true;
+ } else if (/[a-z]/i.test(regex.source.replace(
+ /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
+ needToFoldCase = true;
+ ignoreCase = false;
+ break;
+ }
+ }
+
+ var escapeCharToCodeUnit = {
+ 'b': 8,
+ 't': 9,
+ 'n': 0xa,
+ 'v': 0xb,
+ 'f': 0xc,
+ 'r': 0xd
+ };
+
+ function decodeEscape(charsetPart) {
+ var cc0 = charsetPart.charCodeAt(0);
+ if (cc0 !== 92 /* \\ */) {
+ return cc0;
+ }
+ var c1 = charsetPart.charAt(1);
+ cc0 = escapeCharToCodeUnit[c1];
+ if (cc0) {
+ return cc0;
+ } else if ('0' <= c1 && c1 <= '7') {
+ return parseInt(charsetPart.substring(1), 8);
+ } else if (c1 === 'u' || c1 === 'x') {
+ return parseInt(charsetPart.substring(2), 16);
+ } else {
+ return charsetPart.charCodeAt(1);
+ }
+ }
+
+ function encodeEscape(charCode) {
+ if (charCode < 0x20) {
+ return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
+ }
+ var ch = String.fromCharCode(charCode);
+ return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
+ ? "\\" + ch : ch;
+ }
+
+ function caseFoldCharset(charSet) {
+ var charsetParts = charSet.substring(1, charSet.length - 1).match(
+ new RegExp(
+ '\\\\u[0-9A-Fa-f]{4}'
+ + '|\\\\x[0-9A-Fa-f]{2}'
+ + '|\\\\[0-3][0-7]{0,2}'
+ + '|\\\\[0-7]{1,2}'
+ + '|\\\\[\\s\\S]'
+ + '|-'
+ + '|[^-\\\\]',
+ 'g'));
+ var ranges = [];
+ var inverse = charsetParts[0] === '^';
+
+ var out = ['['];
+ if (inverse) { out.push('^'); }
+
+ for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
+ var p = charsetParts[i];
+ if (/\\[bdsw]/i.test(p)) { // Don't muck with named groups.
+ out.push(p);
+ } else {
+ var start = decodeEscape(p);
+ var end;
+ if (i + 2 < n && '-' === charsetParts[i + 1]) {
+ end = decodeEscape(charsetParts[i + 2]);
+ i += 2;
+ } else {
+ end = start;
+ }
+ ranges.push([start, end]);
+ // If the range might intersect letters, then expand it.
+ // This case handling is too simplistic.
+ // It does not deal with non-latin case folding.
+ // It works for latin source code identifiers though.
+ if (!(end < 65 || start > 122)) {
+ if (!(end < 65 || start > 90)) {
+ ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
+ }
+ if (!(end < 97 || start > 122)) {
+ ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
+ }
+ }
+ }
+ }
+
+ // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
+ // -> [[1, 12], [14, 14], [16, 17]]
+ ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1] - a[1]); });
+ var consolidatedRanges = [];
+ var lastRange = [];
+ for (var i = 0; i < ranges.length; ++i) {
+ var range = ranges[i];
+ if (range[0] <= lastRange[1] + 1) {
+ lastRange[1] = Math.max(lastRange[1], range[1]);
+ } else {
+ consolidatedRanges.push(lastRange = range);
+ }
+ }
+
+ for (var i = 0; i < consolidatedRanges.length; ++i) {
+ var range = consolidatedRanges[i];
+ out.push(encodeEscape(range[0]));
+ if (range[1] > range[0]) {
+ if (range[1] + 1 > range[0]) { out.push('-'); }
+ out.push(encodeEscape(range[1]));
+ }
+ }
+ out.push(']');
+ return out.join('');
+ }
+
+ function allowAnywhereFoldCaseAndRenumberGroups(regex) {
+ // Split into character sets, escape sequences, punctuation strings
+ // like ('(', '(?:', ')', '^'), and runs of characters that do not
+ // include any of the above.
+ var parts = regex.source.match(
+ new RegExp(
+ '(?:'
+ + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]' // a character set
+ + '|\\\\u[A-Fa-f0-9]{4}' // a unicode escape
+ + '|\\\\x[A-Fa-f0-9]{2}' // a hex escape
+ + '|\\\\[0-9]+' // a back-reference or octal escape
+ + '|\\\\[^ux0-9]' // other escape sequence
+ + '|\\(\\?[:!=]' // start of a non-capturing group
+ + '|[\\(\\)\\^]' // start/end of a group, or line start
+ + '|[^\\x5B\\x5C\\(\\)\\^]+' // run of other characters
+ + ')',
+ 'g'));
+ var n = parts.length;
+
+ // Maps captured group numbers to the number they will occupy in
+ // the output or to -1 if that has not been determined, or to
+ // undefined if they need not be capturing in the output.
+ var capturedGroups = [];
+
+ // Walk over and identify back references to build the capturedGroups
+ // mapping.
+ for (var i = 0, groupIndex = 0; i < n; ++i) {
+ var p = parts[i];
+ if (p === '(') {
+ // groups are 1-indexed, so max group index is count of '('
+ ++groupIndex;
+ } else if ('\\' === p.charAt(0)) {
+ var decimalValue = +p.substring(1);
+ if (decimalValue) {
+ if (decimalValue <= groupIndex) {
+ capturedGroups[decimalValue] = -1;
+ } else {
+ // Replace with an unambiguous escape sequence so that
+ // an octal escape sequence does not turn into a backreference
+ // to a capturing group from an earlier regex.
+ parts[i] = encodeEscape(decimalValue);
+ }
+ }
+ }
+ }
+
+ // Renumber groups and reduce capturing groups to non-capturing groups
+ // where possible.
+ for (var i = 1; i < capturedGroups.length; ++i) {
+ if (-1 === capturedGroups[i]) {
+ capturedGroups[i] = ++capturedGroupIndex;
+ }
+ }
+ for (var i = 0, groupIndex = 0; i < n; ++i) {
+ var p = parts[i];
+ if (p === '(') {
+ ++groupIndex;
+ if (!capturedGroups[groupIndex]) {
+ parts[i] = '(?:';
+ }
+ } else if ('\\' === p.charAt(0)) {
+ var decimalValue = +p.substring(1);
+ if (decimalValue && decimalValue <= groupIndex) {
+ parts[i] = '\\' + capturedGroups[decimalValue];
+ }
+ }
+ }
+
+ // Remove any prefix anchors so that the output will match anywhere.
+ // ^^ really does mean an anchored match though.
+ for (var i = 0; i < n; ++i) {
+ if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
+ }
+
+ // Expand letters to groups to handle mixing of case-sensitive and
+ // case-insensitive patterns if necessary.
+ if (regex.ignoreCase && needToFoldCase) {
+ for (var i = 0; i < n; ++i) {
+ var p = parts[i];
+ var ch0 = p.charAt(0);
+ if (p.length >= 2 && ch0 === '[') {
+ parts[i] = caseFoldCharset(p);
+ } else if (ch0 !== '\\') {
+ // TODO: handle letters in numeric escapes.
+ parts[i] = p.replace(
+ /[a-zA-Z]/g,
+ function (ch) {
+ var cc = ch.charCodeAt(0);
+ return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
+ });
+ }
+ }
+ }
+
+ return parts.join('');
+ }
+
+ var rewritten = [];
+ for (var i = 0, n = regexs.length; i < n; ++i) {
+ var regex = regexs[i];
+ if (regex.global || regex.multiline) { throw new Error('' + regex); }
+ rewritten.push(
+ '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
+ }
+
+ return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
+ }
+
+ /**
+ * Split markup into a string of source code and an array mapping ranges in
+ * that string to the text nodes in which they appear.
+ *
+ *
+ * The HTML DOM structure:
+ *
+ * (Element "p"
+ * (Element "b"
+ * (Text "print ")) ; #1
+ * (Text "'Hello '") ; #2
+ * (Element "br") ; #3
+ * (Text " + 'World';")) ; #4
+ *
+ *
+ * corresponds to the HTML
+ * {@code
print 'Hello '
+ 'World';
}.
+ *
+ *
+ * It will produce the output:
+ *
+ * {
+ * sourceCode: "print 'Hello '\n + 'World';",
+ * // 1 2
+ * // 012345678901234 5678901234567
+ * spans: [0, #1, 6, #2, 14, #3, 15, #4]
+ * }
+ *
+ *
+ * where #1 is a reference to the {@code "print "} text node above, and so
+ * on for the other text nodes.
+ *
+ *
+ *
+ * The {@code} spans array is an array of pairs. Even elements are the start
+ * indices of substrings, and odd elements are the text nodes (or BR elements)
+ * that contain the text for those substrings.
+ * Substrings continue until the next index or the end of the source.
+ *
+ *
+ * @param {Node} node an HTML DOM subtree containing source-code.
+ * @param {boolean} isPreformatted true if white-space in text nodes should
+ * be considered significant.
+ * @return {Object} source code and the text nodes in which they occur.
+ */
+ function extractSourceSpans(node, isPreformatted) {
+ var nocode = /(?:^|\s)nocode(?:\s|$)/;
+
+ var chunks = [];
+ var length = 0;
+ var spans = [];
+ var k = 0;
+
+ function walk(node) {
+ var type = node.nodeType;
+ if (type == 1) { // Element
+ if (nocode.test(node.className)) { return; }
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ walk(child);
+ }
+ var nodeName = node.nodeName.toLowerCase();
+ if ('br' === nodeName || 'li' === nodeName) {
+ chunks[k] = '\n';
+ spans[k << 1] = length++;
+ spans[(k++ << 1) | 1] = node;
+ }
+ } else if (type == 3 || type == 4) { // Text
+ var text = node.nodeValue;
+ if (text.length) {
+ if (!isPreformatted) {
+ text = text.replace(/[ \t\r\n]+/g, ' ');
+ } else {
+ text = text.replace(/\r\n?/g, '\n'); // Normalize newlines.
+ }
+ // TODO: handle tabs here?
+ chunks[k] = text;
+ spans[k << 1] = length;
+ length += text.length;
+ spans[(k++ << 1) | 1] = node;
+ }
+ }
+ }
+
+ walk(node);
+
+ return {
+ sourceCode: chunks.join('').replace(/\n$/, ''),
+ spans: spans
+ };
+ }
+
+ /**
+ * Apply the given language handler to sourceCode and add the resulting
+ * decorations to out.
+ * @param {number} basePos the index of sourceCode within the chunk of source
+ * whose decorations are already present on out.
+ */
+ function appendDecorations(basePos, sourceCode, langHandler, out) {
+ if (!sourceCode) { return; }
+ var job = {
+ sourceCode: sourceCode,
+ basePos: basePos
+ };
+ langHandler(job);
+ out.push.apply(out, job.decorations);
+ }
+
+ var notWs = /\S/;
+
+ /**
+ * Given an element, if it contains only one child element and any text nodes
+ * it contains contain only space characters, return the sole child element.
+ * Otherwise returns undefined.
+ *
+ * This is meant to return the CODE element in {@code
} when
+ * there is a single child element that contains all the non-space textual
+ * content, but not to return anything where there are multiple child elements
+ * as in {@code ...
...
} or when there
+ * is textual content.
+ */
+ function childContentWrapper(element) {
+ var wrapper = undefined;
+ for (var c = element.firstChild; c; c = c.nextSibling) {
+ var type = c.nodeType;
+ wrapper = (type === 1) // Element Node
+ ? (wrapper ? element : c)
+ : (type === 3) // Text Node
+ ? (notWs.test(c.nodeValue) ? element : wrapper)
+ : wrapper;
+ }
+ return wrapper === element ? undefined : wrapper;
+ }
+
+ /** Given triples of [style, pattern, context] returns a lexing function,
+ * The lexing function interprets the patterns to find token boundaries and
+ * returns a decoration list of the form
+ * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
+ * where index_n is an index into the sourceCode, and style_n is a style
+ * constant like PR_PLAIN. index_n-1 <= index_n, and style_n-1 applies to
+ * all characters in sourceCode[index_n-1:index_n].
+ *
+ * The stylePatterns is a list whose elements have the form
+ * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
+ *
+ * Style is a style constant like PR_PLAIN, or can be a string of the
+ * form 'lang-FOO', where FOO is a language extension describing the
+ * language of the portion of the token in $1 after pattern executes.
+ * E.g., if style is 'lang-lisp', and group 1 contains the text
+ * '(hello (world))', then that portion of the token will be passed to the
+ * registered lisp handler for formatting.
+ * The text before and after group 1 will be restyled using this decorator
+ * so decorators should take care that this doesn't result in infinite
+ * recursion. For example, the HTML lexer rule for SCRIPT elements looks
+ * something like ['lang-js', /<[s]cript>(.+?)<\/script>/]. This may match
+ * '
Copies a matrix (same as copy) -Also see create and set
- -Returns
A copy of m.
-