<!-- NEW7 — TEST 7 · THE WOVEN CITY · part 273 -->
ex ];
			parsedPaths.pop();

			paths[ index ] = paths[ lastBindingsIndex ];
			paths.pop();

		}

	}

}

/**
 * An instance of `AnimationAction` schedules the playback of an animation which is
 * stored in {@link AnimationClip}.
 */
class AnimationAction {

	/**
	 * Constructs a new animation action.
	 *
	 * @param {AnimationMixer} mixer - The mixer that is controlled by this action.
	 * @param {AnimationClip} clip - The animation clip that holds the actual keyframes.
	 * @param {?Object3D} [localRoot=null] - The root object on which this action is performed.
	 * @param {(NormalAnimationBlendMode|AdditiveAnimationBlendMode)} [blendMode] - The blend mode.
	 */
	constructor( mixer, clip, localRoot = null, blendMode = clip.blendMode ) {

		this._mixer = mixer;
		this._clip = clip;
		this._localRoot = localRoot;

		/**
		 * Defines how the animation is blended/combined when two or more animations
		 * are simultaneously played.
		 *
		 * @type {(NormalAnimationBlendMode|AdditiveAnimationBlendMode)}
		 */
		this.blendMode = blendMode;

		const tracks = clip.tracks,
			nTracks = tracks.length,
			interpolants = new Array( nTracks );

		const interpolantSettings = {
			endingStart: ZeroCurvatureEnding,
			endingEnd: ZeroCurvatureEnding
		};

		for ( let i = 0; i !== nTracks; ++ i ) {

			const interpolant = tracks[ i ].createInterpolant( null );
			interpolants[ i ] = interpolant;
			interpolant.settings = interpolantSettings;

		}

		this._interpolantSettings = interpolantSettings;

		this._interpolants = interpolants; // bound by the mixer

		// inside: PropertyMixer (managed by the mixer)
		this._propertyBindings = new Array( nTracks );

		this._cacheIndex = null; // for the memory manager
		this._byClipCacheIndex = null; // for the memory manager

		this._timeScaleInterpolant = null;
		this._restoreTimeScale = null;
		this._weightInterpolant = null;

		/**
		 * The loop mode, set via {@link AnimationAction#setLoop}.
		 *
		 * @type {(LoopRepeat|LoopOnce|LoopPingPong)}
		 * @default LoopRepeat
		 */
		this.loop = LoopRepeat;
		this._loopCount = -1;

		// global mixer time when the action is to be started
		// it's set back to 'null' upon start of the action
		this._startTime = null;

		/**
		 * The local time of this action (in seconds, starting with `0`).
		 *
		 * The value gets clamped or wrapped to `[0,clip.duration]` (according to the
		 * loop state).
		 *
		 * @type {number}
		 * @default Infinity
		 */
		this.time = 0;

		/**
		 * Scaling factor for the {@link AnimationAction#time}. A value of `0` causes the
		 * animation to pause. Negative values cause the animation to play backwards.
		 *
		 * @type {number}
		 * @default 1
		 */
		this.timeScale = 1;
		this._effectiveTimeScale = 1;

		/**
		 * The degree of influence of this action (in the interval `[0, 1]`). Values
		 * between `0` (no impact) and `1` (full impact) can be used to blend between
		 * several actions.
		 *
		 * @type {number}
		 * @default 1
		 */
		this.weight = 1;
		this._effectiveWeight = 1;

		/**
		 * The number of repetitions of the performed clip over the course of this action.
		 * Can be set via {@link AnimationAction#setLoop}.
		 *
		 * Setting this number has no effect if {@link AnimationAction#loop} is set to
		 * `THREE:LoopOnce`.
		 *
		 * @type {number}
		 * @default Infinity
		 */
		this.repetitions = Infinity;

		/**
		 * If set to `true`, the playback of the action is paused.
		 *
		 * @type {boolean}
		 * @default false
		 */
		this.paused = false;

		/**
		 * If set to `false`, the action is disabled so it has no impact.
		 *
		 * When the action is re-enabled, the animation continues from its current
		 * time (setting `enabled` to `false` doesn't reset the action).
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.enabled = true;

		/**
		 * If set to true the animation will automatically be paused on its last frame.
		 *
		 * If set to false, {@link AnimationAction#enabled} will automatically be switched
		 * to `false` when the last loop of the action has finished, so that this action has
		 * no further impact.
		 *
		 * Note: This member has no impact if the action is interrupted (it
		 * has only an effect if its last loop has really finished).
		 *
		 * @type {boolean}
		 * @default false
		 */
		this.clampWhenFinished = false;

		/**
		 * Enables smooth interpolation without separate clips for start, loop and end.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.zeroSlopeAtStart = true;

		/**
		 * Enables smooth interpolation without separate clips for start, loop and end.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.zeroSlopeAtEnd = true;

	}

	/**
	 * Starts the playback of the animation.
	 *
	 * @return {AnimationAction} A reference to this animation action.
	 */
	play() {

		this._mixer._activateAction( this );

		return this;

	}

	/**
	 * Stops the playback of the animation.
	 *
	 * @return {AnimationAction} A refere