<!-- NEW4 — TEST 4 · THE QUILT · part 131 -->
 @type {boolean}
		 * @readonly
		 * @default true
		 */
		this.isDataTexture = true;

		/**
		 * The image definition of a data texture.
		 *
		 * @type {{data:TypedArray,width:number,height:number}}
		 */
		this.image = { data: data, width: width, height: height };

		/**
		 * Whether to generate mipmaps (if possible) for a texture.
		 *
		 * Overwritten and set to `false` by default.
		 *
		 * @type {boolean}
		 * @default false
		 */
		this.generateMipmaps = false;

		/**
		 * If set to `true`, the texture is flipped along the vertical axis when
		 * uploaded to the GPU.
		 *
		 * Overwritten and set to `false` by default.
		 *
		 * @type {boolean}
		 * @default false
		 */
		this.flipY = false;

		/**
		 * Specifies the alignment requirements for the start of each pixel row in memory.
		 *
		 * Overwritten and set to `1` by default.
		 *
		 * @type {boolean}
		 * @default 1
		 */
		this.unpackAlignment = 1;

	}

}

const _offsetMatrix = /*@__PURE__*/ new Matrix4();
const _identityMatrix = /*@__PURE__*/ new Matrix4();

/**
 * Class for representing the armatures in `three.js`. The skeleton
 * is defined by a hierarchy of bones.
 *
 * ```js
 * const bones = [];
 *
 * const shoulder = new THREE.Bone();
 * const elbow = new THREE.Bone();
 * const hand = new THREE.Bone();
 *
 * shoulder.add( elbow );
 * elbow.add( hand );
 *
 * bones.push( shoulder , elbow, hand);
 *
 * shoulder.position.y = -5;
 * elbow.position.y = 0;
 * hand.position.y = 5;
 *
 * const armSkeleton = new THREE.Skeleton( bones );
 * ```
 */
class Skeleton {

	/**
	 * Constructs a new skeleton.
	 *
	 * @param {Array<Bone>} [bones] - An array of bones.
	 * @param {Array<Matrix4>} [boneInverses] - An array of bone inverse matrices.
	 * If not provided, these matrices will be computed automatically via {@link Skeleton#calculateInverses}.
	 */
	constructor( bones = [], boneInverses = [] ) {

		this.uuid = generateUUID();

		/**
		 * An array of bones defining the skeleton.
		 *
		 * @type {Array<Bone>}
		 */
		this.bones = bones.slice( 0 );

		/**
		 * An array of bone inverse matrices.
		 *
		 * @type {Array<Matrix4>}
		 */
		this.boneInverses = boneInverses;

		/**
		 * An array buffer holding the bone data.
		 * Input data for {@link Skeleton#boneTexture}.
		 *
		 * @type {?Float32Array}
		 * @default null
		 */
		this.boneMatrices = null;

		/**
		 * A texture holding the bone data for use
		 * in the vertex shader.
		 *
		 * @type {?DataTexture}
		 * @default null
		 */
		this.boneTexture = null;

		this.init();

	}

	/**
	 * Initializes the skeleton. This method gets automatically called by the constructor
	 * but depending on how the skeleton is created it might be necessary to call this method
	 * manually.
	 */
	init() {

		const bones = this.bones;
		const boneInverses = this.boneInverses;

		this.boneMatrices = new Float32Array( bones.length * 16 );

		// calculate inverse bone matrices if necessary

		if ( boneInverses.length === 0 ) {

			this.calculateInverses();

		} else {

			// handle special case

			if ( bones.length !== boneInverses.length ) {

				warn( 'Skeleton: Number of inverse bone matrices does not match amount of bones.' );

				this.boneInverses = [];

				for ( let i = 0, il = this.bones.length; i < il; i ++ ) {

					this.boneInverses.push( new Matrix4() );

				}

			}

		}

	}

	/**
	 * Computes the bone inverse matrices. This method resets {@link Skeleton#boneInverses}
	 * and fills it with new matrices.
	 */
	calculateInverses() {

		this.boneInverses.length = 0;

		for ( let i = 0, il = this.bones.length; i < il; i ++ ) {

			const inverse = new Matrix4();

			if ( this.bones[ i ] ) {

				inverse.copy( this.bones[ i ].matrixWorld ).invert();

			}

			this.boneInverses.push( inverse );

		}

	}

	/**
	 * Resets the skeleton to the base pose.
	 */
	pose() {

		// recover the bind-time world matrices

		for ( let i = 0, il = this.bones.length; i < il; i ++ ) {

			const bone = this.bones[ i ];

			if ( bone ) {

				bone.matrixWorld.copy( this.boneInverses[ i ] ).invert();

			}

		}

		// compute the local matrices, positions, rotations and scales

		for ( let i = 0, il = this.bones.length; i < il; i ++ ) {

			const bone = this.bones[ i ];

			if ( bone ) {

				if ( bone.parent && bone.parent.isBone ) {

					bone.matrix.copy( bone.parent.matrixWorld ).invert();
					bone.matrix.multiply( bone.matrixWorld );

				} else {

					bone.matrix.copy( bone.matrixWorld );

				}

				bone.matrix.decompose( bone.position, bone.quaternion, bone.scale );

			}

		}

	}

	/**
	 * Resets the skeleton to the base pose.
	 */
	update() {

		const bones = this.bones;
		const boneInverses = this.boneInverses;
		const boneMatrices = this.boneMatrices;
		const boneTexture = this.boneTexture;

		// flatten bone matrices to array

		for ( let i = 0, il = bones.length; i < il; i ++ ) {

			// compute the offset between the current and the original transform

			const matrix = bone