(function (exports, Laya) {
    'use strict';

    class IAniLib {
    }
    IAniLib.Skeleton = null;
    IAniLib.AnimationTemplet = null;
    IAniLib.Templet = null;

    class AnimationContent {
    }

    class AnimationNodeContent {
    }

    class KeyFramesContent {
    }

    class AnimationParser01 {
        static parse(templet, reader) {
            var data = reader.__getBuffer();
            var i, j, k, n, l, m, o;
            var aniClassName = reader.readUTFString();
            templet._aniClassName = aniClassName;
            var strList = reader.readUTFString().split("\n");
            var aniCount = reader.getUint8();
            var publicDataPos = reader.getUint32();
            var publicExtDataPos = reader.getUint32();
            var publicData;
            if (publicDataPos > 0)
                publicData = data.slice(publicDataPos, publicExtDataPos);
            var publicRead = new Laya.Byte(publicData);
            if (publicExtDataPos > 0)
                templet._publicExtData = data.slice(publicExtDataPos, data.byteLength);
            templet._useParent = !!reader.getUint8();
            templet._anis.length = aniCount;
            for (i = 0; i < aniCount; i++) {
                var ani = templet._anis[i] = new AnimationContent();
                ani.nodes = [];
                var name = ani.name = strList[reader.getUint16()];
                templet._aniMap[name] = i;
                ani.bone3DMap = {};
                ani.playTime = reader.getFloat32();
                var boneCount = ani.nodes.length = reader.getUint8();
                ani.totalKeyframeDatasLength = 0;
                for (j = 0; j < boneCount; j++) {
                    var node = ani.nodes[j] = new AnimationNodeContent();
                    node.childs = [];
                    var nameIndex = reader.getInt16();
                    if (nameIndex >= 0) {
                        node.name = strList[nameIndex];
                        ani.bone3DMap[node.name] = j;
                    }
                    node.keyFrame = [];
                    node.parentIndex = reader.getInt16();
                    node.parentIndex == -1 ? node.parent = null : node.parent = ani.nodes[node.parentIndex];
                    node.lerpType = reader.getUint8();
                    var keyframeParamsOffset = reader.getUint32();
                    publicRead.pos = keyframeParamsOffset;
                    var keyframeDataCount = node.keyframeWidth = publicRead.getUint16();
                    ani.totalKeyframeDatasLength += keyframeDataCount;
                    if (node.lerpType === 0 || node.lerpType === 1) {
                        node.interpolationMethod = [];
                        node.interpolationMethod.length = keyframeDataCount;
                        for (k = 0; k < keyframeDataCount; k++)
                            node.interpolationMethod[k] = IAniLib.AnimationTemplet.interpolation[publicRead.getUint8()];
                    }
                    if (node.parent != null)
                        node.parent.childs.push(node);
                    var privateDataLen = reader.getUint16();
                    if (privateDataLen > 0) {
                        node.extenData = data.slice(reader.pos, reader.pos + privateDataLen);
                        reader.pos += privateDataLen;
                    }
                    var keyframeCount = reader.getUint16();
                    node.keyFrame.length = keyframeCount;
                    var startTime = 0;
                    var keyFrame;
                    for (k = 0, n = keyframeCount; k < n; k++) {
                        keyFrame = node.keyFrame[k] = new KeyFramesContent();
                        keyFrame.duration = reader.getFloat32();
                        keyFrame.startTime = startTime;
                        if (node.lerpType === 2) {
                            keyFrame.interpolationData = [];
                            var interDataLength = reader.getUint8();
                            var lerpType;
                            lerpType = reader.getFloat32();
                            switch (lerpType) {
                                case 254:
                                    keyFrame.interpolationData.length = keyframeDataCount;
                                    for (o = 0; o < keyframeDataCount; o++)
                                        keyFrame.interpolationData[o] = 0;
                                    break;
                                case 255:
                                    keyFrame.interpolationData.length = keyframeDataCount;
                                    for (o = 0; o < keyframeDataCount; o++)
                                        keyFrame.interpolationData[o] = 5;
                                    break;
                                default:
                                    keyFrame.interpolationData.push(lerpType);
                                    for (m = 1; m < interDataLength; m++) {
                                        keyFrame.interpolationData.push(reader.getFloat32());
                                    }
                            }
                        }
                        keyFrame.data = new Float32Array(keyframeDataCount);
                        keyFrame.dData = new Float32Array(keyframeDataCount);
                        keyFrame.nextData = new Float32Array(keyframeDataCount);
                        for (l = 0; l < keyframeDataCount; l++) {
                            keyFrame.data[l] = reader.getFloat32();
                            if (keyFrame.data[l] > -0.00000001 && keyFrame.data[l] < 0.00000001)
                                keyFrame.data[l] = 0;
                        }
                        startTime += keyFrame.duration;
                    }
                    keyFrame.startTime = ani.playTime;
                    node.playTime = ani.playTime;
                    templet._calculateKeyFrame(node, keyframeCount, keyframeDataCount);
                }
            }
        }
    }

    class AnimationParser02 {
        static READ_DATA() {
            AnimationParser02._DATA.offset = AnimationParser02._reader.getUint32();
            AnimationParser02._DATA.size = AnimationParser02._reader.getUint32();
        }
        static READ_BLOCK() {
            var count = AnimationParser02._BLOCK.count = AnimationParser02._reader.getUint16();
            var blockStarts = AnimationParser02._BLOCK.blockStarts = [];
            var blockLengths = AnimationParser02._BLOCK.blockLengths = [];
            for (var i = 0; i < count; i++) {
                blockStarts.push(AnimationParser02._reader.getUint32());
                blockLengths.push(AnimationParser02._reader.getUint32());
            }
        }
        static READ_STRINGS() {
            var offset = AnimationParser02._reader.getUint32();
            var count = AnimationParser02._reader.getUint16();
            var prePos = AnimationParser02._reader.pos;
            AnimationParser02._reader.pos = offset + AnimationParser02._DATA.offset;
            for (var i = 0; i < count; i++)
                AnimationParser02._strings[i] = AnimationParser02._reader.readUTFString();
            AnimationParser02._reader.pos = prePos;
        }
        static parse(templet, reader) {
            AnimationParser02._templet = templet;
            AnimationParser02._reader = reader;
            var arrayBuffer = reader.__getBuffer();
            AnimationParser02.READ_DATA();
            AnimationParser02.READ_BLOCK();
            AnimationParser02.READ_STRINGS();
            for (var i = 0, n = AnimationParser02._BLOCK.count; i < n; i++) {
                var index = reader.getUint16();
                var blockName = AnimationParser02._strings[index];
                var fn = AnimationParser02["READ_" + blockName];
                if (fn == null)
                    throw new Error("model file err,no this function:" + index + " " + blockName);
                else
                    fn.call(null);
            }
        }
        static READ_ANIMATIONS() {
            var reader = AnimationParser02._reader;
            var arrayBuffer = reader.__getBuffer();
            var i, j, k, n;
            var keyframeWidth = reader.getUint16();
            var interpolationMethod = [];
            interpolationMethod.length = keyframeWidth;
            for (i = 0; i < keyframeWidth; i++)
                interpolationMethod[i] = IAniLib.AnimationTemplet.interpolation[reader.getByte()];
            var aniCount = reader.getUint8();
            AnimationParser02._templet._anis.length = aniCount;
            for (i = 0; i < aniCount; i++) {
                var ani = AnimationParser02._templet._anis[i] = new AnimationContent();
                ani.nodes = [];
                var aniName = ani.name = AnimationParser02._strings[reader.getUint16()];
                AnimationParser02._templet._aniMap[aniName] = i;
                ani.bone3DMap = {};
                ani.playTime = reader.getFloat32();
                var boneCount = ani.nodes.length = reader.getInt16();
                ani.totalKeyframeDatasLength = 0;
                for (j = 0; j < boneCount; j++) {
                    var node = ani.nodes[j] = new AnimationNodeContent();
                    node.keyframeWidth = keyframeWidth;
                    node.childs = [];
                    var nameIndex = reader.getUint16();
                    if (nameIndex >= 0) {
                        node.name = AnimationParser02._strings[nameIndex];
                        ani.bone3DMap[node.name] = j;
                    }
                    node.keyFrame = [];
                    node.parentIndex = reader.getInt16();
                    node.parentIndex == -1 ? node.parent = null : node.parent = ani.nodes[node.parentIndex];
                    ani.totalKeyframeDatasLength += keyframeWidth;
                    node.interpolationMethod = interpolationMethod;
                    if (node.parent != null)
                        node.parent.childs.push(node);
                    var keyframeCount = reader.getUint16();
                    node.keyFrame.length = keyframeCount;
                    var keyFrame = null, lastKeyFrame = null;
                    for (k = 0, n = keyframeCount; k < n; k++) {
                        keyFrame = node.keyFrame[k] = new KeyFramesContent();
                        keyFrame.startTime = reader.getFloat32();
                        (lastKeyFrame) && (lastKeyFrame.duration = keyFrame.startTime - lastKeyFrame.startTime);
                        keyFrame.dData = new Float32Array(keyframeWidth);
                        keyFrame.nextData = new Float32Array(keyframeWidth);
                        var offset = AnimationParser02._DATA.offset;
                        var keyframeDataOffset = reader.getUint32();
                        var keyframeDataLength = keyframeWidth * 4;
                        var keyframeArrayBuffer = arrayBuffer.slice(offset + keyframeDataOffset, offset + keyframeDataOffset + keyframeDataLength);
                        keyFrame.data = new Float32Array(keyframeArrayBuffer);
                        lastKeyFrame = keyFrame;
                    }
                    keyFrame.duration = 0;
                    node.playTime = ani.playTime;
                    AnimationParser02._templet._calculateKeyFrame(node, keyframeCount, keyframeWidth);
                }
            }
        }
    }
    AnimationParser02._strings = [];
    AnimationParser02._BLOCK = { count: 0 };
    AnimationParser02._DATA = { offset: 0, size: 0 };

    class AnimationState {
        constructor() {
        }
    }
    AnimationState.stopped = 0;
    AnimationState.paused = 1;
    AnimationState.playing = 2;

    class AnimationPlayer extends Laya.EventDispatcher {
        constructor() {
            super();
            this.isCache = true;
            this.playbackRate = 1.0;
            this._destroyed = false;
            this._currentAnimationClipIndex = -1;
            this._currentKeyframeIndex = -1;
            this._currentTime = 0.0;
            this._overallDuration = Number.MAX_VALUE;
            this._stopWhenCircleFinish = false;
            this._elapsedPlaybackTime = 0;
            this._startUpdateLoopCount = -1;
            this._cachePlayRate = 1.0;
            this.cacheFrameRate = 60;
            this.returnToZeroStopped = false;
        }
        get templet() {
            return this._templet;
        }
        set templet(value) {
            if (!(this.state === AnimationState.stopped))
                this.stop(true);
            if (this._templet !== value) {
                this._templet = value;
                this._computeFullKeyframeIndices();
            }
        }
        get playStart() {
            return this._playStart;
        }
        get playEnd() {
            return this._playEnd;
        }
        get playDuration() {
            return this._playDuration;
        }
        get overallDuration() {
            return this._overallDuration;
        }
        get currentAnimationClipIndex() {
            return this._currentAnimationClipIndex;
        }
        get currentKeyframeIndex() {
            return this._currentKeyframeIndex;
        }
        get currentPlayTime() {
            return this._currentTime + this._playStart;
        }
        get currentFrameTime() {
            return this._currentFrameTime;
        }
        get cachePlayRate() {
            return this._cachePlayRate;
        }
        set cachePlayRate(value) {
            if (this._cachePlayRate !== value) {
                this._cachePlayRate = value;
                if (this._templet)
                    this._computeFullKeyframeIndices();
            }
        }
        get cacheFrameRate() {
            return this._cacheFrameRate;
        }
        set cacheFrameRate(value) {
            if (this._cacheFrameRate !== value) {
                this._cacheFrameRate = value;
                this._cacheFrameRateInterval = 1000.0 / this._cacheFrameRate;
                if (this._templet)
                    this._computeFullKeyframeIndices();
            }
        }
        set currentTime(value) {
            if (this._currentAnimationClipIndex === -1 || !this._templet)
                return;
            if (value < this._playStart || value > this._playEnd)
                throw new Error("AnimationPlayer:value must large than playStartTime,small than playEndTime.");
            this._startUpdateLoopCount = Laya.Stat.loopCount;
            var cacheFrameInterval = this._cacheFrameRateInterval * this._cachePlayRate;
            this._currentTime = value;
            this._currentKeyframeIndex = Math.floor(this.currentPlayTime / cacheFrameInterval);
            this._currentFrameTime = this._currentKeyframeIndex * cacheFrameInterval;
        }
        get paused() {
            return this._paused;
        }
        set paused(value) {
            this._paused = value;
            value && this.event(Laya.Event.PAUSED);
        }
        get cacheFrameRateInterval() {
            return this._cacheFrameRateInterval;
        }
        get state() {
            if (this._currentAnimationClipIndex === -1)
                return AnimationState.stopped;
            if (this._paused)
                return AnimationState.paused;
            return AnimationState.playing;
        }
        get destroyed() {
            return this._destroyed;
        }
        _onTempletLoadedComputeFullKeyframeIndices(cachePlayRate, cacheFrameRate, templet) {
            if (this._templet === templet && this._cachePlayRate === cachePlayRate && this._cacheFrameRate === cacheFrameRate)
                this._computeFullKeyframeIndices();
        }
        _computeFullKeyframeIndices() {
            return;
            var templet = this._templet;
            if (templet._fullFrames)
                return;
            var anifullFrames = this._templet._fullFrames = [];
            var cacheFrameInterval = this._cacheFrameRateInterval * this._cachePlayRate;
            for (var i = 0, iNum = templet.getAnimationCount(); i < iNum; i++) {
                var aniFullFrame = [];
                if (!templet.getAnimation(i).nodes) {
                    anifullFrames.push(aniFullFrame);
                    continue;
                }
                for (var j = 0, jNum = templet.getAnimation(i).nodes.length; j < jNum; j++) {
                    var node = templet.getAnimation(i).nodes[j];
                    var frameCount = Math.round(node.playTime / cacheFrameInterval);
                    var nodeFullFrames = new Uint16Array(frameCount + 1);
                    var stidx = -1;
                    var nodeframes = node.keyFrame;
                    for (var n = 0, nNum = nodeframes.length; n < nNum; n++) {
                        var keyFrame = nodeframes[n];
                        var pos = Math.round(keyFrame.startTime / cacheFrameInterval);
                        if (stidx < 0 && pos > 0) {
                            stidx = pos;
                        }
                        if (pos <= frameCount) {
                            nodeFullFrames[pos] = n;
                        }
                    }
                    var cf = 0;
                    for (n = stidx; n < frameCount; n++) {
                        if (nodeFullFrames[n] == 0) {
                            nodeFullFrames[n] = cf;
                        }
                        else {
                            cf = nodeFullFrames[n];
                        }
                    }
                    aniFullFrame.push(nodeFullFrames);
                }
                anifullFrames.push(aniFullFrame);
            }
        }
        _onAnimationTempletLoaded() {
            (this.destroyed) || (this._calculatePlayDuration());
        }
        _calculatePlayDuration() {
            if (this.state !== AnimationState.stopped) {
                var oriDuration = this._templet.getAniDuration(this._currentAnimationClipIndex);
                (this._playEnd === 0) && (this._playEnd = oriDuration);
                if (this._playEnd > oriDuration)
                    this._playEnd = oriDuration;
                this._playDuration = this._playEnd - this._playStart;
            }
        }
        _setPlayParams(time, cacheFrameInterval) {
            this._currentTime = time;
            this._currentKeyframeIndex = Math.floor((this.currentPlayTime) / cacheFrameInterval + 0.01);
            this._currentFrameTime = this._currentKeyframeIndex * cacheFrameInterval;
        }
        _setPlayParamsWhenStop(currentAniClipPlayDuration, cacheFrameInterval, playEnd = -1) {
            this._currentTime = currentAniClipPlayDuration;
            var endTime = playEnd > 0 ? playEnd : currentAniClipPlayDuration;
            this._currentKeyframeIndex = Math.floor(endTime / cacheFrameInterval + 0.01);
            this._currentKeyframeIndex = Math.floor(currentAniClipPlayDuration / cacheFrameInterval + 0.01);
            this._currentFrameTime = this._currentKeyframeIndex * cacheFrameInterval;
            this._currentAnimationClipIndex = -1;
        }
        _update(elapsedTime) {
            if (this._currentAnimationClipIndex === -1 || this._paused || !this._templet)
                return;
            var cacheFrameInterval = this._cacheFrameRateInterval * this._cachePlayRate;
            var time = 0;
            (this._startUpdateLoopCount !== Laya.Stat.loopCount) && (time = elapsedTime * this.playbackRate, this._elapsedPlaybackTime += time);
            var currentAniClipPlayDuration = this.playDuration;
            time += this._currentTime;
            if ((this._overallDuration !== 0 && this._elapsedPlaybackTime >= this._overallDuration) || (this._overallDuration === 0 && this._elapsedPlaybackTime >= currentAniClipPlayDuration
                || (this._overallDuration === 0 && time >= this.playEnd))) {
                this._setPlayParamsWhenStop(currentAniClipPlayDuration, cacheFrameInterval, this.playEnd);
                this.event(Laya.Event.STOPPED);
                return;
            }
            if (currentAniClipPlayDuration > 0) {
                if (time >= currentAniClipPlayDuration) {
                    if (this._stopWhenCircleFinish) {
                        this._setPlayParamsWhenStop(currentAniClipPlayDuration, cacheFrameInterval);
                        this._stopWhenCircleFinish = false;
                        this.event(Laya.Event.STOPPED);
                        return;
                    }
                    else {
                        time = time % currentAniClipPlayDuration;
                        this._setPlayParams(time, cacheFrameInterval);
                        this.event(Laya.Event.COMPLETE);
                        return;
                    }
                }
                else {
                    this._setPlayParams(time, cacheFrameInterval);
                }
            }
            else {
                if (this._stopWhenCircleFinish) {
                    this._setPlayParamsWhenStop(currentAniClipPlayDuration, cacheFrameInterval);
                    this._stopWhenCircleFinish = false;
                    this.event(Laya.Event.STOPPED);
                    return;
                }
                this._currentTime = this._currentFrameTime = this._currentKeyframeIndex = 0;
                this.event(Laya.Event.COMPLETE);
            }
        }
        _destroy() {
            this.offAll();
            this._templet = null;
            this._destroyed = true;
        }
        play(index = 0, playbackRate = 1.0, overallDuration = 2147483647, playStart = 0, playEnd = 0) {
            if (!this._templet)
                throw new Error("AnimationPlayer:templet must not be null,maybe you need to set url.");
            if (overallDuration < 0 || playStart < 0 || playEnd < 0)
                throw new Error("AnimationPlayer:overallDuration,playStart and playEnd must large than zero.");
            if ((playEnd !== 0) && (playStart > playEnd))
                throw new Error("AnimationPlayer:start must less than end.");
            this._currentTime = 0;
            this._currentFrameTime = 0;
            this._elapsedPlaybackTime = 0;
            this.playbackRate = playbackRate;
            this._overallDuration = overallDuration;
            this._playStart = playStart;
            this._playEnd = playEnd;
            this._paused = false;
            this._currentAnimationClipIndex = index;
            this._currentKeyframeIndex = 0;
            this._startUpdateLoopCount = Laya.Stat.loopCount;
            this.event(Laya.Event.PLAYED);
            this._calculatePlayDuration();
            this._update(0);
        }
        playByFrame(index = 0, playbackRate = 1.0, overallDuration = 2147483647, playStartFrame = 0, playEndFrame = 0, fpsIn3DBuilder = 30) {
            var interval = 1000.0 / fpsIn3DBuilder;
            this.play(index, playbackRate, overallDuration, playStartFrame * interval, playEndFrame * interval);
        }
        stop(immediate = true) {
            if (immediate) {
                this._currentTime = this._currentFrameTime = this._currentKeyframeIndex = 0;
                this._currentAnimationClipIndex = -1;
                this.event(Laya.Event.STOPPED);
            }
            else {
                this._stopWhenCircleFinish = true;
            }
        }
        destroy() {
        }
    }

    class BezierLerp {
        constructor() {
        }
        static getBezierRate(t, px0, py0, px1, py1) {
            var key = BezierLerp._getBezierParamKey(px0, py0, px1, py1);
            var vKey = key * 100 + t;
            if (BezierLerp._bezierResultCache[vKey])
                return BezierLerp._bezierResultCache[vKey];
            var points = BezierLerp._getBezierPoints(px0, py0, px1, py1, key);
            var i, len;
            len = points.length;
            for (i = 0; i < len; i += 2) {
                if (t <= points[i]) {
                    BezierLerp._bezierResultCache[vKey] = points[i + 1];
                    return points[i + 1];
                }
            }
            BezierLerp._bezierResultCache[vKey] = 1;
            return 1;
        }
        static _getBezierParamKey(px0, py0, px1, py1) {
            return (((px0 * 100 + py0) * 100 + px1) * 100 + py1) * 100;
        }
        static _getBezierPoints(px0, py0, px1, py1, key) {
            if (BezierLerp._bezierPointsCache[key])
                return BezierLerp._bezierPointsCache[key];
            var controlPoints;
            controlPoints = [0, 0, px0, py0, px1, py1, 1, 1];
            var bz;
            bz = new Laya.Bezier();
            var points;
            points = bz.getBezierPoints(controlPoints, 100, 3);
            BezierLerp._bezierPointsCache[key] = points;
            return points;
        }
    }
    BezierLerp._bezierResultCache = {};
    BezierLerp._bezierPointsCache = {};

    class AnimationTemplet extends Laya.Resource {
        constructor() {
            super();
            this._anis = [];
            this._aniMap = {};
            this.unfixedLastAniIndex = -1;
            this._fullFrames = null;
            this._boneCurKeyFrm = [];
        }
        static _LinearInterpolation_0(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null) {
            out[outOfs] = data[index] + dt * dData[index];
            return 1;
        }
        static _QuaternionInterpolation_1(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null) {
            var amount = duration === 0 ? 0 : dt / duration;
            Laya.MathUtil.slerpQuaternionArray(data, index, nextData, index, amount, out, outOfs);
            return 4;
        }
        static _AngleInterpolation_2(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null) {
            return 0;
        }
        static _RadiansInterpolation_3(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null) {
            return 0;
        }
        static _Matrix4x4Interpolation_4(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null) {
            for (var i = 0; i < 16; i++, index++)
                out[outOfs + i] = data[index] + dt * dData[index];
            return 16;
        }
        static _NoInterpolation_5(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null) {
            out[outOfs] = data[index];
            return 1;
        }
        static _BezierInterpolation_6(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null, offset = 0) {
            out[outOfs] = data[index] + (nextData[index] - data[index]) * BezierLerp.getBezierRate(dt / duration, interData[offset], interData[offset + 1], interData[offset + 2], interData[offset + 3]);
            return 5;
        }
        static _BezierInterpolation_7(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null, offset = 0) {
            out[outOfs] = interData[offset + 4] + interData[offset + 5] * BezierLerp.getBezierRate((dt * 0.001 + interData[offset + 6]) / interData[offset + 7], interData[offset], interData[offset + 1], interData[offset + 2], interData[offset + 3]);
            return 9;
        }
        parse(data) {
            var reader = new Laya.Byte(data);
            this._aniVersion = reader.readUTFString();
            AnimationParser01.parse(this, reader);
        }
        _calculateKeyFrame(node, keyframeCount, keyframeDataCount) {
            var keyFrames = node.keyFrame;
            keyFrames[keyframeCount] = keyFrames[0];
            for (var i = 0; i < keyframeCount; i++) {
                var keyFrame = keyFrames[i];
                for (var j = 0; j < keyframeDataCount; j++) {
                    keyFrame.dData[j] = (keyFrame.duration === 0) ? 0 : (keyFrames[i + 1].data[j] - keyFrame.data[j]) / keyFrame.duration;
                    keyFrame.nextData[j] = keyFrames[i + 1].data[j];
                }
            }
            keyFrames.length--;
        }
        _onAsynLoaded(data, propertyParams = null) {
            var reader = new Laya.Byte(data);
            this._aniVersion = reader.readUTFString();
            switch (this._aniVersion) {
                case "LAYAANIMATION:02":
                    AnimationParser02.parse(this, reader);
                    break;
                default:
                    AnimationParser01.parse(this, reader);
            }
        }
        getAnimationCount() {
            return this._anis.length;
        }
        getAnimation(aniIndex) {
            return this._anis[aniIndex];
        }
        getAniDuration(aniIndex) {
            return this._anis[aniIndex].playTime;
        }
        getNodes(aniIndex) {
            return this._anis[aniIndex].nodes;
        }
        getNodeIndexWithName(aniIndex, name) {
            return this._anis[aniIndex].bone3DMap[name];
        }
        getNodeCount(aniIndex) {
            return this._anis[aniIndex].nodes.length;
        }
        getTotalkeyframesLength(aniIndex) {
            return this._anis[aniIndex].totalKeyframeDatasLength;
        }
        getPublicExtData() {
            return this._publicExtData;
        }
        getAnimationDataWithCache(key, cacheDatas, aniIndex, frameIndex) {
            var aniDatas = cacheDatas[aniIndex];
            if (!aniDatas) {
                return null;
            }
            else {
                var keyDatas = aniDatas[key];
                if (!keyDatas)
                    return null;
                else {
                    return keyDatas[frameIndex];
                }
            }
        }
        setAnimationDataWithCache(key, cacheDatas, aniIndex, frameIndex, data) {
            var aniDatas = (cacheDatas[aniIndex]) || (cacheDatas[aniIndex] = {});
            var aniDatasCache = (aniDatas[key]) || (aniDatas[key] = []);
            aniDatasCache[frameIndex] = data;
        }
        getNodeKeyFrame(nodeframes, nodeid, tm) {
            var cid = this._boneCurKeyFrm[nodeid];
            var frmNum = nodeframes.length;
            if (cid == void 0 || cid >= frmNum) {
                cid = this._boneCurKeyFrm[nodeid] = 0;
            }
            var kinfo = nodeframes[cid];
            var curFrmTm = kinfo.startTime;
            var dt = tm - curFrmTm;
            if (dt == 0 || (dt > 0 && kinfo.duration > dt)) {
                return cid;
            }
            var i = 0;
            if (dt > 0) {
                tm = tm + 0.01;
                for (i = cid + 1; i < frmNum; i++) {
                    kinfo = nodeframes[i];
                    if (kinfo.startTime <= tm && kinfo.startTime + kinfo.duration > tm) {
                        this._boneCurKeyFrm[nodeid] = i;
                        return i;
                    }
                }
                return frmNum - 1;
            }
            else {
                for (i = 0; i < cid; i++) {
                    kinfo = nodeframes[i];
                    if (kinfo.startTime <= tm && kinfo.startTime + kinfo.duration > tm) {
                        this._boneCurKeyFrm[nodeid] = i;
                        return i;
                    }
                }
                return cid;
            }
            return 0;
        }
        getOriginalData(aniIndex, originalData, nodesFrameIndices, frameIndex, playCurTime) {
            var oneAni = this._anis[aniIndex];
            var nodes = oneAni.nodes;
            var curKFrm = this._boneCurKeyFrm;
            if (curKFrm.length < nodes.length) {
                curKFrm.length = nodes.length;
            }
            var j = 0;
            for (var i = 0, n = nodes.length, outOfs = 0; i < n; i++) {
                var node = nodes[i];
                var key;
                var kfrm = node.keyFrame;
                key = kfrm[this.getNodeKeyFrame(kfrm, i, playCurTime)];
                node.dataOffset = outOfs;
                var dt = playCurTime - key.startTime;
                var lerpType = node.lerpType;
                if (lerpType) {
                    switch (lerpType) {
                        case 0:
                        case 1:
                            for (j = 0; j < node.keyframeWidth;)
                                j += node.interpolationMethod[j](node, j, originalData, outOfs + j, key.data, dt, key.dData, key.duration, key.nextData);
                            break;
                        case 2:
                            var interpolationData = key.interpolationData;
                            var interDataLen = interpolationData.length;
                            var dataIndex = 0;
                            for (j = 0; j < interDataLen;) {
                                var type = interpolationData[j];
                                switch (type) {
                                    case 6:
                                        j += AnimationTemplet.interpolation[type](node, dataIndex, originalData, outOfs + dataIndex, key.data, dt, key.dData, key.duration, key.nextData, interpolationData, j + 1);
                                        break;
                                    case 7:
                                        j += AnimationTemplet.interpolation[type](node, dataIndex, originalData, outOfs + dataIndex, key.data, dt, key.dData, key.duration, key.nextData, interpolationData, j + 1);
                                        break;
                                    default:
                                        j += AnimationTemplet.interpolation[type](node, dataIndex, originalData, outOfs + dataIndex, key.data, dt, key.dData, key.duration, key.nextData);
                                }
                                dataIndex++;
                            }
                            break;
                    }
                }
                else {
                    for (j = 0; j < node.keyframeWidth;)
                        j += node.interpolationMethod[j](node, j, originalData, outOfs + j, key.data, dt, key.dData, key.duration, key.nextData);
                }
                outOfs += node.keyframeWidth;
            }
        }
        getNodesCurrentFrameIndex(aniIndex, playCurTime) {
            var ani = this._anis[aniIndex];
            var nodes = ani.nodes;
            if (aniIndex !== this.unfixedLastAniIndex) {
                this.unfixedCurrentFrameIndexes = new Uint32Array(nodes.length);
                this.unfixedCurrentTimes = new Float32Array(nodes.length);
                this.unfixedLastAniIndex = aniIndex;
            }
            for (var i = 0, n = nodes.length; i < n; i++) {
                var node = nodes[i];
                if (playCurTime < this.unfixedCurrentTimes[i])
                    this.unfixedCurrentFrameIndexes[i] = 0;
                this.unfixedCurrentTimes[i] = playCurTime;
                while ((this.unfixedCurrentFrameIndexes[i] < node.keyFrame.length)) {
                    if (node.keyFrame[this.unfixedCurrentFrameIndexes[i]].startTime > this.unfixedCurrentTimes[i])
                        break;
                    this.unfixedCurrentFrameIndexes[i]++;
                }
                this.unfixedCurrentFrameIndexes[i]--;
            }
            return this.unfixedCurrentFrameIndexes;
        }
        getOriginalDataUnfixedRate(aniIndex, originalData, playCurTime) {
            var oneAni = this._anis[aniIndex];
            var nodes = oneAni.nodes;
            if (aniIndex !== this.unfixedLastAniIndex) {
                this.unfixedCurrentFrameIndexes = new Uint32Array(nodes.length);
                this.unfixedCurrentTimes = new Float32Array(nodes.length);
                this.unfixedKeyframes = [];
                this.unfixedLastAniIndex = aniIndex;
            }
            var j = 0;
            for (var i = 0, n = nodes.length, outOfs = 0; i < n; i++) {
                var node = nodes[i];
                if (playCurTime < this.unfixedCurrentTimes[i])
                    this.unfixedCurrentFrameIndexes[i] = 0;
                this.unfixedCurrentTimes[i] = playCurTime;
                while (this.unfixedCurrentFrameIndexes[i] < node.keyFrame.length) {
                    if (node.keyFrame[this.unfixedCurrentFrameIndexes[i]].startTime > this.unfixedCurrentTimes[i])
                        break;
                    this.unfixedKeyframes[i] = node.keyFrame[this.unfixedCurrentFrameIndexes[i]];
                    this.unfixedCurrentFrameIndexes[i]++;
                }
                var key = this.unfixedKeyframes[i];
                node.dataOffset = outOfs;
                var dt = playCurTime - key.startTime;
                var lerpType = node.lerpType;
                if (lerpType) {
                    switch (node.lerpType) {
                        case 0:
                        case 1:
                            for (j = 0; j < node.keyframeWidth;)
                                j += node.interpolationMethod[j](node, j, originalData, outOfs + j, key.data, dt, key.dData, key.duration, key.nextData);
                            break;
                        case 2:
                            var interpolationData = key.interpolationData;
                            var interDataLen = interpolationData.length;
                            var dataIndex = 0;
                            for (j = 0; j < interDataLen;) {
                                var type = interpolationData[j];
                                switch (type) {
                                    case 6:
                                        j += AnimationTemplet.interpolation[type](node, dataIndex, originalData, outOfs + dataIndex, key.data, dt, key.dData, key.duration, key.nextData, interpolationData, j + 1);
                                        break;
                                    case 7:
                                        j += AnimationTemplet.interpolation[type](node, dataIndex, originalData, outOfs + dataIndex, key.data, dt, key.dData, key.duration, key.nextData, interpolationData, j + 1);
                                        break;
                                    default:
                                        j += AnimationTemplet.interpolation[type](node, dataIndex, originalData, outOfs + dataIndex, key.data, dt, key.dData, key.duration, key.nextData);
                                }
                                dataIndex++;
                            }
                            break;
                    }
                }
                else {
                    for (j = 0; j < node.keyframeWidth;)
                        j += node.interpolationMethod[j](node, j, originalData, outOfs + j, key.data, dt, key.dData, key.duration, key.nextData);
                }
                outOfs += node.keyframeWidth;
            }
        }
    }
    AnimationTemplet.interpolation = [AnimationTemplet._LinearInterpolation_0, AnimationTemplet._QuaternionInterpolation_1, AnimationTemplet._AngleInterpolation_2, AnimationTemplet._RadiansInterpolation_3, AnimationTemplet._Matrix4x4Interpolation_4, AnimationTemplet._NoInterpolation_5, AnimationTemplet._BezierInterpolation_6, AnimationTemplet._BezierInterpolation_7];
    IAniLib.AnimationTemplet = AnimationTemplet;

    class GraphicsAni extends Laya.Graphics {
        drawSkin(skinA, alpha) {
            this.drawTriangles(skinA.texture, 0, 0, skinA.vertices, skinA.uvs, skinA.indexes, skinA.transform || Laya.Matrix.EMPTY, alpha);
        }
        static create() {
            var rs = GraphicsAni._caches.pop();
            return rs || new GraphicsAni();
        }
        static recycle(graphics) {
            graphics.clear();
            GraphicsAni._caches.push(graphics);
        }
    }
    GraphicsAni._caches = [];

    class Transform {
        constructor() {
            this.skX = 0;
            this.skY = 0;
            this.scX = 1;
            this.scY = 1;
            this.x = 0;
            this.y = 0;
            this.skewX = 0;
            this.skewY = 0;
        }
        initData(data) {
            if (data.x != undefined) {
                this.x = data.x;
            }
            if (data.y != undefined) {
                this.y = data.y;
            }
            if (data.skX != undefined) {
                this.skX = data.skX;
            }
            if (data.skY != undefined) {
                this.skY = data.skY;
            }
            if (data.scX != undefined) {
                this.scX = data.scX;
            }
            if (data.scY != undefined) {
                this.scY = data.scY;
            }
        }
        getMatrix() {
            var tMatrix;
            if (this.mMatrix) {
                tMatrix = this.mMatrix;
            }
            else {
                tMatrix = this.mMatrix = new Laya.Matrix();
            }
            tMatrix.identity();
            tMatrix.scale(this.scX, this.scY);
            if (this.skewX || this.skewY) {
                this.skew(tMatrix, this.skewX * Math.PI / 180, this.skewY * Math.PI / 180);
            }
            tMatrix.rotate(this.skX * Math.PI / 180);
            tMatrix.translate(this.x, this.y);
            return tMatrix;
        }
        skew(m, x, y) {
            var sinX = Math.sin(y);
            var cosX = Math.cos(y);
            var sinY = Math.sin(x);
            var cosY = Math.cos(x);
            m.setTo(m.a * cosY - m.b * sinX, m.a * sinY + m.b * cosX, m.c * cosY - m.d * sinX, m.c * sinY + m.d * cosX, m.tx * cosY - m.ty * sinX, m.tx * sinY + m.ty * cosX);
            return m;
        }
    }

    class Bone {
        constructor() {
            this.length = 10;
            this.resultTransform = new Transform();
            this.resultMatrix = new Laya.Matrix();
            this.inheritScale = true;
            this.inheritRotation = true;
            this.d = -1;
            this._children = [];
        }
        setTempMatrix(matrix) {
            this._tempMatrix = matrix;
            var i = 0, n = 0;
            var tBone;
            for (i = 0, n = this._children.length; i < n; i++) {
                tBone = this._children[i];
                tBone.setTempMatrix(this._tempMatrix);
            }
        }
        update(pMatrix = null) {
            this.rotation = this.transform.skX;
            var tResultMatrix;
            if (pMatrix) {
                tResultMatrix = this.resultTransform.getMatrix();
                Laya.Matrix.mul(tResultMatrix, pMatrix, this.resultMatrix);
                this.resultRotation = this.rotation;
            }
            else {
                this.resultRotation = this.rotation + this.parentBone.resultRotation;
                if (this.parentBone) {
                    if (this.inheritRotation && this.inheritScale) {
                        tResultMatrix = this.resultTransform.getMatrix();
                        Laya.Matrix.mul(tResultMatrix, this.parentBone.resultMatrix, this.resultMatrix);
                    }
                    else {
                        var parent = this.parentBone;
                        var tAngle;
                        var cos;
                        var sin;
                        var tParentMatrix = this.parentBone.resultMatrix;
                        tResultMatrix = this.resultTransform.getMatrix();
                        var worldX = tParentMatrix.a * tResultMatrix.tx + tParentMatrix.c * tResultMatrix.ty + tParentMatrix.tx;
                        var worldY = tParentMatrix.b * tResultMatrix.tx + tParentMatrix.d * tResultMatrix.ty + tParentMatrix.ty;
                        var tTestMatrix = new Laya.Matrix();
                        if (this.inheritRotation) {
                            tAngle = Math.atan2(parent.resultMatrix.b, parent.resultMatrix.a);
                            cos = Math.cos(tAngle), sin = Math.sin(tAngle);
                            tTestMatrix.setTo(cos, sin, -sin, cos, 0, 0);
                            Laya.Matrix.mul(this._tempMatrix, tTestMatrix, Laya.Matrix.TEMP);
                            Laya.Matrix.TEMP.copyTo(tTestMatrix);
                            tResultMatrix = this.resultTransform.getMatrix();
                            Laya.Matrix.mul(tResultMatrix, tTestMatrix, this.resultMatrix);
                            if (this.resultTransform.scX * this.resultTransform.scY < 0) {
                                this.resultMatrix.rotate(Math.PI * 0.5);
                            }
                            this.resultMatrix.tx = worldX;
                            this.resultMatrix.ty = worldY;
                        }
                        else if (this.inheritScale) {
                            tResultMatrix = this.resultTransform.getMatrix();
                            Laya.Matrix.TEMP.identity();
                            Laya.Matrix.TEMP.d = this.d;
                            Laya.Matrix.mul(tResultMatrix, Laya.Matrix.TEMP, this.resultMatrix);
                            this.resultMatrix.tx = worldX;
                            this.resultMatrix.ty = worldY;
                        }
                        else {
                            tResultMatrix = this.resultTransform.getMatrix();
                            Laya.Matrix.TEMP.identity();
                            Laya.Matrix.TEMP.d = this.d;
                            Laya.Matrix.mul(tResultMatrix, Laya.Matrix.TEMP, this.resultMatrix);
                            this.resultMatrix.tx = worldX;
                            this.resultMatrix.ty = worldY;
                        }
                    }
                }
                else {
                    tResultMatrix = this.resultTransform.getMatrix();
                    tResultMatrix.copyTo(this.resultMatrix);
                }
            }
            var i = 0, n = 0;
            var tBone;
            for (i = 0, n = this._children.length; i < n; i++) {
                tBone = this._children[i];
                tBone.update();
            }
        }
        updateChild() {
            var i = 0, n = 0;
            var tBone;
            for (i = 0, n = this._children.length; i < n; i++) {
                tBone = this._children[i];
                tBone.update();
            }
        }
        setRotation(rd) {
            if (this._sprite) {
                this._sprite.rotation = rd * 180 / Math.PI;
            }
        }
        updateDraw(x, y) {
            if (!Bone.ShowBones || Bone.ShowBones[this.name]) {
                if (this._sprite) {
                    this._sprite.x = x + this.resultMatrix.tx;
                    this._sprite.y = y + this.resultMatrix.ty;
                }
                else {
                    this._sprite = new Laya.Sprite();
                    this._sprite.graphics.drawCircle(0, 0, 5, "#ff0000");
                    this._sprite.graphics.drawLine(0, 0, this.length, 0, "#00ff00");
                    this._sprite.graphics.fillText(this.name, 0, 0, "20px Arial", "#00ff00", "center");
                    Laya.ILaya.stage.addChild(this._sprite);
                    this._sprite.x = x + this.resultMatrix.tx;
                    this._sprite.y = y + this.resultMatrix.ty;
                }
            }
            var i = 0, n = 0;
            var tBone;
            for (i = 0, n = this._children.length; i < n; i++) {
                tBone = this._children[i];
                tBone.updateDraw(x, y);
            }
        }
        addChild(bone) {
            this._children.push(bone);
            bone.parentBone = this;
        }
        findBone(boneName) {
            if (this.name == boneName) {
                return this;
            }
            else {
                var i, n;
                var tBone;
                var tResult;
                for (i = 0, n = this._children.length; i < n; i++) {
                    tBone = this._children[i];
                    tResult = tBone.findBone(boneName);
                    if (tResult) {
                        return tResult;
                    }
                }
            }
            return null;
        }
        localToWorld(local) {
            var localX = local[0];
            var localY = local[1];
            local[0] = localX * this.resultMatrix.a + localY * this.resultMatrix.c + this.resultMatrix.tx;
            local[1] = localX * this.resultMatrix.b + localY * this.resultMatrix.d + this.resultMatrix.ty;
        }
    }
    Bone.ShowBones = {};

    class UVTools {
        constructor() {
        }
        static getRelativeUV(bigUV, smallUV, rst = null) {
            var startX = bigUV[0];
            var width = bigUV[2] - bigUV[0];
            var startY = bigUV[1];
            var height = bigUV[5] - bigUV[1];
            if (!rst)
                rst = [];
            rst.length = smallUV.length;
            var i, len;
            len = rst.length;
            var dWidth = 1 / width;
            var dHeight = 1 / height;
            for (i = 0; i < len; i += 2) {
                rst[i] = (smallUV[i] - startX) * dWidth;
                rst[i + 1] = (smallUV[i + 1] - startY) * dHeight;
            }
            return rst;
        }
        static getAbsoluteUV(bigUV, smallUV, rst = null) {
            if (bigUV[0] == 0 && bigUV[1] == 0 && bigUV[4] == 1 && bigUV[5] == 1) {
                if (rst) {
                    Laya.Utils.copyArray(rst, smallUV);
                    return rst;
                }
                else {
                    return smallUV;
                }
            }
            var startX = bigUV[0];
            var width = bigUV[2] - bigUV[0];
            var startY = bigUV[1];
            var height = bigUV[5] - bigUV[1];
            if (!rst)
                rst = [];
            rst.length = smallUV.length;
            var i, len;
            len = rst.length;
            for (i = 0; i < len; i += 2) {
                rst[i] = smallUV[i] * width + startX;
                rst[i + 1] = smallUV[i + 1] * height + startY;
            }
            return rst;
        }
    }

    class MeshData {
        constructor() {
            this.uvs = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]);
            this.vertices = new Float32Array([0, 0, 100, 0, 100, 100, 0, 100]);
            this.indexes = new Uint16Array([0, 1, 3, 3, 1, 2]);
            this.useUvTransform = false;
            this.canvasPadding = 1;
        }
        getBounds() {
            return Laya.Rectangle._getWrapRec(this.vertices);
        }
    }

    class SkinMeshForGraphic extends MeshData {
        constructor() {
            super();
        }
        init2(texture, ps, verticles, uvs) {
            if (this.transform) {
                this.transform = null;
            }
            var _ps = ps || [0, 1, 3, 3, 1, 2];
            this.texture = texture;
            this.indexes = new Uint16Array(_ps);
            this.vertices = new Float32Array(verticles);
            this.uvs = new Float32Array(uvs);
        }
    }

    class BoneSlot {
        constructor() {
            this.srcDisplayIndex = -1;
            this.type = "src";
            this.displayIndex = -1;
            this.originalIndex = -1;
            this._replaceDic = {};
        }
        showSlotData(slotData, freshIndex = true) {
            this.currSlotData = slotData;
            if (freshIndex)
                this.displayIndex = this.srcDisplayIndex;
            this.currDisplayData = null;
            this.currTexture = null;
        }
        showDisplayByName(name) {
            if (this.currSlotData) {
                this.showDisplayByIndex(this.currSlotData.getDisplayByName(name));
            }
        }
        replaceDisplayByName(tarName, newName) {
            if (!this.currSlotData)
                return;
            var preIndex;
            preIndex = this.currSlotData.getDisplayByName(tarName);
            var newIndex;
            newIndex = this.currSlotData.getDisplayByName(newName);
            this.replaceDisplayByIndex(preIndex, newIndex);
        }
        replaceDisplayByIndex(tarIndex, newIndex) {
            if (!this.currSlotData)
                return;
            this._replaceDic[tarIndex] = newIndex;
            if (this.originalIndex == tarIndex) {
                this.showDisplayByIndex(tarIndex);
            }
        }
        showDisplayByIndex(index) {
            this.originalIndex = index;
            if (this._replaceDic[index] != null)
                index = this._replaceDic[index];
            if (this.currSlotData && index > -1 && index < this.currSlotData.displayArr.length) {
                this.displayIndex = index;
                this.currDisplayData = this.currSlotData.displayArr[index];
                if (this.currDisplayData) {
                    var tName = this.currDisplayData.name;
                    this.currTexture = this.templet.getTexture(tName);
                    if (this.currTexture && this.currDisplayData.type == 0 && this.currDisplayData.uvs) {
                        this.currTexture = this.currDisplayData.createTexture(this.currTexture);
                    }
                }
            }
            else {
                this.displayIndex = -1;
                this.currDisplayData = null;
                this.currTexture = null;
            }
        }
        replaceSkin(_texture) {
            this._diyTexture = _texture;
            if (this._curDiyUV)
                this._curDiyUV.length = 0;
            if (this.currDisplayData && this._diyTexture == this.currDisplayData.texture) {
                this._diyTexture = null;
            }
        }
        setParentMatrix(parentMatrix) {
            this._parentMatrix = parentMatrix;
        }
        static createSkinMesh() {
            return new SkinMeshForGraphic();
        }
        static isSameArr(arrA, arrB) {
            if (arrA.length != arrB.length)
                return false;
            var i, len;
            len = arrA.length;
            for (i = 0; i < len; i++) {
                if (arrA[i] != arrB[i])
                    return false;
            }
            return true;
        }
        getSaveVerticle(tArr) {
            if (BoneSlot.useSameMatrixAndVerticle && this._preGraphicVerticle && BoneSlot.isSameArr(tArr, this._preGraphicVerticle)) {
                tArr = this._preGraphicVerticle;
            }
            else {
                tArr = Laya.ILaya.Utils.copyArray([], tArr);
                this._preGraphicVerticle = tArr;
            }
            return tArr;
        }
        static isSameMatrix(mtA, mtB) {
            return mtA.a == mtB.a && mtA.b == mtB.b && mtA.c == mtB.c && mtA.d == mtB.d && Math.abs(mtA.tx - mtB.tx) < 0.00001 && Math.abs(mtA.ty - mtB.ty) < 0.00001;
        }
        getSaveMatrix(tResultMatrix) {
            if (BoneSlot.useSameMatrixAndVerticle && this._preGraphicMatrix && BoneSlot.isSameMatrix(tResultMatrix, this._preGraphicMatrix)) {
                tResultMatrix = this._preGraphicMatrix;
            }
            else {
                var newMatrix = tResultMatrix.clone();
                tResultMatrix = newMatrix;
                this._preGraphicMatrix = tResultMatrix;
            }
            return tResultMatrix;
        }
        draw(graphics, boneMatrixArray, noUseSave = false, alpha = 1) {
            if ((this._diyTexture == null && this.currTexture == null) || this.currDisplayData == null) {
                if (!(this.currDisplayData && this.currDisplayData.type == 3)) {
                    return;
                }
            }
            var tTexture = this.currTexture;
            if (this._diyTexture)
                tTexture = this._diyTexture;
            var tSkinSprite;
            switch (this.currDisplayData.type) {
                case 0:
                    if (graphics) {
                        var tCurrentMatrix = this.getDisplayMatrix();
                        if (this._parentMatrix) {
                            var tRotateKey = false;
                            if (tCurrentMatrix) {
                                Laya.Matrix.mul(tCurrentMatrix, this._parentMatrix, Laya.Matrix.TEMP);
                                var tResultMatrix;
                                if (noUseSave) {
                                    if (this._resultMatrix == null)
                                        this._resultMatrix = new Laya.Matrix();
                                    tResultMatrix = this._resultMatrix;
                                }
                                else {
                                    tResultMatrix = BoneSlot._tempResultMatrix;
                                }
                                if (this._diyTexture && this.currDisplayData.uvs) {
                                    var tTestMatrix = BoneSlot._tempMatrix;
                                    tTestMatrix.identity();
                                    if (this.currDisplayData.uvs[1] > this.currDisplayData.uvs[5]) {
                                        tTestMatrix.d = -1;
                                    }
                                    if (this.currDisplayData.uvs[0] > this.currDisplayData.uvs[4]
                                        && this.currDisplayData.uvs[1] > this.currDisplayData.uvs[5]) {
                                        tRotateKey = true;
                                        tTestMatrix.rotate(-Math.PI / 2);
                                    }
                                    Laya.Matrix.mul(tTestMatrix, Laya.Matrix.TEMP, tResultMatrix);
                                }
                                else {
                                    Laya.Matrix.TEMP.copyTo(tResultMatrix);
                                }
                                if (!noUseSave) {
                                    tResultMatrix = this.getSaveMatrix(tResultMatrix);
                                }
                                tResultMatrix._checkTransform();
                                if (tRotateKey) {
                                    graphics.drawTexture(tTexture, -this.currDisplayData.height / 2, -this.currDisplayData.width / 2, this.currDisplayData.height, this.currDisplayData.width, tResultMatrix, alpha);
                                }
                                else {
                                    graphics.drawTexture(tTexture, -this.currDisplayData.width / 2, -this.currDisplayData.height / 2, this.currDisplayData.width, this.currDisplayData.height, tResultMatrix, alpha);
                                }
                            }
                        }
                    }
                    break;
                case 1:
                    if (noUseSave) {
                        if (this._skinSprite == null) {
                            this._skinSprite = BoneSlot.createSkinMesh();
                        }
                        tSkinSprite = this._skinSprite;
                    }
                    else {
                        tSkinSprite = BoneSlot.createSkinMesh();
                    }
                    if (tSkinSprite == null) {
                        return;
                    }
                    var tIBArray;
                    if (this.currDisplayData.bones == null) {
                        var tVertices = this.currDisplayData.weights;
                        if (this.deformData) {
                            tVertices = this.deformData;
                        }
                        var tUVs;
                        if (this._diyTexture) {
                            if (!this._curDiyUV) {
                                this._curDiyUV = [];
                            }
                            if (this._curDiyUV.length == 0) {
                                this._curDiyUV = UVTools.getRelativeUV(this.currTexture.uv, this.currDisplayData.uvs, this._curDiyUV);
                                this._curDiyUV = UVTools.getAbsoluteUV(this._diyTexture.uv, this._curDiyUV, this._curDiyUV);
                            }
                            tUVs = this._curDiyUV;
                        }
                        else {
                            tUVs = this.currDisplayData.uvs;
                        }
                        this._mVerticleArr = tVertices;
                        var tTriangleNum = this.currDisplayData.triangles.length / 3;
                        tIBArray = this.currDisplayData.triangles;
                        if (this.deformData) {
                            if (!noUseSave) {
                                this._mVerticleArr = this.getSaveVerticle(this._mVerticleArr);
                            }
                        }
                        tSkinSprite.init2(tTexture, tIBArray, this._mVerticleArr, tUVs);
                        var tCurrentMatrix2 = this.getDisplayMatrix();
                        if (this._parentMatrix) {
                            if (tCurrentMatrix2) {
                                Laya.Matrix.mul(tCurrentMatrix2, this._parentMatrix, Laya.Matrix.TEMP);
                                var tResultMatrix2;
                                if (noUseSave) {
                                    if (this._resultMatrix == null)
                                        this._resultMatrix = new Laya.Matrix();
                                    tResultMatrix2 = this._resultMatrix;
                                }
                                else {
                                    tResultMatrix2 = BoneSlot._tempResultMatrix;
                                }
                                Laya.Matrix.TEMP.copyTo(tResultMatrix2);
                                if (!noUseSave) {
                                    tResultMatrix2 = this.getSaveMatrix(tResultMatrix2);
                                }
                                tSkinSprite.transform = tResultMatrix2;
                            }
                        }
                    }
                    else {
                        this.skinMesh(boneMatrixArray, tSkinSprite);
                    }
                    graphics.drawSkin(tSkinSprite, alpha);
                    break;
                case 2:
                    if (noUseSave) {
                        if (this._skinSprite == null) {
                            this._skinSprite = BoneSlot.createSkinMesh();
                        }
                        tSkinSprite = this._skinSprite;
                    }
                    else {
                        tSkinSprite = BoneSlot.createSkinMesh();
                    }
                    if (tSkinSprite == null) {
                        return;
                    }
                    this.skinMesh(boneMatrixArray, tSkinSprite);
                    graphics.drawSkin(tSkinSprite, alpha);
                    break;
                case 3:
                    break;
            }
        }
        skinMesh(boneMatrixArray, skinSprite) {
            var tTexture = this.currTexture;
            var tBones = this.currDisplayData.bones;
            var tUvs;
            if (this._diyTexture) {
                tTexture = this._diyTexture;
                if (!this._curDiyUV) {
                    this._curDiyUV = [];
                }
                if (this._curDiyUV.length == 0) {
                    this._curDiyUV = UVTools.getRelativeUV(this.currTexture.uv, this.currDisplayData.uvs, this._curDiyUV);
                    this._curDiyUV = UVTools.getAbsoluteUV(this._diyTexture.uv, this._curDiyUV, this._curDiyUV);
                }
                tUvs = this._curDiyUV;
            }
            else {
                tUvs = this.currDisplayData.uvs;
            }
            var tWeights = this.currDisplayData.weights;
            var tTriangles = this.currDisplayData.triangles;
            var tIBArray;
            var tRx = 0;
            var tRy = 0;
            var nn = 0;
            var tMatrix;
            var tX;
            var tY;
            var tB = 0;
            var tWeight = 0;
            var tVertices;
            var i = 0, n = 0;
            BoneSlot._tempVerticleArr.length = 0;
            tVertices = BoneSlot._tempVerticleArr;
            if (this.deformData && this.deformData.length > 0) {
                var f = 0;
                for (i = 0, n = tBones.length; i < n;) {
                    nn = tBones[i++] + i;
                    tRx = 0, tRy = 0;
                    for (; i < nn; i++) {
                        tMatrix = boneMatrixArray[tBones[i]];
                        tX = tWeights[tB] + this.deformData[f++];
                        tY = tWeights[tB + 1] + this.deformData[f++];
                        tWeight = tWeights[tB + 2];
                        tRx += (tX * tMatrix.a + tY * tMatrix.c + tMatrix.tx) * tWeight;
                        tRy += (tX * tMatrix.b + tY * tMatrix.d + tMatrix.ty) * tWeight;
                        tB += 3;
                    }
                    tVertices.push(tRx, tRy);
                }
            }
            else {
                for (i = 0, n = tBones.length; i < n;) {
                    nn = tBones[i++] + i;
                    tRx = 0, tRy = 0;
                    for (; i < nn; i++) {
                        tMatrix = boneMatrixArray[tBones[i]];
                        tX = tWeights[tB];
                        tY = tWeights[tB + 1];
                        tWeight = tWeights[tB + 2];
                        tRx += (tX * tMatrix.a + tY * tMatrix.c + tMatrix.tx) * tWeight;
                        tRy += (tX * tMatrix.b + tY * tMatrix.d + tMatrix.ty) * tWeight;
                        tB += 3;
                    }
                    tVertices.push(tRx, tRy);
                }
            }
            this._mVerticleArr = tVertices;
            tIBArray = tTriangles;
            this._mVerticleArr = this.getSaveVerticle(this._mVerticleArr);
            skinSprite.init2(tTexture, tIBArray, this._mVerticleArr, tUvs);
        }
        drawBonePoint(graphics) {
            if (graphics && this._parentMatrix) {
                graphics.drawCircle(this._parentMatrix.tx, this._parentMatrix.ty, 5, "#ff0000");
            }
        }
        getDisplayMatrix() {
            if (this.currDisplayData) {
                return this.currDisplayData.transform.getMatrix();
            }
            return null;
        }
        getMatrix() {
            return this._resultMatrix;
        }
        copy() {
            var tBoneSlot = new BoneSlot();
            tBoneSlot.type = "copy";
            tBoneSlot.name = this.name;
            tBoneSlot.attachmentName = this.attachmentName;
            tBoneSlot.srcDisplayIndex = this.srcDisplayIndex;
            tBoneSlot.parent = this.parent;
            tBoneSlot.displayIndex = this.displayIndex;
            tBoneSlot.templet = this.templet;
            tBoneSlot.currSlotData = this.currSlotData;
            tBoneSlot.currTexture = this.currTexture;
            tBoneSlot.currDisplayData = this.currDisplayData;
            return tBoneSlot;
        }
    }
    BoneSlot._tempMatrix = new Laya.Matrix();
    BoneSlot._tempResultMatrix = new Laya.Matrix();
    BoneSlot.useSameMatrixAndVerticle = true;
    BoneSlot._tempVerticleArr = [];

    class DeformAniData {
        constructor() {
            this.deformSlotDataList = [];
        }
    }

    class DeformSlotData {
        constructor() {
            this.deformSlotDisplayList = [];
        }
    }

    class DeformSlotDisplayData {
        constructor() {
            this.slotIndex = -1;
            this.timeList = [];
            this.vectices = [];
            this.tweenKeyList = [];
            this.frameIndex = 0;
        }
        binarySearch1(values, target) {
            var low = 0;
            var high = values.length - 2;
            if (high == 0)
                return 1;
            var current = high >>> 1;
            while (true) {
                if (values[Math.floor(current + 1)] <= target)
                    low = current + 1;
                else
                    high = current;
                if (low == high)
                    return low + 1;
                current = (low + high) >>> 1;
            }
            return 0;
        }
        apply(time, boneSlot, alpha = 1) {
            time += 0.05;
            if (this.timeList.length <= 0) {
                return;
            }
            var i = 0;
            var tTime = this.timeList[0];
            if (time < tTime) {
                return;
            }
            var tVertexCount = this.vectices[0].length;
            var tVertices = [];
            var tFrameIndex = this.binarySearch1(this.timeList, time);
            this.frameIndex = tFrameIndex;
            if (time >= this.timeList[this.timeList.length - 1]) {
                var lastVertices = this.vectices[this.vectices.length - 1];
                if (alpha < 1) {
                    for (i = 0; i < tVertexCount; i++) {
                        tVertices[i] += (lastVertices[i] - tVertices[i]) * alpha;
                    }
                }
                else {
                    for (i = 0; i < tVertexCount; i++) {
                        tVertices[i] = lastVertices[i];
                    }
                }
                this.deformData = tVertices;
                return;
            }
            var tPrevVertices = this.vectices[this.frameIndex - 1];
            var tNextVertices = this.vectices[this.frameIndex];
            var tPreFrameTime = this.timeList[this.frameIndex - 1];
            var tFrameTime = this.timeList[this.frameIndex];
            if (this.tweenKeyList[tFrameIndex - 1]) {
                alpha = (time - tPreFrameTime) / (tFrameTime - tPreFrameTime);
            }
            else {
                alpha = 0;
            }
            var tPrev;
            for (i = 0; i < tVertexCount; i++) {
                tPrev = tPrevVertices[i];
                tVertices[i] = tPrev + (tNextVertices[i] - tPrev) * alpha;
            }
            this.deformData = tVertices;
        }
    }

    class DrawOrderData {
        constructor() {
            this.drawOrder = [];
        }
    }

    class EventData {
        constructor() {
        }
    }

    class IkConstraint {
        constructor(data, bones) {
            this.isSpine = true;
            this.isDebug = false;
            this._targetBone = bones[data.targetBoneIndex];
            this.isSpine = data.isSpine;
            if (this._bones == null)
                this._bones = [];
            this._bones.length = 0;
            for (var i = 0, n = data.boneIndexs.length; i < n; i++) {
                this._bones.push(bones[data.boneIndexs[i]]);
            }
            this.name = data.name;
            this.mix = data.mix;
            this.bendDirection = data.bendDirection;
        }
        apply() {
            switch (this._bones.length) {
                case 1:
                    this._applyIk1(this._bones[0], this._targetBone.resultMatrix.tx, this._targetBone.resultMatrix.ty, this.mix);
                    break;
                case 2:
                    if (this.isSpine) {
                        this._applyIk2(this._bones[0], this._bones[1], this._targetBone.resultMatrix.tx, this._targetBone.resultMatrix.ty, this.bendDirection, this.mix);
                    }
                    else {
                        this._applyIk3(this._bones[0], this._bones[1], this._targetBone.resultMatrix.tx, this._targetBone.resultMatrix.ty, this.bendDirection, this.mix);
                    }
                    break;
            }
        }
        _applyIk1(bone, targetX, targetY, alpha) {
            var pp = bone.parentBone;
            var id = 1 / (pp.resultMatrix.a * pp.resultMatrix.d - pp.resultMatrix.b * pp.resultMatrix.c);
            var x = targetX - pp.resultMatrix.tx;
            var y = targetY - pp.resultMatrix.ty;
            var tx = (x * pp.resultMatrix.d - y * pp.resultMatrix.c) * id - bone.transform.x;
            var ty = (y * pp.resultMatrix.a - x * pp.resultMatrix.b) * id - bone.transform.y;
            var rotationIK = Math.atan2(ty, tx) * IkConstraint.radDeg - 0 - bone.transform.skX;
            if (bone.transform.scX < 0)
                rotationIK += 180;
            if (rotationIK > 180)
                rotationIK -= 360;
            else if (rotationIK < -180)
                rotationIK += 360;
            bone.transform.skX = bone.transform.skY = bone.transform.skX + rotationIK * alpha;
            bone.update();
        }
        updatePos(x, y) {
            if (this._sp) {
                this._sp.pos(x, y);
            }
        }
        _applyIk2(parent, child, targetX, targetY, bendDir, alpha) {
            if (alpha == 0) {
                return;
            }
            var px = parent.resultTransform.x, py = parent.resultTransform.y;
            var psx = parent.transform.scX, psy = parent.transform.scY;
            var csx = child.transform.scX;
            var os1, os2, s2;
            if (psx < 0) {
                psx = -psx;
                os1 = 180;
                s2 = -1;
            }
            else {
                os1 = 0;
                s2 = 1;
            }
            if (psy < 0) {
                psy = -psy;
                s2 = -s2;
            }
            if (csx < 0) {
                csx = -csx;
                os2 = 180;
            }
            else {
                os2 = 0;
            }
            var cx = child.resultTransform.x, cy, cwx, cwy;
            var a = parent.resultMatrix.a, b = parent.resultMatrix.c;
            var c = parent.resultMatrix.b, d = parent.resultMatrix.d;
            var u = Math.abs(psx - psy) <= 0.0001;
            if (!u) {
                cy = 0;
                cwx = a * cx + parent.resultMatrix.tx;
                cwy = c * cx + parent.resultMatrix.ty;
            }
            else {
                cy = child.resultTransform.y;
                cwx = a * cx + b * cy + parent.resultMatrix.tx;
                cwy = c * cx + d * cy + parent.resultMatrix.ty;
            }
            if (this.isDebug) {
                if (!this._sp) {
                    this._sp = new Laya.Sprite();
                    Laya.ILaya.stage.addChild(this._sp);
                }
                this._sp.graphics.clear();
                this._sp.graphics.drawCircle(targetX, targetY, 15, "#ffff00");
                this._sp.graphics.drawCircle(cwx, cwy, 15, "#ff00ff");
            }
            parent.setRotation(Math.atan2(cwy - parent.resultMatrix.ty, cwx - parent.resultMatrix.tx));
            var pp = parent.parentBone;
            a = pp.resultMatrix.a;
            b = pp.resultMatrix.c;
            c = pp.resultMatrix.b;
            d = pp.resultMatrix.d;
            var id = 1 / (a * d - b * c);
            var x = targetX - pp.resultMatrix.tx, y = targetY - pp.resultMatrix.ty;
            var tx = (x * d - y * b) * id - px;
            var ty = (y * a - x * c) * id - py;
            x = cwx - pp.resultMatrix.tx;
            y = cwy - pp.resultMatrix.ty;
            var dx = (x * d - y * b) * id - px;
            var dy = (y * a - x * c) * id - py;
            var l1 = Math.sqrt(dx * dx + dy * dy);
            var l2 = child.length * csx;
            var a1, a2;
            if (u) {
                l2 *= psx;
                var cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
                if (cos < -1)
                    cos = -1;
                else if (cos > 1)
                    cos = 1;
                a2 = Math.acos(cos) * bendDir;
                a = l1 + l2 * cos;
                b = l2 * Math.sin(a2);
                a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b);
            }
            else {
                a = psx * l2;
                b = psy * l2;
                var aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = Math.atan2(ty, tx);
                c = bb * l1 * l1 + aa * dd - aa * bb;
                var c1 = -2 * bb * l1, c2 = bb - aa;
                d = c1 * c1 - 4 * c2 * c;
                if (d > 0) {
                    var q = Math.sqrt(d);
                    if (c1 < 0)
                        q = -q;
                    q = -(c1 + q) / 2;
                    var r0 = q / c2, r1 = c / q;
                    var r = Math.abs(r0) < Math.abs(r1) ? r0 : r1;
                    if (r * r <= dd) {
                        y = Math.sqrt(dd - r * r) * bendDir;
                        a1 = ta - Math.atan2(y, r);
                        a2 = Math.atan2(y / psy, (r - l1) / psx);
                    }
                }
                var minAngle = 0, minDist = Number.MAX_VALUE, minX = 0, minY = 0;
                var maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
                x = l1 + a;
                d = x * x;
                if (d > maxDist) {
                    maxAngle = 0;
                    maxDist = d;
                    maxX = x;
                }
                x = l1 - a;
                d = x * x;
                if (d < minDist) {
                    minAngle = Math.PI;
                    minDist = d;
                    minX = x;
                }
                var angle = Math.acos(-a * l1 / (aa - bb));
                x = a * Math.cos(angle) + l1;
                y = b * Math.sin(angle);
                d = x * x + y * y;
                if (d < minDist) {
                    minAngle = angle;
                    minDist = d;
                    minX = x;
                    minY = y;
                }
                if (d > maxDist) {
                    maxAngle = angle;
                    maxDist = d;
                    maxX = x;
                    maxY = y;
                }
                if (dd <= (minDist + maxDist) / 2) {
                    a1 = ta - Math.atan2(minY * bendDir, minX);
                    a2 = minAngle * bendDir;
                }
                else {
                    a1 = ta - Math.atan2(maxY * bendDir, maxX);
                    a2 = maxAngle * bendDir;
                }
            }
            var os = Math.atan2(cy, cx) * s2;
            var rotation = parent.resultTransform.skX;
            a1 = (a1 - os) * IkConstraint.radDeg + os1 - rotation;
            if (a1 > 180)
                a1 -= 360;
            else if (a1 < -180)
                a1 += 360;
            parent.resultTransform.x = px;
            parent.resultTransform.y = py;
            parent.resultTransform.skX = parent.resultTransform.skY = rotation + a1 * alpha;
            rotation = child.resultTransform.skX;
            rotation = rotation % 360;
            a2 = ((a2 + os) * IkConstraint.radDeg - 0) * s2 + os2 - rotation;
            if (a2 > 180)
                a2 -= 360;
            else if (a2 < -180)
                a2 += 360;
            child.resultTransform.x = cx;
            child.resultTransform.y = cy;
            child.resultTransform.skX = child.resultTransform.skY = child.resultTransform.skY + a2 * alpha;
            parent.update();
        }
        _applyIk3(parent, child, targetX, targetY, bendDir, alpha) {
            if (alpha == 0) {
                return;
            }
            var cwx, cwy;
            const x = child.resultMatrix.a * child.length;
            const y = child.resultMatrix.b * child.length;
            const lLL = x * x + y * y;
            const lL = Math.sqrt(lLL);
            var parentX = parent.resultMatrix.tx;
            var parentY = parent.resultMatrix.ty;
            var childX = child.resultMatrix.tx;
            var childY = child.resultMatrix.ty;
            var dX = childX - parentX;
            var dY = childY - parentY;
            const lPP = dX * dX + dY * dY;
            const lP = Math.sqrt(lPP);
            dX = targetX - parent.resultMatrix.tx;
            dY = targetY - parent.resultMatrix.ty;
            const lTT = dX * dX + dY * dY;
            const lT = Math.sqrt(lTT);
            if (lL + lP <= lT || lT + lL <= lP || lT + lP <= lL) {
                var rate;
                if (lL + lP <= lT) {
                    rate = 1;
                }
                else {
                    rate = -1;
                }
                childX = parentX + rate * (targetX - parentX) * lP / lT;
                childY = parentY + rate * (targetY - parentY) * lP / lT;
            }
            else {
                const h = (lPP - lLL + lTT) / (2 * lTT);
                const r = Math.sqrt(lPP - h * h * lTT) / lT;
                const hX = parentX + (dX * h);
                const hY = parentY + (dY * h);
                const rX = -dY * r;
                const rY = dX * r;
                if (bendDir > 0) {
                    childX = hX - rX;
                    childY = hY - rY;
                }
                else {
                    childX = hX + rX;
                    childY = hY + rY;
                }
            }
            cwx = childX;
            cwy = childY;
            if (this.isDebug) {
                if (!this._sp) {
                    this._sp = new Laya.Sprite();
                    Laya.ILaya.stage.addChild(this._sp);
                }
                this._sp.graphics.clear();
                this._sp.graphics.drawCircle(parentX, parentY, 15, "#ff00ff");
                this._sp.graphics.drawCircle(targetX, targetY, 15, "#ffff00");
                this._sp.graphics.drawCircle(cwx, cwy, 15, "#ff00ff");
            }
            var pRotation;
            pRotation = Math.atan2(cwy - parent.resultMatrix.ty, cwx - parent.resultMatrix.tx);
            parent.setRotation(pRotation);
            var pTarMatrix;
            pTarMatrix = IkConstraint._tempMatrix;
            pTarMatrix.identity();
            pTarMatrix.rotate(pRotation);
            pTarMatrix.scale(parent.resultMatrix.getScaleX(), parent.resultMatrix.getScaleY());
            pTarMatrix.translate(parent.resultMatrix.tx, parent.resultMatrix.ty);
            pTarMatrix.copyTo(parent.resultMatrix);
            parent.updateChild();
            var childRotation;
            childRotation = Math.atan2(targetY - cwy, targetX - cwx);
            child.setRotation(childRotation);
            var childTarMatrix;
            childTarMatrix = IkConstraint._tempMatrix;
            childTarMatrix.identity();
            childTarMatrix.rotate(childRotation);
            childTarMatrix.scale(child.resultMatrix.getScaleX(), child.resultMatrix.getScaleY());
            childTarMatrix.translate(cwx, cwy);
            pTarMatrix.copyTo(child.resultMatrix);
            child.updateChild();
        }
    }
    IkConstraint.radDeg = 180 / Math.PI;
    IkConstraint.degRad = Math.PI / 180;
    IkConstraint._tempMatrix = new Laya.Matrix();

    class IkConstraintData {
        constructor() {
            this.boneNames = [];
            this.bendDirection = 1;
            this.mix = 1;
            this.isSpine = true;
            this.targetBoneIndex = -1;
            this.boneIndexs = [];
        }
    }

    class PathConstraint {
        constructor(data, bones) {
            this._debugKey = false;
            this._segments = [];
            this._curves = [];
            this.data = data;
            this.position = data.position;
            this.spacing = data.spacing;
            this.rotateMix = data.rotateMix;
            this.translateMix = data.translateMix;
            this.bones = [];
            var tBoneIds = this.data.bones;
            for (var i = 0, n = tBoneIds.length; i < n; i++) {
                this.bones.push(bones[tBoneIds[i]]);
            }
        }
        apply(boneList, graphics) {
            if (!this.target)
                return;
            var tTranslateMix = this.translateMix;
            var tRotateMix = this.translateMix;
            var tRotate = tRotateMix > 0;
            var tSpacingMode = this.data.spacingMode;
            var tLengthSpacing = tSpacingMode == "length";
            var tRotateMode = this.data.rotateMode;
            var tTangents = tRotateMode == "tangent";
            var tScale = tRotateMode == "chainScale";
            var lengths = [];
            var boneCount = this.bones.length;
            var spacesCount = tTangents ? boneCount : boneCount + 1;
            var spaces = [];
            this._spaces = spaces;
            spaces[0] = this.position;
            var spacing = this.spacing;
            if (tScale || tLengthSpacing) {
                for (var i = 0, n = spacesCount - 1; i < n;) {
                    var bone = this.bones[i];
                    var length = bone.length;
                    var x = length * bone.resultMatrix.a;
                    var y = length * bone.resultMatrix.b;
                    length = Math.sqrt(x * x + y * y);
                    if (tScale)
                        lengths[i] = length;
                    spaces[++i] = tLengthSpacing ? Math.max(0, length + spacing) : spacing;
                }
            }
            else {
                for (i = 1; i < spacesCount; i++) {
                    spaces[i] = spacing;
                }
            }
            var positions = this.computeWorldPositions(this.target, boneList, graphics, spacesCount, tTangents, this.data.positionMode == "percent", tSpacingMode == "percent");
            if (this._debugKey) {
                for (i = 0; i < positions.length; i++) {
                    graphics.drawCircle(positions[i++], positions[i++], 5, "#00ff00");
                }
                var tLinePos = [];
                for (i = 0; i < positions.length; i++) {
                    tLinePos.push(positions[i++], positions[i++]);
                }
                graphics.drawLines(0, 0, tLinePos, "#ff0000");
            }
            var boneX = positions[0];
            var boneY = positions[1];
            var offsetRotation = this.data.offsetRotation;
            var tip = tRotateMode == "chain" && offsetRotation == 0;
            var p;
            for (i = 0, p = 3; i < boneCount; i++, p += 3) {
                bone = this.bones[i];
                bone.resultMatrix.tx += (boneX - bone.resultMatrix.tx) * tTranslateMix;
                bone.resultMatrix.ty += (boneY - bone.resultMatrix.ty) * tTranslateMix;
                x = positions[p];
                y = positions[p + 1];
                var dx = x - boneX, dy = y - boneY;
                if (tScale) {
                    length = lengths[i];
                    if (length != 0) {
                        var s = (Math.sqrt(dx * dx + dy * dy) / length - 1) * tRotateMix + 1;
                        bone.resultMatrix.a *= s;
                        bone.resultMatrix.c *= s;
                    }
                }
                boneX = x;
                boneY = y;
                if (tRotate) {
                    var a = bone.resultMatrix.a;
                    var b = bone.resultMatrix.c;
                    var c = bone.resultMatrix.b;
                    var d = bone.resultMatrix.d;
                    var r;
                    var cos;
                    var sin;
                    if (tTangents) {
                        r = positions[p - 1];
                    }
                    else if (spaces[i + 1] == 0) {
                        r = positions[p + 2];
                    }
                    else {
                        r = Math.atan2(dy, dx);
                    }
                    r -= Math.atan2(c, a) - offsetRotation / 180 * Math.PI;
                    if (tip) {
                        cos = Math.cos(r);
                        sin = Math.sin(r);
                        length = bone.length;
                        boneX += (length * (cos * a - sin * c) - dx) * tRotateMix;
                        boneY += (length * (sin * a + cos * c) - dy) * tRotateMix;
                    }
                    if (r > Math.PI) {
                        r -= (Math.PI * 2);
                    }
                    else if (r < -Math.PI) {
                        r += (Math.PI * 2);
                    }
                    r *= tRotateMix;
                    cos = Math.cos(r);
                    sin = Math.sin(r);
                    bone.resultMatrix.a = cos * a - sin * c;
                    bone.resultMatrix.c = cos * b - sin * d;
                    bone.resultMatrix.b = sin * a + cos * c;
                    bone.resultMatrix.d = sin * b + cos * d;
                }
            }
        }
        computeWorldVertices2(boneSlot, boneList, start, count, worldVertices, offset) {
            var tBones = boneSlot.currDisplayData.bones;
            var tWeights = boneSlot.currDisplayData.weights;
            var tTriangles = boneSlot.currDisplayData.triangles;
            var tMatrix;
            var i = 0;
            var v = 0;
            var skip = 0;
            var n = 0;
            var w = 0;
            var b = 0;
            var wx = 0;
            var wy = 0;
            var vx = 0;
            var vy = 0;
            var bone;
            var len;
            if (tBones == null) {
                if (!tTriangles)
                    tTriangles = tWeights;
                if (boneSlot.deformData)
                    tTriangles = boneSlot.deformData;
                var parentName;
                parentName = boneSlot.parent;
                if (boneList) {
                    len = boneList.length;
                    for (i = 0; i < len; i++) {
                        if (boneList[i].name == parentName) {
                            bone = boneList[i];
                            break;
                        }
                    }
                }
                var tBoneMt;
                if (bone) {
                    tBoneMt = bone.resultMatrix;
                }
                if (!tBoneMt)
                    tBoneMt = PathConstraint._tempMt;
                var x = tBoneMt.tx;
                var y = tBoneMt.ty;
                var a = tBoneMt.a, bb = tBoneMt.b, c = tBoneMt.c, d = tBoneMt.d;
                if (bone)
                    d *= bone.d;
                for (v = start, w = offset; w < count; v += 2, w += 2) {
                    vx = tTriangles[v], vy = tTriangles[v + 1];
                    worldVertices[w] = vx * a + vy * bb + x;
                    worldVertices[w + 1] = -(vx * c + vy * d + y);
                }
                return;
            }
            for (i = 0; i < start; i += 2) {
                n = tBones[v];
                v += n + 1;
                skip += n;
            }
            var skeletonBones = boneList;
            for (w = offset, b = skip * 3; w < count; w += 2) {
                wx = 0, wy = 0;
                n = tBones[v++];
                n += v;
                for (; v < n; v++, b += 3) {
                    tMatrix = skeletonBones[tBones[v]].resultMatrix;
                    vx = tWeights[b];
                    vy = tWeights[b + 1];
                    var weight = tWeights[b + 2];
                    wx += (vx * tMatrix.a + vy * tMatrix.c + tMatrix.tx) * weight;
                    wy += (vx * tMatrix.b + vy * tMatrix.d + tMatrix.ty) * weight;
                }
                worldVertices[w] = wx;
                worldVertices[w + 1] = wy;
            }
        }
        computeWorldPositions(boneSlot, boneList, graphics, spacesCount, tangents, percentPosition, percentSpacing) {
            var tBones = boneSlot.currDisplayData.bones;
            var tWeights = boneSlot.currDisplayData.weights;
            var tTriangles = boneSlot.currDisplayData.triangles;
            var tVertices = [];
            var i = 0;
            var verticesLength = boneSlot.currDisplayData.verLen;
            var position = this.position;
            var spaces = this._spaces;
            var world = [];
            var out = [];
            var curveCount = verticesLength / 6;
            var prevCurve = -1;
            var pathLength;
            var o, curve;
            var p;
            var space;
            var prev;
            var length;
            {
                curveCount--;
                verticesLength -= 4;
                this.computeWorldVertices2(boneSlot, boneList, 2, verticesLength, tVertices, 0);
                if (this._debugKey) {
                    for (i = 0; i < tVertices.length;) {
                        graphics.drawCircle(tVertices[i++], tVertices[i++], 10, "#ff0000");
                    }
                }
                world = tVertices;
            }
            this._curves.length = curveCount;
            var curves = this._curves;
            pathLength = 0;
            var x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0;
            var tmpx, tmpy, dddfx, dddfy, ddfx, ddfy, dfx, dfy;
            var w;
            for (i = 0, w = 2; i < curveCount; i++, w += 6) {
                cx1 = world[w];
                cy1 = world[w + 1];
                cx2 = world[w + 2];
                cy2 = world[w + 3];
                x2 = world[w + 4];
                y2 = world[w + 5];
                tmpx = (x1 - cx1 * 2 + cx2) * 0.1875;
                tmpy = (y1 - cy1 * 2 + cy2) * 0.1875;
                dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375;
                dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375;
                ddfx = tmpx * 2 + dddfx;
                ddfy = tmpy * 2 + dddfy;
                dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667;
                dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667;
                pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
                dfx += ddfx;
                dfy += ddfy;
                ddfx += dddfx;
                ddfy += dddfy;
                pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
                dfx += ddfx;
                dfy += ddfy;
                pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
                dfx += ddfx + dddfx;
                dfy += ddfy + dddfy;
                pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
                curves[i] = pathLength;
                x1 = x2;
                y1 = y2;
            }
            if (percentPosition)
                position *= pathLength;
            if (percentSpacing) {
                for (i = 0; i < spacesCount; i++)
                    spaces[i] *= pathLength;
            }
            var segments = this._segments;
            var curveLength = 0;
            var segment;
            for (i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) {
                space = spaces[i];
                position += space;
                p = position;
                if (p < 0) {
                    this.addBeforePosition(p, world, 0, out, o);
                    continue;
                }
                else if (p > pathLength) {
                    this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o);
                    continue;
                }
                for (;; curve++) {
                    length = curves[curve];
                    if (p > length)
                        continue;
                    if (curve == 0)
                        p /= length;
                    else {
                        prev = curves[curve - 1];
                        p = (p - prev) / (length - prev);
                    }
                    break;
                }
                if (curve != prevCurve) {
                    prevCurve = curve;
                    var ii = curve * 6;
                    x1 = world[ii];
                    y1 = world[ii + 1];
                    cx1 = world[ii + 2];
                    cy1 = world[ii + 3];
                    cx2 = world[ii + 4];
                    cy2 = world[ii + 5];
                    x2 = world[ii + 6];
                    y2 = world[ii + 7];
                    tmpx = (x1 - cx1 * 2 + cx2) * 0.03;
                    tmpy = (y1 - cy1 * 2 + cy2) * 0.03;
                    dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006;
                    dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006;
                    ddfx = tmpx * 2 + dddfx;
                    ddfy = tmpy * 2 + dddfy;
                    dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667;
                    dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667;
                    curveLength = Math.sqrt(dfx * dfx + dfy * dfy);
                    segments[0] = curveLength;
                    for (ii = 1; ii < 8; ii++) {
                        dfx += ddfx;
                        dfy += ddfy;
                        ddfx += dddfx;
                        ddfy += dddfy;
                        curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
                        segments[ii] = curveLength;
                    }
                    dfx += ddfx;
                    dfy += ddfy;
                    curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
                    segments[8] = curveLength;
                    dfx += ddfx + dddfx;
                    dfy += ddfy + dddfy;
                    curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
                    segments[9] = curveLength;
                    segment = 0;
                }
                p *= curveLength;
                for (;; segment++) {
                    length = segments[segment];
                    if (p > length)
                        continue;
                    if (segment == 0)
                        p /= length;
                    else {
                        prev = segments[segment - 1];
                        p = segment + (p - prev) / (length - prev);
                    }
                    break;
                }
                this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0));
            }
            return out;
        }
        addBeforePosition(p, temp, i, out, o) {
            var x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx);
            out[o] = x1 + p * Math.cos(r);
            out[o + 1] = y1 + p * Math.sin(r);
            out[o + 2] = r;
        }
        addAfterPosition(p, temp, i, out, o) {
            var x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx);
            out[o] = x1 + p * Math.cos(r);
            out[o + 1] = y1 + p * Math.sin(r);
            out[o + 2] = r;
        }
        addCurvePosition(p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) {
            if (p == 0)
                p = 0.0001;
            var tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u;
            var ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p;
            var x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt;
            out[o] = x;
            out[o + 1] = y;
            if (tangents) {
                out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
            }
            else {
                out[o + 2] = 0;
            }
        }
    }
    PathConstraint.BEFORE = -2;
    PathConstraint.AFTER = -3;
    PathConstraint._tempMt = new Laya.Matrix();

    class PathConstraintData {
        constructor() {
            this.bones = [];
        }
    }

    class TfConstraint {
        constructor(data, bones) {
            this._temp = [];
            this._data = data;
            if (this._bones == null) {
                this._bones = [];
            }
            this.target = bones[data.targetIndex];
            var j, n;
            for (j = 0, n = data.boneIndexs.length; j < n; j++) {
                this._bones.push(bones[data.boneIndexs[j]]);
            }
            this.rotateMix = data.rotateMix;
            this.translateMix = data.translateMix;
            this.scaleMix = data.scaleMix;
            this.shearMix = data.shearMix;
        }
        apply() {
            var tTfBone;
            var ta = this.target.resultMatrix.a, tb = this.target.resultMatrix.b, tc = this.target.resultMatrix.c, td = this.target.resultMatrix.d;
            for (var j = 0, n = this._bones.length; j < n; j++) {
                tTfBone = this._bones[j];
                if (this.rotateMix > 0) {
                    var a = tTfBone.resultMatrix.a, b = tTfBone.resultMatrix.b, c = tTfBone.resultMatrix.c, d = tTfBone.resultMatrix.d;
                    var r = Math.atan2(tc, ta) - Math.atan2(c, a) + this._data.offsetRotation * Math.PI / 180;
                    if (r > Math.PI)
                        r -= Math.PI * 2;
                    else if (r < -Math.PI)
                        r += Math.PI * 2;
                    r *= this.rotateMix;
                    var cos = Math.cos(r), sin = Math.sin(r);
                    tTfBone.resultMatrix.a = cos * a - sin * c;
                    tTfBone.resultMatrix.b = cos * b - sin * d;
                    tTfBone.resultMatrix.c = sin * a + cos * c;
                    tTfBone.resultMatrix.d = sin * b + cos * d;
                }
                if (this.translateMix) {
                    this._temp[0] = this._data.offsetX;
                    this._temp[1] = this._data.offsetY;
                    this.target.localToWorld(this._temp);
                    tTfBone.resultMatrix.tx += (this._temp[0] - tTfBone.resultMatrix.tx) * this.translateMix;
                    tTfBone.resultMatrix.ty += (this._temp[1] - tTfBone.resultMatrix.ty) * this.translateMix;
                    tTfBone.updateChild();
                }
                if (this.scaleMix > 0) {
                    var bs = Math.sqrt(tTfBone.resultMatrix.a * tTfBone.resultMatrix.a + tTfBone.resultMatrix.c * tTfBone.resultMatrix.c);
                    var ts = Math.sqrt(ta * ta + tc * tc);
                    var s = bs > 0.00001 ? (bs + (ts - bs + this._data.offsetScaleX) * this.scaleMix) / bs : 0;
                    tTfBone.resultMatrix.a *= s;
                    tTfBone.resultMatrix.c *= s;
                    bs = Math.sqrt(tTfBone.resultMatrix.b * tTfBone.resultMatrix.b + tTfBone.resultMatrix.d * tTfBone.resultMatrix.d);
                    ts = Math.sqrt(tb * tb + td * td);
                    s = bs > 0.00001 ? (bs + (ts - bs + this._data.offsetScaleY) * this.scaleMix) / bs : 0;
                    tTfBone.resultMatrix.b *= s;
                    tTfBone.resultMatrix.d *= s;
                }
                if (this.shearMix > 0) {
                    b = tTfBone.resultMatrix.b, d = tTfBone.resultMatrix.d;
                    var by = Math.atan2(d, b);
                    r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(tTfBone.resultMatrix.c, tTfBone.resultMatrix.a));
                    if (r > Math.PI)
                        r -= Math.PI * 2;
                    else if (r < -Math.PI)
                        r += Math.PI * 2;
                    r = by + (r + this._data.offsetShearY * Math.PI / 180) * this.shearMix;
                    s = Math.sqrt(b * b + d * d);
                    tTfBone.resultMatrix.b = Math.cos(r) * s;
                    tTfBone.resultMatrix.d = Math.sin(r) * s;
                }
            }
        }
    }

    class Skeleton extends Laya.Sprite {
        constructor(templet = null, aniMode = 0) {
            super();
            this._boneMatrixArray = [];
            this._lastTime = 0;
            this._currAniIndex = -1;
            this._pause = true;
            this._aniClipIndex = -1;
            this._clipIndex = -1;
            this._skinIndex = 0;
            this._skinName = "default";
            this._aniMode = 0;
            this._index = -1;
            this._total = -1;
            this._indexControl = false;
            this._eventIndex = 0;
            this._drawOrderIndex = 0;
            this._drawOrder = null;
            this._lastAniClipIndex = -1;
            this._lastUpdateAniClipIndex = -1;
            this._playAudio = true;
            this._soundChannelArr = [];
            if (templet)
                this.init(templet, aniMode);
        }
        init(templet, aniMode = 0) {
            var i = 0, n;
            if (aniMode == 1) {
                this._graphicsCache = [];
                for (i = 0, n = templet.getAnimationCount(); i < n; i++) {
                    this._graphicsCache.push([]);
                }
            }
            this._yReverseMatrix = templet.yReverseMatrix;
            this._aniMode = aniMode;
            this._templet = templet;
            this._templet._addReference(1);
            this._player = new AnimationPlayer();
            this._player.cacheFrameRate = templet.rate;
            this._player.templet = templet;
            this._player.play();
            this._parseSrcBoneMatrix();
            this._boneList = templet.mBoneArr;
            this._rootBone = templet.mRootBone;
            this._aniSectionDic = templet.aniSectionDic;
            if (templet.ikArr.length > 0) {
                this._ikArr = [];
                for (i = 0, n = templet.ikArr.length; i < n; i++) {
                    this._ikArr.push(new IkConstraint(templet.ikArr[i], this._boneList));
                }
            }
            if (templet.pathArr.length > 0) {
                var tPathData;
                var tPathConstraint;
                if (this._pathDic == null)
                    this._pathDic = {};
                var tBoneSlot;
                for (i = 0, n = templet.pathArr.length; i < n; i++) {
                    tPathData = templet.pathArr[i];
                    tPathConstraint = new PathConstraint(tPathData, this._boneList);
                    tBoneSlot = this._boneSlotDic[tPathData.name];
                    if (tBoneSlot) {
                        tPathConstraint = new PathConstraint(tPathData, this._boneList);
                        tPathConstraint.target = tBoneSlot;
                    }
                    this._pathDic[tPathData.name] = tPathConstraint;
                }
            }
            if (templet.tfArr.length > 0) {
                this._tfArr = [];
                for (i = 0, n = templet.tfArr.length; i < n; i++) {
                    this._tfArr.push(new TfConstraint(templet.tfArr[i], this._boneList));
                }
            }
            if (templet.skinDataArray.length > 0) {
                var tSkinData = this._templet.skinDataArray[this._skinIndex];
                this._skinName = tSkinData.name;
            }
            this._player.on(Laya.Event.PLAYED, this, this._onPlay);
            this._player.on(Laya.Event.STOPPED, this, this._onStop);
            this._player.on(Laya.Event.PAUSED, this, this._onPause);
        }
        get url() {
            return this._aniPath;
        }
        set url(path) {
            this.load(path);
        }
        load(path, complete = null, aniMode = 0) {
            this._aniPath = path;
            this._complete = complete;
            this._loadAniMode = aniMode;
            Laya.ILaya.loader.load([{ url: path, type: Laya.ILaya.Loader.BUFFER }], Laya.Handler.create(this, this._onLoaded));
        }
        _onLoaded() {
            var arraybuffer = Laya.ILaya.Loader.getRes(this._aniPath);
            if (arraybuffer == null)
                return;
            if (IAniLib.Templet.TEMPLET_DICTIONARY == null) {
                IAniLib.Templet.TEMPLET_DICTIONARY = {};
            }
            var tFactory;
            tFactory = IAniLib.Templet.TEMPLET_DICTIONARY[this._aniPath];
            if (tFactory) {
                if (tFactory.isParseFail) {
                    this._parseFail();
                }
                else {
                    if (tFactory.isParserComplete) {
                        this._parseComplete();
                    }
                    else {
                        tFactory.on(Laya.Event.COMPLETE, this, this._parseComplete);
                        tFactory.on(Laya.Event.ERROR, this, this._parseFail);
                    }
                }
            }
            else {
                tFactory = new IAniLib.Templet();
                tFactory._setCreateURL(this._aniPath);
                IAniLib.Templet.TEMPLET_DICTIONARY[this._aniPath] = tFactory;
                tFactory.on(Laya.Event.COMPLETE, this, this._parseComplete);
                tFactory.on(Laya.Event.ERROR, this, this._parseFail);
                tFactory.isParserComplete = false;
                tFactory.parseData(null, arraybuffer);
            }
        }
        _parseComplete() {
            var tTemple = IAniLib.Templet.TEMPLET_DICTIONARY[this._aniPath];
            if (tTemple) {
                this.init(tTemple, this._loadAniMode);
                this.play(0, true);
            }
            this._complete && this._complete.runWith(this);
        }
        _parseFail() {
            console.log("[Error]:" + this._aniPath + "解析失败");
        }
        _onPlay() {
            this.event(Laya.Event.PLAYED);
        }
        _onStop() {
            var tEventData;
            var tEventAniArr = this._templet.eventAniArr;
            var tEventArr = tEventAniArr[this._aniClipIndex];
            if (tEventArr && this._eventIndex < tEventArr.length) {
                for (; this._eventIndex < tEventArr.length; this._eventIndex++) {
                    tEventData = tEventArr[this._eventIndex];
                    if (tEventData.time >= this._player.playStart && tEventData.time <= this._player.playEnd) {
                        this.event(Laya.Event.LABEL, tEventData);
                    }
                }
            }
            this._drawOrder = null;
            this.event(Laya.Event.STOPPED);
        }
        _onPause() {
            this.event(Laya.Event.PAUSED);
        }
        _parseSrcBoneMatrix() {
            var i = 0, n = 0;
            n = this._templet.srcBoneMatrixArr.length;
            for (i = 0; i < n; i++) {
                this._boneMatrixArray.push(new Laya.Matrix());
            }
            if (this._aniMode == 0) {
                this._boneSlotDic = this._templet.boneSlotDic;
                this._bindBoneBoneSlotDic = this._templet.bindBoneBoneSlotDic;
                this._boneSlotArray = this._templet.boneSlotArray;
            }
            else {
                if (this._boneSlotDic == null)
                    this._boneSlotDic = {};
                if (this._bindBoneBoneSlotDic == null)
                    this._bindBoneBoneSlotDic = {};
                if (this._boneSlotArray == null)
                    this._boneSlotArray = [];
                var tArr = this._templet.boneSlotArray;
                var tBS;
                var tBSArr;
                for (i = 0, n = tArr.length; i < n; i++) {
                    tBS = tArr[i];
                    tBSArr = this._bindBoneBoneSlotDic[tBS.parent];
                    if (tBSArr == null) {
                        this._bindBoneBoneSlotDic[tBS.parent] = tBSArr = [];
                    }
                    this._boneSlotDic[tBS.name] = tBS = tBS.copy();
                    tBSArr.push(tBS);
                    this._boneSlotArray.push(tBS);
                }
            }
        }
        _emitMissedEvents(startTime, endTime, startIndex = 0) {
            var tEventAniArr = this._templet.eventAniArr;
            var tEventArr = tEventAniArr[this._player.currentAnimationClipIndex];
            if (tEventArr) {
                var i = 0, len;
                var tEventData;
                len = tEventArr.length;
                for (i = startIndex; i < len; i++) {
                    tEventData = tEventArr[i];
                    if (tEventData.time >= this._player.playStart && tEventData.time <= this._player.playEnd) {
                        this.event(Laya.Event.LABEL, tEventData);
                    }
                }
            }
        }
        _update(autoKey = true) {
            if (this._pause)
                return;
            if (autoKey && this._indexControl) {
                return;
            }
            var tCurrTime = this.timer.currTimer;
            var preIndex = this._player.currentKeyframeIndex;
            var dTime = tCurrTime - this._lastTime;
            if (autoKey) {
                this._player._update(dTime);
            }
            else {
                preIndex = -1;
            }
            this._lastTime = tCurrTime;
            if (!this._player)
                return;
            this._index = this._clipIndex = this._player.currentKeyframeIndex;
            if (this._index < 0)
                return;
            if (dTime > 0 && this._clipIndex == preIndex && this._lastUpdateAniClipIndex == this._aniClipIndex) {
                return;
            }
            this._lastUpdateAniClipIndex = this._aniClipIndex;
            if (preIndex > this._clipIndex && this._eventIndex != 0) {
                this._emitMissedEvents(this._player.playStart, this._player.playEnd, this._eventIndex);
                this._eventIndex = 0;
            }
            var tEventArr = this._templet.eventAniArr[this._aniClipIndex];
            var _soundChannel;
            if (tEventArr && this._eventIndex < tEventArr.length) {
                var tEventData = tEventArr[this._eventIndex];
                if (tEventData.time >= this._player.playStart && tEventData.time <= this._player.playEnd) {
                    if (this._player.currentPlayTime >= tEventData.time) {
                        this.event(Laya.Event.LABEL, tEventData);
                        this._eventIndex++;
                        if (this._playAudio && tEventData.audioValue && tEventData.audioValue !== "null" && tEventData.audioValue !== "undefined") {
                            _soundChannel = Laya.SoundManager.playSound(this._player.templet._path + tEventData.audioValue, 1, Laya.Handler.create(this, this._onAniSoundStoped));
                            Laya.SoundManager.playbackRate = this._player.playbackRate;
                            _soundChannel && this._soundChannelArr.push(_soundChannel);
                        }
                    }
                }
                else if (tEventData.time < this._player.playStart && this._playAudio && tEventData.audioValue && tEventData.audioValue !== "null" && tEventData.audioValue !== "undefined") {
                    this._eventIndex++;
                    _soundChannel = Laya.SoundManager.playSound(this._player.templet._path + tEventData.audioValue, 1, Laya.Handler.create(this, this._onAniSoundStoped), null, (this._player.currentPlayTime - tEventData.time) / 1000);
                    Laya.SoundManager.playbackRate = this._player.playbackRate;
                    _soundChannel && this._soundChannelArr.push(_soundChannel);
                }
                else {
                    this._eventIndex++;
                }
            }
            var tGraphics;
            if (this._aniMode == 0) {
                tGraphics = this._templet.getGrahicsDataWithCache(this._aniClipIndex, this._clipIndex) || this._createGraphics();
                if (tGraphics && this.graphics != tGraphics) {
                    this.graphics = tGraphics;
                }
            }
            else if (this._aniMode == 1) {
                tGraphics = this._getGrahicsDataWithCache(this._aniClipIndex, this._clipIndex) || this._createGraphics();
                if (tGraphics && this.graphics != tGraphics) {
                    this.graphics = tGraphics;
                }
            }
            else {
                this._createGraphics();
            }
        }
        _onAniSoundStoped(force) {
            var _channel;
            for (var len = this._soundChannelArr.length, i = 0; i < len; i++) {
                _channel = this._soundChannelArr[i];
                if (_channel.isStopped || force) {
                    !_channel.isStopped && _channel.stop();
                    this._soundChannelArr.splice(i, 1);
                    len--;
                    i--;
                }
            }
        }
        _createGraphics(_clipIndex = -1) {
            if (_clipIndex == -1)
                _clipIndex = this._clipIndex;
            var curTime = _clipIndex * this._player.cacheFrameRateInterval;
            var tDrawOrderData;
            var tDrawOrderAniArr = this._templet.drawOrderAniArr;
            var tDrawOrderArr = tDrawOrderAniArr[this._aniClipIndex];
            if (tDrawOrderArr && tDrawOrderArr.length > 0) {
                this._drawOrderIndex = 0;
                tDrawOrderData = tDrawOrderArr[this._drawOrderIndex];
                while (curTime >= tDrawOrderData.time) {
                    this._drawOrder = tDrawOrderData.drawOrder;
                    this._drawOrderIndex++;
                    if (this._drawOrderIndex >= tDrawOrderArr.length) {
                        break;
                    }
                    tDrawOrderData = tDrawOrderArr[this._drawOrderIndex];
                }
            }
            if (this._aniMode == 0 || this._aniMode == 1) {
                this.graphics = GraphicsAni.create();
            }
            else {
                if (this.graphics instanceof GraphicsAni) {
                    this.graphics.clear();
                }
                else {
                    this.graphics = GraphicsAni.create();
                }
            }
            var tGraphics = this.graphics;
            var bones = this._templet.getNodes(this._aniClipIndex);
            var stopped = this._player.state == 0;
            this._templet.getOriginalData(this._aniClipIndex, this._curOriginalData, null, _clipIndex, stopped ? (curTime + this._player.cacheFrameRateInterval) : curTime);
            var tSectionArr = this._aniSectionDic[this._aniClipIndex];
            var tStartIndex = 0;
            var i = 0, j = 0, k = 0, n = 0;
            var tDBBoneSlot;
            var tDBBoneSlotArr;
            var tParentTransform;
            var tSrcBone;
            var boneCount = this._templet.srcBoneMatrixArr.length;
            var origDt = this._curOriginalData;
            for (i = 0, n = tSectionArr[0]; i < boneCount; i++) {
                tSrcBone = this._boneList[i];
                var resultTrans = tSrcBone.resultTransform;
                tParentTransform = this._templet.srcBoneMatrixArr[i];
                resultTrans.scX = tParentTransform.scX * origDt[tStartIndex++];
                resultTrans.skX = tParentTransform.skX + origDt[tStartIndex++];
                resultTrans.skY = tParentTransform.skY + origDt[tStartIndex++];
                resultTrans.scY = tParentTransform.scY * origDt[tStartIndex++];
                resultTrans.x = tParentTransform.x + origDt[tStartIndex++];
                resultTrans.y = tParentTransform.y + origDt[tStartIndex++];
                if (this._templet.tMatrixDataLen === 8) {
                    resultTrans.skewX = tParentTransform.skewX + origDt[tStartIndex++];
                    resultTrans.skewY = tParentTransform.skewY + origDt[tStartIndex++];
                }
            }
            var tSlotDic = {};
            var tSlotAlphaDic = {};
            var tBoneData;
            for (n += tSectionArr[1]; i < n; i++) {
                tBoneData = bones[i];
                tSlotDic[tBoneData.name] = origDt[tStartIndex++];
                tSlotAlphaDic[tBoneData.name] = origDt[tStartIndex++];
                tStartIndex += 4;
            }
            var tBendDirectionDic = {};
            var tMixDic = {};
            for (n += tSectionArr[2]; i < n; i++) {
                tBoneData = bones[i];
                tBendDirectionDic[tBoneData.name] = origDt[tStartIndex++];
                tMixDic[tBoneData.name] = origDt[tStartIndex++];
                tStartIndex += 4;
            }
            if (this._pathDic) {
                var tPathConstraint;
                for (n += tSectionArr[3]; i < n; i++) {
                    tBoneData = bones[i];
                    tPathConstraint = this._pathDic[tBoneData.name];
                    if (tPathConstraint) {
                        var tByte = new Laya.Byte(tBoneData.extenData);
                        switch (tByte.getByte()) {
                            case 1:
                                tPathConstraint.position = origDt[tStartIndex++];
                                break;
                            case 2:
                                tPathConstraint.spacing = origDt[tStartIndex++];
                                break;
                            case 3:
                                tPathConstraint.rotateMix = origDt[tStartIndex++];
                                tPathConstraint.translateMix = origDt[tStartIndex++];
                                break;
                        }
                    }
                }
            }
            this._rootBone.update(this._yReverseMatrix || Laya.Matrix.TEMP.identity());
            if (this._ikArr) {
                var tIkConstraint;
                for (i = 0, n = this._ikArr.length; i < n; i++) {
                    tIkConstraint = this._ikArr[i];
                    if (tIkConstraint.name in tBendDirectionDic) {
                        tIkConstraint.bendDirection = tBendDirectionDic[tIkConstraint.name];
                    }
                    if (tIkConstraint.name in tMixDic) {
                        tIkConstraint.mix = tMixDic[tIkConstraint.name];
                    }
                    tIkConstraint.apply();
                }
            }
            if (this._pathDic) {
                for (var tPathStr in this._pathDic) {
                    tPathConstraint = this._pathDic[tPathStr];
                    tPathConstraint.apply(this._boneList, tGraphics);
                }
            }
            if (this._tfArr) {
                var tTfConstraint;
                for (i = 0, k = this._tfArr.length; i < k; i++) {
                    tTfConstraint = this._tfArr[i];
                    tTfConstraint.apply();
                }
            }
            for (i = 0, k = this._boneList.length; i < k; i++) {
                tSrcBone = this._boneList[i];
                tDBBoneSlotArr = this._bindBoneBoneSlotDic[tSrcBone.name];
                tSrcBone.resultMatrix.copyTo(this._boneMatrixArray[i]);
                if (tDBBoneSlotArr) {
                    for (j = 0, n = tDBBoneSlotArr.length; j < n; j++) {
                        tDBBoneSlot = tDBBoneSlotArr[j];
                        if (tDBBoneSlot) {
                            tDBBoneSlot.setParentMatrix(tSrcBone.resultMatrix);
                        }
                    }
                }
            }
            var tDeformDic = {};
            var tDeformAniArr = this._templet.deformAniArr;
            var tDeformAniData;
            if (tDeformAniArr && tDeformAniArr.length > 0) {
                if (this._lastAniClipIndex != this._aniClipIndex) {
                    this._lastAniClipIndex = this._aniClipIndex;
                    for (i = 0, n = this._boneSlotArray.length; i < n; i++) {
                        tDBBoneSlot = this._boneSlotArray[i];
                        tDBBoneSlot.deformData = null;
                    }
                }
                var tSkinDeformAni = tDeformAniArr[this._aniClipIndex];
                tDeformAniData = (tSkinDeformAni["default"]);
                this._setDeform(tDeformAniData, tDeformDic, this._boneSlotArray, curTime);
                var tSkin;
                for (tSkin in tSkinDeformAni) {
                    if (tSkin != "default" && tSkin != this._skinName) {
                        tDeformAniData = tSkinDeformAni[tSkin];
                        this._setDeform(tDeformAniData, tDeformDic, this._boneSlotArray, curTime);
                    }
                }
                tDeformAniData = (tSkinDeformAni[this._skinName]);
                this._setDeform(tDeformAniData, tDeformDic, this._boneSlotArray, curTime);
            }
            var tSlotData2;
            var tSlotData3;
            var tObject;
            if (this._drawOrder) {
                for (i = 0, n = this._drawOrder.length; i < n; i++) {
                    tDBBoneSlot = this._boneSlotArray[this._drawOrder[i]];
                    tSlotData2 = tSlotDic[tDBBoneSlot.name];
                    tSlotData3 = tSlotAlphaDic[tDBBoneSlot.name];
                    if (!isNaN(tSlotData2) && tSlotData2 != -2) {
                        if (this._templet.attachmentNames) {
                            tDBBoneSlot.showDisplayByName(this._templet.attachmentNames[tSlotData2]);
                        }
                        else {
                            tDBBoneSlot.showDisplayByIndex(tSlotData2);
                        }
                    }
                    if (tDeformDic[this._drawOrder[i]]) {
                        tObject = tDeformDic[this._drawOrder[i]];
                        if (tDBBoneSlot.currDisplayData && tObject[tDBBoneSlot.currDisplayData.attachmentName]) {
                            tDBBoneSlot.deformData = tObject[tDBBoneSlot.currDisplayData.attachmentName];
                        }
                        else {
                            tDBBoneSlot.deformData = null;
                        }
                    }
                    else {
                        tDBBoneSlot.deformData = null;
                    }
                    if (!isNaN(tSlotData3)) {
                        tDBBoneSlot.draw(tGraphics, this._boneMatrixArray, this._aniMode == 2, tSlotData3);
                    }
                    else {
                        tDBBoneSlot.draw(tGraphics, this._boneMatrixArray, this._aniMode == 2);
                    }
                }
            }
            else {
                for (i = 0, n = this._boneSlotArray.length; i < n; i++) {
                    tDBBoneSlot = this._boneSlotArray[i];
                    tSlotData2 = tSlotDic[tDBBoneSlot.name];
                    tSlotData3 = tSlotAlphaDic[tDBBoneSlot.name];
                    if (!isNaN(tSlotData2) && tSlotData2 != -2) {
                        if (this._templet.attachmentNames) {
                            tDBBoneSlot.showDisplayByName(this._templet.attachmentNames[tSlotData2]);
                        }
                        else {
                            tDBBoneSlot.showDisplayByIndex(tSlotData2);
                        }
                    }
                    if (tDeformDic[i]) {
                        tObject = tDeformDic[i];
                        if (tDBBoneSlot.currDisplayData && tObject[tDBBoneSlot.currDisplayData.attachmentName]) {
                            tDBBoneSlot.deformData = tObject[tDBBoneSlot.currDisplayData.attachmentName];
                        }
                        else {
                            tDBBoneSlot.deformData = null;
                        }
                    }
                    else {
                        tDBBoneSlot.deformData = null;
                    }
                    if (!isNaN(tSlotData3)) {
                        tDBBoneSlot.draw(tGraphics, this._boneMatrixArray, this._aniMode == 2, tSlotData3);
                    }
                    else {
                        tDBBoneSlot.draw(tGraphics, this._boneMatrixArray, this._aniMode == 2);
                    }
                }
            }
            if (this._aniMode == 0) {
                this._templet.setGrahicsDataWithCache(this._aniClipIndex, _clipIndex, tGraphics);
                this._checkIsAllParsed(this._aniClipIndex);
            }
            else if (this._aniMode == 1) {
                this._setGrahicsDataWithCache(this._aniClipIndex, _clipIndex, tGraphics);
            }
            return tGraphics;
        }
        _checkIsAllParsed(_aniClipIndex) {
            var i, len;
            len = Math.floor(0.01 + this._templet.getAniDuration(_aniClipIndex) / 1000 * this._player.cacheFrameRate);
            for (i = 0; i < len; i++) {
                if (!this._templet.getGrahicsDataWithCache(_aniClipIndex, i))
                    return;
            }
            if (!this._templet.getGrahicsDataWithCache(_aniClipIndex, len)) {
                this._createGraphics(len);
                return;
            }
            this._templet.deleteAniData(_aniClipIndex);
        }
        _setDeform(tDeformAniData, tDeformDic, _boneSlotArray, curTime) {
            if (!tDeformAniData)
                return;
            var tDeformSlotData;
            var tDeformSlotDisplayData;
            var tDBBoneSlot;
            var i, n, j;
            if (tDeformAniData) {
                for (i = 0, n = tDeformAniData.deformSlotDataList.length; i < n; i++) {
                    tDeformSlotData = tDeformAniData.deformSlotDataList[i];
                    for (j = 0; j < tDeformSlotData.deformSlotDisplayList.length; j++) {
                        tDeformSlotDisplayData = tDeformSlotData.deformSlotDisplayList[j];
                        tDBBoneSlot = _boneSlotArray[tDeformSlotDisplayData.slotIndex];
                        tDeformSlotDisplayData.apply(curTime, tDBBoneSlot);
                        if (!tDeformDic[tDeformSlotDisplayData.slotIndex]) {
                            tDeformDic[tDeformSlotDisplayData.slotIndex] = {};
                        }
                        tDeformDic[tDeformSlotDisplayData.slotIndex][tDeformSlotDisplayData.attachment] = tDeformSlotDisplayData.deformData;
                    }
                }
            }
        }
        getAnimNum() {
            return this._templet.getAnimationCount();
        }
        getAniNameByIndex(index) {
            return this._templet.getAniNameByIndex(index);
        }
        getSlotByName(name) {
            return this._boneSlotDic[name];
        }
        showSkinByName(name, freshSlotIndex = true) {
            this.showSkinByIndex(this._templet.getSkinIndexByName(name), freshSlotIndex);
        }
        showSkinByIndex(skinIndex, freshSlotIndex = true) {
            for (var i = 0; i < this._boneSlotArray.length; i++) {
                this._boneSlotArray[i].showSlotData(null, freshSlotIndex);
            }
            if (this._templet.showSkinByIndex(this._boneSlotDic, skinIndex, freshSlotIndex)) {
                var tSkinData = this._templet.skinDataArray[skinIndex];
                this._skinIndex = skinIndex;
                this._skinName = tSkinData.name;
            }
            this._clearCache();
        }
        showSlotSkinByIndex(slotName, index) {
            if (this._aniMode == 0)
                return;
            var tBoneSlot = this.getSlotByName(slotName);
            if (tBoneSlot) {
                tBoneSlot.showDisplayByIndex(index);
            }
            this._clearCache();
        }
        showSlotSkinByName(slotName, name) {
            if (this._aniMode == 0)
                return;
            var tBoneSlot = this.getSlotByName(slotName);
            if (tBoneSlot) {
                tBoneSlot.showDisplayByName(name);
            }
            this._clearCache();
        }
        replaceSlotSkinName(slotName, oldName, newName) {
            if (this._aniMode == 0)
                return;
            var tBoneSlot = this.getSlotByName(slotName);
            if (tBoneSlot) {
                tBoneSlot.replaceDisplayByName(oldName, newName);
            }
            this._clearCache();
        }
        replaceSlotSkinByIndex(slotName, oldIndex, newIndex) {
            if (this._aniMode == 0)
                return;
            var tBoneSlot = this.getSlotByName(slotName);
            if (tBoneSlot) {
                tBoneSlot.replaceDisplayByIndex(oldIndex, newIndex);
            }
            this._clearCache();
        }
        setSlotSkin(slotName, texture) {
            if (this._aniMode == 0)
                return;
            var tBoneSlot = this.getSlotByName(slotName);
            if (tBoneSlot) {
                tBoneSlot.replaceSkin(texture);
            }
            this._clearCache();
        }
        _clearCache() {
            if (this._aniMode == 1) {
                for (var i = 0, n = this._graphicsCache.length; i < n; i++) {
                    for (var j = 0, len = this._graphicsCache[i].length; j < len; j++) {
                        var gp = this._graphicsCache[i][j];
                        if (gp && gp != this.graphics) {
                            GraphicsAni.recycle(gp);
                        }
                    }
                    this._graphicsCache[i].length = 0;
                }
            }
        }
        play(nameOrIndex, loop, force = true, start = 0, end = 0, freshSkin = true, playAudio = true) {
            this._playAudio = playAudio;
            this._indexControl = false;
            var index = -1;
            var duration;
            if (loop) {
                duration = 2147483647;
            }
            else {
                duration = 0;
            }
            if (typeof (nameOrIndex) == 'string') {
                for (var i = 0, n = this._templet.getAnimationCount(); i < n; i++) {
                    var animation = this._templet.getAnimation(i);
                    if (animation && nameOrIndex == animation.name) {
                        index = i;
                        break;
                    }
                }
            }
            else {
                index = nameOrIndex;
            }
            if (index > -1 && index < this.getAnimNum()) {
                this._aniClipIndex = index;
                if (force || this._pause || this._currAniIndex != index) {
                    this._currAniIndex = index;
                    this._curOriginalData = new Float32Array(this._templet.getTotalkeyframesLength(index));
                    this._drawOrder = null;
                    this._eventIndex = 0;
                    this._player.play(index, this._player.playbackRate, duration, start, end);
                    if (freshSkin)
                        this._templet.showSkinByIndex(this._boneSlotDic, this._skinIndex);
                    if (this._pause) {
                        this._pause = false;
                        this._lastTime = Laya.ILaya.Browser.now();
                        this.timer.frameLoop(1, this, this._update, null, true);
                    }
                    this._update();
                }
            }
        }
        stop() {
            if (!this._pause) {
                this._pause = true;
                if (this._player) {
                    this._player.stop(true);
                }
                if (this._soundChannelArr.length > 0) {
                    this._onAniSoundStoped(true);
                }
                this.timer.clear(this, this._update);
            }
        }
        playbackRate(value) {
            if (this._player) {
                this._player.playbackRate = value;
            }
        }
        paused() {
            if (!this._pause) {
                this._pause = true;
                if (this._player) {
                    this._player.paused = true;
                }
                if (this._soundChannelArr.length > 0) {
                    var _soundChannel;
                    for (var len = this._soundChannelArr.length, i = 0; i < len; i++) {
                        _soundChannel = this._soundChannelArr[i];
                        if (!_soundChannel.isStopped) {
                            _soundChannel.pause();
                        }
                    }
                }
                this.timer.clear(this, this._update);
            }
        }
        resume() {
            this._indexControl = false;
            if (this._pause) {
                this._pause = false;
                if (this._player) {
                    this._player.paused = false;
                }
                if (this._soundChannelArr.length > 0) {
                    var _soundChannel;
                    for (var len = this._soundChannelArr.length, i = 0; i < len; i++) {
                        _soundChannel = this._soundChannelArr[i];
                        if (_soundChannel.audioBuffer) {
                            _soundChannel.resume();
                        }
                    }
                }
                this._lastTime = Laya.ILaya.Browser.now();
                this.timer.frameLoop(1, this, this._update, null, true);
            }
        }
        _getGrahicsDataWithCache(aniIndex, frameIndex) {
            return this._graphicsCache[aniIndex][frameIndex];
        }
        _setGrahicsDataWithCache(aniIndex, frameIndex, graphics) {
            this._graphicsCache[aniIndex][frameIndex] = graphics;
        }
        destroy(destroyChild = true) {
            super.destroy(destroyChild);
            this._templet._removeReference(1);
            this._templet = null;
            if (this._player)
                this._player.offAll();
            this._player = null;
            this._curOriginalData = null;
            this._boneMatrixArray.length = 0;
            this._lastTime = 0;
            this.timer.clear(this, this._update);
            if (this._soundChannelArr.length > 0) {
                this._onAniSoundStoped(true);
            }
        }
        get index() {
            return this._index;
        }
        set index(value) {
            if (this.player) {
                this._index = value;
                this._player.currentTime = this._index * 1000 / this._player.cacheFrameRate;
                this._indexControl = true;
                this._update(false);
            }
        }
        get total() {
            if (this._templet && this._player) {
                this._total = Math.floor(this._templet.getAniDuration(this._player.currentAnimationClipIndex) / 1000 * this._player.cacheFrameRate);
            }
            else {
                this._total = -1;
            }
            return this._total;
        }
        get player() {
            return this._player;
        }
        get templet() {
            return this._templet;
        }
    }
    Skeleton.useSimpleMeshInCanvas = false;
    IAniLib.Skeleton = Skeleton;
    Laya.ILaya.regClass(Skeleton);
    Laya.ClassUtils.regClass("laya.ani.bone.Skeleton", Skeleton);
    Laya.ClassUtils.regClass("Laya.Skeleton", Skeleton);

    class SkinData {
        constructor() {
            this.slotArr = [];
        }
    }

    class SkinSlotDisplayData {
        createTexture(currTexture) {
            if (this.texture)
                return this.texture;
            this.texture = new Laya.Texture(currTexture.bitmap, this.uvs);
            if (this.uvs[0] > this.uvs[4]
                && this.uvs[1] > this.uvs[5]) {
                this.texture.width = currTexture.height;
                this.texture.height = currTexture.width;
                this.texture.offsetX = -currTexture.offsetX;
                this.texture.offsetY = -currTexture.offsetY;
                this.texture.sourceWidth = currTexture.sourceHeight;
                this.texture.sourceHeight = currTexture.sourceWidth;
            }
            else {
                this.texture.width = currTexture.width;
                this.texture.height = currTexture.height;
                this.texture.offsetX = -currTexture.offsetX;
                this.texture.offsetY = -currTexture.offsetY;
                this.texture.sourceWidth = currTexture.sourceWidth;
                this.texture.sourceHeight = currTexture.sourceHeight;
            }
            return this.texture;
        }
        destory() {
            if (this.texture)
                this.texture.destroy();
        }
    }

    class SlotData {
        constructor() {
            this.displayArr = [];
        }
        getDisplayByName(name) {
            var tDisplay;
            for (var i = 0, n = this.displayArr.length; i < n; i++) {
                tDisplay = this.displayArr[i];
                if (tDisplay.attachmentName == name) {
                    return i;
                }
            }
            return -1;
        }
    }

    class TfConstraintData {
        constructor() {
            this.boneIndexs = [];
        }
    }

    class Templet extends AnimationTemplet {
        constructor() {
            super(...arguments);
            this._graphicsCache = [];
            this.srcBoneMatrixArr = [];
            this.ikArr = [];
            this.tfArr = [];
            this.pathArr = [];
            this.boneSlotDic = {};
            this.bindBoneBoneSlotDic = {};
            this.boneSlotArray = [];
            this.skinDataArray = [];
            this.skinDic = {};
            this.subTextureDic = {};
            this.isParseFail = false;
            this.drawOrderAniArr = [];
            this.eventAniArr = [];
            this.attachmentNames = null;
            this.deformAniArr = [];
            this.skinSlotDisplayDataArr = [];
            this._isParseAudio = false;
            this._isDestroyed = false;
            this._rate = 30;
            this.isParserComplete = false;
            this.aniSectionDic = {};
            this._textureDic = {};
            this.mBoneArr = [];
        }
        loadAni(url) {
            this._skBufferUrl = url;
            Laya.ILaya.loader.load(url, Laya.Handler.create(this, this.onComplete), null, Laya.ILaya.Loader.BUFFER);
        }
        onComplete(content = null) {
            if (this._isDestroyed) {
                this.destroy();
                return;
            }
            var tSkBuffer = Laya.ILaya.Loader.getRes(this._skBufferUrl);
            if (!tSkBuffer) {
                this.event(Laya.Event.ERROR, "load failed:" + this._skBufferUrl);
                return;
            }
            this._path = this._skBufferUrl.slice(0, this._skBufferUrl.lastIndexOf("/")) + "/";
            this.parseData(null, tSkBuffer);
        }
        parseData(texture, skeletonData, playbackRate = 30) {
            if (!this._path) {
                var s1 = (this._relativeUrl || this.url);
                if (s1) {
                    var p1 = s1.lastIndexOf('/');
                    if (p1 > 0) {
                        this._path = s1.slice(0, p1) + "/";
                    }
                    else {
                        this._path = '';
                    }
                }
            }
            this._mainTexture = texture;
            this._rate = playbackRate;
            this.parse(skeletonData);
        }
        buildArmature(aniMode = 0) {
            return new Skeleton(this, aniMode);
        }
        parse(data) {
            super.parse(data);
            this.event(Laya.Event.LOADED, this);
            if (this._aniVersion === Templet.LAYA_ANIMATION_VISION) {
                this._isParseAudio = true;
            }
            else if (this._aniVersion != Templet.LAYA_ANIMATION_160_VISION) {
                console.log("[Error] 版本不一致，请使用IDE版本配套的重新导出" + this._aniVersion + "->" + Templet.LAYA_ANIMATION_VISION);
            }
            if (this._mainTexture) {
                this._parsePublicExtData();
            }
            else {
                this._parseTexturePath();
            }
        }
        _parseTexturePath() {
            if (this._isDestroyed) {
                this.destroy();
                return;
            }
            var i = 0;
            this._loadList = [];
            var tByte = new Laya.Byte(this.getPublicExtData());
            var tX = 0, tY = 0, tWidth = 0, tHeight = 0;
            var tTempleData = 0;
            var tTextureLen = tByte.getInt32();
            var tTextureName = tByte.readUTFString();
            var tTextureNameArr = tTextureName.split("\n");
            var tSrcTexturePath;
            for (i = 0; i < tTextureLen; i++) {
                tSrcTexturePath = this._path + tTextureNameArr[i * 2];
                tTextureName = tTextureNameArr[i * 2 + 1];
                tX = tByte.getFloat32();
                tY = tByte.getFloat32();
                tWidth = tByte.getFloat32();
                tHeight = tByte.getFloat32();
                tTempleData = tByte.getFloat32();
                tTempleData = tByte.getFloat32();
                tTempleData = tByte.getFloat32();
                tTempleData = tByte.getFloat32();
                if (this._loadList.indexOf(tSrcTexturePath) == -1) {
                    this._loadList.push(tSrcTexturePath);
                }
            }
            Laya.ILaya.loader.load(this._loadList, Laya.Handler.create(this, this._textureComplete));
        }
        _textureComplete() {
            var tTexture;
            var tTextureName;
            for (var i = 0, n = this._loadList.length; i < n; i++) {
                tTextureName = this._loadList[i];
                tTexture = this._textureDic[tTextureName] = Laya.ILaya.Loader.getRes(tTextureName);
            }
            this._parsePublicExtData();
        }
        _parsePublicExtData() {
            var i = 0, j = 0, k = 0, l = 0, n = 0;
            for (i = 0, n = this.getAnimationCount(); i < n; i++) {
                this._graphicsCache.push([]);
            }
            var isSpine;
            isSpine = this._aniClassName != "Dragon";
            var tByte = new Laya.Byte(this.getPublicExtData());
            var tX = 0, tY = 0, tWidth = 0, tHeight = 0;
            var tFrameX = 0, tFrameY = 0, tFrameWidth = 0, tFrameHeight = 0;
            var tTempleData = 0;
            var tTextureLen = tByte.getInt32();
            var tTextureName = tByte.readUTFString();
            var tTextureNameArr = tTextureName.split("\n");
            var tTexture;
            var tSrcTexturePath;
            for (i = 0; i < tTextureLen; i++) {
                tTexture = this._mainTexture;
                tSrcTexturePath = this._path + tTextureNameArr[i * 2];
                tTextureName = tTextureNameArr[i * 2 + 1];
                if (this._mainTexture == null) {
                    tTexture = this._textureDic[tSrcTexturePath];
                }
                if (!tTexture) {
                    this.event(Laya.Event.ERROR, this);
                    this.isParseFail = true;
                    return;
                }
                tX = tByte.getFloat32();
                tY = tByte.getFloat32();
                tWidth = tByte.getFloat32();
                tHeight = tByte.getFloat32();
                tTempleData = tByte.getFloat32();
                tFrameX = isNaN(tTempleData) ? 0 : tTempleData;
                tTempleData = tByte.getFloat32();
                tFrameY = isNaN(tTempleData) ? 0 : tTempleData;
                tTempleData = tByte.getFloat32();
                tFrameWidth = isNaN(tTempleData) ? tWidth : tTempleData;
                tTempleData = tByte.getFloat32();
                tFrameHeight = isNaN(tTempleData) ? tHeight : tTempleData;
                this.subTextureDic[tTextureName] = Laya.Texture.create(tTexture, tX, tY, tWidth, tHeight, -tFrameX, -tFrameY, tFrameWidth, tFrameHeight);
            }
            this._mainTexture = tTexture;
            var tAniCount = tByte.getUint16();
            var tSectionArr;
            for (i = 0; i < tAniCount; i++) {
                tSectionArr = [];
                tSectionArr.push(tByte.getUint16());
                tSectionArr.push(tByte.getUint16());
                tSectionArr.push(tByte.getUint16());
                tSectionArr.push(tByte.getUint16());
                this.aniSectionDic[i] = tSectionArr;
            }
            var tBone;
            var tParentBone;
            var tName;
            var tParentName;
            var tBoneLen = tByte.getInt16();
            var tBoneDic = {};
            var tRootBone;
            for (i = 0; i < tBoneLen; i++) {
                tBone = new Bone();
                if (i == 0) {
                    tRootBone = tBone;
                }
                else {
                    tBone.root = tRootBone;
                }
                tBone.d = isSpine ? -1 : 1;
                tName = tByte.readUTFString();
                tParentName = tByte.readUTFString();
                tBone.length = tByte.getFloat32();
                if (tByte.getByte() == 1) {
                    tBone.inheritRotation = false;
                }
                if (tByte.getByte() == 1) {
                    tBone.inheritScale = false;
                }
                tBone.name = tName;
                if (tParentName) {
                    tParentBone = tBoneDic[tParentName];
                    if (tParentBone) {
                        tParentBone.addChild(tBone);
                    }
                    else {
                        this.mRootBone = tBone;
                    }
                }
                tBoneDic[tName] = tBone;
                this.mBoneArr.push(tBone);
            }
            this.tMatrixDataLen = tByte.getUint16();
            var tLen = tByte.getUint16();
            var boneLength = Math.floor(tLen / this.tMatrixDataLen);
            var tResultTransform;
            var tMatrixArray = this.srcBoneMatrixArr;
            for (i = 0; i < boneLength; i++) {
                tResultTransform = new Transform();
                tResultTransform.scX = tByte.getFloat32();
                tResultTransform.skX = tByte.getFloat32();
                tResultTransform.skY = tByte.getFloat32();
                tResultTransform.scY = tByte.getFloat32();
                tResultTransform.x = tByte.getFloat32();
                tResultTransform.y = tByte.getFloat32();
                if (this.tMatrixDataLen === 8) {
                    tResultTransform.skewX = tByte.getFloat32();
                    tResultTransform.skewY = tByte.getFloat32();
                }
                tMatrixArray.push(tResultTransform);
                tBone = this.mBoneArr[i];
                tBone.transform = tResultTransform;
            }
            var tIkConstraintData;
            var tIkLen = tByte.getUint16();
            var tIkBoneLen;
            for (i = 0; i < tIkLen; i++) {
                tIkConstraintData = new IkConstraintData();
                tIkBoneLen = tByte.getUint16();
                for (j = 0; j < tIkBoneLen; j++) {
                    tIkConstraintData.boneNames.push(tByte.readUTFString());
                    tIkConstraintData.boneIndexs.push(tByte.getInt16());
                }
                tIkConstraintData.name = tByte.readUTFString();
                tIkConstraintData.targetBoneName = tByte.readUTFString();
                tIkConstraintData.targetBoneIndex = tByte.getInt16();
                tIkConstraintData.bendDirection = tByte.getFloat32();
                tIkConstraintData.mix = tByte.getFloat32();
                tIkConstraintData.isSpine = isSpine;
                this.ikArr.push(tIkConstraintData);
            }
            var tTfConstraintData;
            var tTfLen = tByte.getUint16();
            var tTfBoneLen;
            for (i = 0; i < tTfLen; i++) {
                tTfConstraintData = new TfConstraintData();
                tTfBoneLen = tByte.getUint16();
                for (j = 0; j < tTfBoneLen; j++) {
                    tTfConstraintData.boneIndexs.push(tByte.getInt16());
                }
                tTfConstraintData.name = tByte.getUTFString();
                tTfConstraintData.targetIndex = tByte.getInt16();
                tTfConstraintData.rotateMix = tByte.getFloat32();
                tTfConstraintData.translateMix = tByte.getFloat32();
                tTfConstraintData.scaleMix = tByte.getFloat32();
                tTfConstraintData.shearMix = tByte.getFloat32();
                tTfConstraintData.offsetRotation = tByte.getFloat32();
                tTfConstraintData.offsetX = tByte.getFloat32();
                tTfConstraintData.offsetY = tByte.getFloat32();
                tTfConstraintData.offsetScaleX = tByte.getFloat32();
                tTfConstraintData.offsetScaleY = tByte.getFloat32();
                tTfConstraintData.offsetShearY = tByte.getFloat32();
                this.tfArr.push(tTfConstraintData);
            }
            var tPathConstraintData;
            var tPathLen = tByte.getUint16();
            var tPathBoneLen;
            for (i = 0; i < tPathLen; i++) {
                tPathConstraintData = new PathConstraintData();
                tPathConstraintData.name = tByte.readUTFString();
                tPathBoneLen = tByte.getUint16();
                for (j = 0; j < tPathBoneLen; j++) {
                    tPathConstraintData.bones.push(tByte.getInt16());
                }
                tPathConstraintData.target = tByte.readUTFString();
                tPathConstraintData.positionMode = tByte.readUTFString();
                tPathConstraintData.spacingMode = tByte.readUTFString();
                tPathConstraintData.rotateMode = tByte.readUTFString();
                tPathConstraintData.offsetRotation = tByte.getFloat32();
                tPathConstraintData.position = tByte.getFloat32();
                tPathConstraintData.spacing = tByte.getFloat32();
                tPathConstraintData.rotateMix = tByte.getFloat32();
                tPathConstraintData.translateMix = tByte.getFloat32();
                this.pathArr.push(tPathConstraintData);
            }
            var tDeformSlotLen;
            var tDeformSlotDisplayLen;
            var tDSlotIndex;
            var tDAttachment;
            var tDeformTimeLen;
            var tDTime;
            var tDeformVecticesLen;
            var tDeformAniData;
            var tDeformSlotData;
            var tDeformSlotDisplayData;
            var tDeformVectices;
            var tDeformAniLen = tByte.getInt16();
            for (i = 0; i < tDeformAniLen; i++) {
                var tDeformSkinLen = tByte.getUint8();
                var tSkinDic = {};
                this.deformAniArr.push(tSkinDic);
                for (var f = 0; f < tDeformSkinLen; f++) {
                    tDeformAniData = new DeformAniData();
                    tDeformAniData.skinName = tByte.getUTFString();
                    tSkinDic[tDeformAniData.skinName] = tDeformAniData;
                    tDeformSlotLen = tByte.getInt16();
                    for (j = 0; j < tDeformSlotLen; j++) {
                        tDeformSlotData = new DeformSlotData();
                        tDeformAniData.deformSlotDataList.push(tDeformSlotData);
                        tDeformSlotDisplayLen = tByte.getInt16();
                        for (k = 0; k < tDeformSlotDisplayLen; k++) {
                            tDeformSlotDisplayData = new DeformSlotDisplayData();
                            tDeformSlotData.deformSlotDisplayList.push(tDeformSlotDisplayData);
                            tDeformSlotDisplayData.slotIndex = tDSlotIndex = tByte.getInt16();
                            tDeformSlotDisplayData.attachment = tDAttachment = tByte.getUTFString();
                            tDeformTimeLen = tByte.getInt16();
                            for (l = 0; l < tDeformTimeLen; l++) {
                                if (tByte.getByte() == 1) {
                                    tDeformSlotDisplayData.tweenKeyList.push(true);
                                }
                                else {
                                    tDeformSlotDisplayData.tweenKeyList.push(false);
                                }
                                tDTime = tByte.getFloat32();
                                tDeformSlotDisplayData.timeList.push(tDTime);
                                tDeformVectices = [];
                                tDeformSlotDisplayData.vectices.push(tDeformVectices);
                                tDeformVecticesLen = tByte.getInt16();
                                for (n = 0; n < tDeformVecticesLen; n++) {
                                    tDeformVectices.push(tByte.getFloat32());
                                }
                            }
                        }
                    }
                }
            }
            var tDrawOrderArr;
            var tDrawOrderAniLen = tByte.getInt16();
            var tDrawOrderLen;
            var tDrawOrderData;
            var tDoLen;
            for (i = 0; i < tDrawOrderAniLen; i++) {
                tDrawOrderLen = tByte.getInt16();
                tDrawOrderArr = [];
                for (j = 0; j < tDrawOrderLen; j++) {
                    tDrawOrderData = new DrawOrderData();
                    tDrawOrderData.time = tByte.getFloat32();
                    tDoLen = tByte.getInt16();
                    for (k = 0; k < tDoLen; k++) {
                        tDrawOrderData.drawOrder.push(tByte.getInt16());
                    }
                    tDrawOrderArr.push(tDrawOrderData);
                }
                this.drawOrderAniArr.push(tDrawOrderArr);
            }
            var tEventArr;
            var tEventAniLen = tByte.getInt16();
            var tEventLen;
            var tEventData;
            for (i = 0; i < tEventAniLen; i++) {
                tEventLen = tByte.getInt16();
                tEventArr = [];
                for (j = 0; j < tEventLen; j++) {
                    tEventData = new EventData();
                    tEventData.name = tByte.getUTFString();
                    if (this._isParseAudio)
                        tEventData.audioValue = tByte.getUTFString();
                    tEventData.intValue = tByte.getInt32();
                    tEventData.floatValue = tByte.getFloat32();
                    tEventData.stringValue = tByte.getUTFString();
                    tEventData.time = tByte.getFloat32();
                    tEventArr.push(tEventData);
                }
                this.eventAniArr.push(tEventArr);
            }
            var tAttachmentLen = tByte.getInt16();
            if (tAttachmentLen > 0) {
                this.attachmentNames = [];
                for (i = 0; i < tAttachmentLen; i++) {
                    this.attachmentNames.push(tByte.getUTFString());
                }
            }
            var tBoneSlotLen = tByte.getInt16();
            var tDBBoneSlot;
            var tDBBoneSlotArr;
            for (i = 0; i < tBoneSlotLen; i++) {
                tDBBoneSlot = new BoneSlot();
                tDBBoneSlot.name = tByte.readUTFString();
                tDBBoneSlot.parent = tByte.readUTFString();
                tDBBoneSlot.attachmentName = tByte.readUTFString();
                tDBBoneSlot.srcDisplayIndex = tDBBoneSlot.displayIndex = tByte.getInt16();
                tDBBoneSlot.templet = this;
                this.boneSlotDic[tDBBoneSlot.name] = tDBBoneSlot;
                tDBBoneSlotArr = this.bindBoneBoneSlotDic[tDBBoneSlot.parent];
                if (tDBBoneSlotArr == null) {
                    this.bindBoneBoneSlotDic[tDBBoneSlot.parent] = tDBBoneSlotArr = [];
                }
                tDBBoneSlotArr.push(tDBBoneSlot);
                this.boneSlotArray.push(tDBBoneSlot);
            }
            var tNameString = tByte.readUTFString();
            var tNameArray = tNameString.split("\n");
            var tNameStartIndex = 0;
            var tSkinDataLen = tByte.getUint8();
            var tSkinData, tSlotData, tDisplayData;
            var tSlotDataLen, tDisplayDataLen;
            var tUvLen, tWeightLen, tTriangleLen, tVerticeLen, tLengthLen;
            for (i = 0; i < tSkinDataLen; i++) {
                tSkinData = new SkinData();
                tSkinData.name = tNameArray[tNameStartIndex++];
                tSlotDataLen = tByte.getUint8();
                for (j = 0; j < tSlotDataLen; j++) {
                    tSlotData = new SlotData();
                    tSlotData.name = tNameArray[tNameStartIndex++];
                    tDBBoneSlot = this.boneSlotDic[tSlotData.name];
                    tDisplayDataLen = tByte.getUint8();
                    for (k = 0; k < tDisplayDataLen; k++) {
                        tDisplayData = new SkinSlotDisplayData();
                        this.skinSlotDisplayDataArr.push(tDisplayData);
                        tDisplayData.name = tNameArray[tNameStartIndex++];
                        tDisplayData.attachmentName = tNameArray[tNameStartIndex++];
                        tDisplayData.transform = new Transform();
                        tDisplayData.transform.scX = tByte.getFloat32();
                        tDisplayData.transform.skX = tByte.getFloat32();
                        tDisplayData.transform.skY = tByte.getFloat32();
                        tDisplayData.transform.scY = tByte.getFloat32();
                        tDisplayData.transform.x = tByte.getFloat32();
                        tDisplayData.transform.y = tByte.getFloat32();
                        tSlotData.displayArr.push(tDisplayData);
                        tDisplayData.width = tByte.getFloat32();
                        tDisplayData.height = tByte.getFloat32();
                        tDisplayData.type = tByte.getUint8();
                        tDisplayData.verLen = tByte.getUint16();
                        tBoneLen = tByte.getUint16();
                        if (tBoneLen > 0) {
                            tDisplayData.bones = [];
                            for (l = 0; l < tBoneLen; l++) {
                                var tBoneId = tByte.getUint16();
                                tDisplayData.bones.push(tBoneId);
                            }
                        }
                        tUvLen = tByte.getUint16();
                        if (tUvLen > 0) {
                            tDisplayData.uvs = [];
                            for (l = 0; l < tUvLen; l++) {
                                tDisplayData.uvs.push(tByte.getFloat32());
                            }
                        }
                        tWeightLen = tByte.getUint16();
                        if (tWeightLen > 0) {
                            tDisplayData.weights = [];
                            for (l = 0; l < tWeightLen; l++) {
                                tDisplayData.weights.push(tByte.getFloat32());
                            }
                        }
                        tTriangleLen = tByte.getUint16();
                        if (tTriangleLen > 0) {
                            tDisplayData.triangles = [];
                            for (l = 0; l < tTriangleLen; l++) {
                                tDisplayData.triangles.push(tByte.getUint16());
                            }
                        }
                        tVerticeLen = tByte.getUint16();
                        if (tVerticeLen > 0) {
                            tDisplayData.vertices = [];
                            for (l = 0; l < tVerticeLen; l++) {
                                tDisplayData.vertices.push(tByte.getFloat32());
                            }
                        }
                        tLengthLen = tByte.getUint16();
                        if (tLengthLen > 0) {
                            tDisplayData.lengths = [];
                            for (l = 0; l < tLengthLen; l++) {
                                tDisplayData.lengths.push(tByte.getFloat32());
                            }
                        }
                    }
                    tSkinData.slotArr.push(tSlotData);
                }
                this.skinDic[tSkinData.name] = tSkinData;
                this.skinDataArray.push(tSkinData);
            }
            var tReverse = tByte.getUint8();
            if (tReverse == 1) {
                this.yReverseMatrix = new Laya.Matrix(1, 0, 0, -1, 0, 0);
                if (tRootBone) {
                    tRootBone.setTempMatrix(this.yReverseMatrix);
                }
            }
            else {
                if (tRootBone) {
                    tRootBone.setTempMatrix(new Laya.Matrix());
                }
            }
            this.showSkinByIndex(this.boneSlotDic, 0);
            this.isParserComplete = true;
            this.event(Laya.Event.COMPLETE, this);
        }
        getTexture(name) {
            var tTexture = this.subTextureDic[name];
            if (!tTexture) {
                tTexture = this.subTextureDic[name.substr(0, name.length - 1)];
            }
            if (tTexture == null) {
                return this._mainTexture;
            }
            return tTexture;
        }
        showSkinByIndex(boneSlotDic, skinIndex, freshDisplayIndex = true) {
            if (skinIndex < 0 && skinIndex >= this.skinDataArray.length)
                return false;
            var i, n;
            var tBoneSlot;
            var tSlotData;
            var tSkinData = this.skinDataArray[skinIndex];
            if (tSkinData) {
                for (i = 0, n = tSkinData.slotArr.length; i < n; i++) {
                    tSlotData = tSkinData.slotArr[i];
                    if (tSlotData) {
                        tBoneSlot = boneSlotDic[tSlotData.name];
                        if (tBoneSlot) {
                            tBoneSlot.showSlotData(tSlotData, freshDisplayIndex);
                            if (freshDisplayIndex && tBoneSlot.attachmentName != "undefined" && tBoneSlot.attachmentName != "null") {
                                tBoneSlot.showDisplayByName(tBoneSlot.attachmentName);
                            }
                            else {
                                tBoneSlot.showDisplayByIndex(tBoneSlot.displayIndex);
                            }
                        }
                    }
                }
                return true;
            }
            return false;
        }
        getSkinIndexByName(skinName) {
            var tSkinData;
            for (var i = 0, n = this.skinDataArray.length; i < n; i++) {
                tSkinData = this.skinDataArray[i];
                if (tSkinData.name == skinName) {
                    return i;
                }
            }
            return -1;
        }
        getGrahicsDataWithCache(aniIndex, frameIndex) {
            if (this._graphicsCache[aniIndex] && this._graphicsCache[aniIndex][frameIndex]) {
                return this._graphicsCache[aniIndex][frameIndex];
            }
            return null;
        }
        _setCreateURL(url) {
            this._skBufferUrl = this._relativeUrl = url;
            super._setCreateURL(url);
        }
        setGrahicsDataWithCache(aniIndex, frameIndex, graphics) {
            this._graphicsCache[aniIndex][frameIndex] = graphics;
        }
        deleteAniData(aniIndex) {
            if (this._anis[aniIndex]) {
                var tAniDataO = this._anis[aniIndex];
                tAniDataO.bone3DMap = null;
                tAniDataO.nodes = null;
            }
        }
        destroy() {
            this._isDestroyed = true;
            var tTexture;
            for (tTexture in this.subTextureDic) {
                if (tTexture) {
                    this.subTextureDic[tTexture].destroy();
                }
            }
            for (tTexture in this._textureDic) {
                if (tTexture) {
                    this._textureDic[tTexture].destroy();
                }
            }
            var tSkinSlotDisplayData;
            for (var i = 0, n = this.skinSlotDisplayDataArr.length; i < n; i++) {
                tSkinSlotDisplayData = this.skinSlotDisplayDataArr[i];
                tSkinSlotDisplayData.destory();
            }
            this.skinSlotDisplayDataArr.length = 0;
            if (this._relativeUrl) {
                delete Templet.TEMPLET_DICTIONARY[this._relativeUrl];
            }
            super.destroy();
            Laya.ILaya.loader.clearRes(this._skBufferUrl);
        }
        getAniNameByIndex(index) {
            var tAni = this.getAnimation(index);
            if (tAni)
                return tAni.name;
            return null;
        }
        get rate() {
            return this._rate;
        }
        set rate(v) {
            this._rate = v;
        }
    }
    Templet.LAYA_ANIMATION_160_VISION = "LAYAANIMATION:1.6.0";
    Templet.LAYA_ANIMATION_VISION = "LAYAANIMATION:1.7.0";
    IAniLib.Templet = Templet;

    class MovieClip extends Laya.Sprite {
        constructor(parentMovieClip = null) {
            super();
            this._start = 0;
            this._Pos = 0;
            this._ended = true;
            this._loadedImage = {};
            this._endFrame = -1;
            this.interval = 30;
            this._ids = {};
            this._idOfSprite = [];
            this._reset();
            this._playing = false;
            this._parentMovieClip = parentMovieClip;
            if (!parentMovieClip) {
                this._movieClipList = [this];
                this._isRoot = true;
                this._setBitUp(Laya.Const.DISPLAY);
            }
            else {
                this._isRoot = false;
                this._movieClipList = parentMovieClip._movieClipList;
                this._movieClipList.push(this);
            }
        }
        destroy(destroyChild = true) {
            this._clear();
            super.destroy(destroyChild);
        }
        _setDisplay(value) {
            super._setDisplay(value);
            if (this._isRoot) {
                this._onDisplay(value);
            }
        }
        _onDisplay(value) {
            if (value)
                this.timer.loop(this.interval, this, this.updates, null, true);
            else
                this.timer.clear(this, this.updates);
        }
        updates() {
            if (this._parentMovieClip)
                return;
            var i, len;
            len = this._movieClipList.length;
            for (i = 0; i < len; i++) {
                this._movieClipList[i] && this._movieClipList[i]._update();
            }
        }
        get index() {
            return this._playIndex;
        }
        set index(value) {
            this._playIndex = value;
            if (this._data)
                this._displayFrame(this._playIndex);
            if (this._labels && this._labels[value])
                this.event(Laya.Event.LABEL, this._labels[value]);
        }
        addLabel(label, index) {
            if (!this._labels)
                this._labels = {};
            this._labels[index] = label;
        }
        removeLabel(label) {
            if (!label)
                this._labels = null;
            else if (!this._labels) {
                for (var name in this._labels) {
                    if (this._labels[name] === label) {
                        delete this._labels[name];
                        break;
                    }
                }
            }
        }
        get count() {
            return this._count;
        }
        get playing() {
            return this._playing;
        }
        _update() {
            if (!this._data)
                return;
            if (!this._playing)
                return;
            this._playIndex++;
            if (this._playIndex >= this._count) {
                if (!this.loop) {
                    this._playIndex--;
                    this.stop();
                    return;
                }
                this._playIndex = 0;
            }
            this._parseFrame(this._playIndex);
            if (this._labels && this._labels[this._playIndex])
                this.event(Laya.Event.LABEL, this._labels[this._playIndex]);
            if (this._endFrame != -1 && this._endFrame == this._playIndex) {
                this._endFrame = -1;
                if (this._completeHandler != null) {
                    var handler = this._completeHandler;
                    this._completeHandler = null;
                    handler.run();
                }
                this.stop();
            }
        }
        stop() {
            this._playing = false;
        }
        gotoAndStop(index) {
            this.index = index;
            this.stop();
        }
        _clear() {
            this.stop();
            this._idOfSprite.length = 0;
            if (!this._parentMovieClip) {
                this.timer.clear(this, this.updates);
                var i, len;
                len = this._movieClipList.length;
                for (i = 0; i < len; i++) {
                    if (this._movieClipList[i] != this)
                        this._movieClipList[i]._clear();
                }
                this._movieClipList.length = 0;
            }
            if (this._atlasPath) {
                Laya.ILaya.Loader.clearRes(this._atlasPath);
            }
            var key;
            for (key in this._loadedImage) {
                if (this._loadedImage[key]) {
                    Laya.ILaya.Loader.clearRes(key);
                    this._loadedImage[key] = false;
                }
            }
            this.removeChildren();
            this.graphics = null;
            this._parentMovieClip = null;
        }
        play(index = 0, loop = true) {
            this.loop = loop;
            this._playing = true;
            if (this._data)
                this._displayFrame(index);
        }
        _displayFrame(frameIndex = -1) {
            if (frameIndex != -1) {
                if (this._curIndex > frameIndex)
                    this._reset();
                this._parseFrame(frameIndex);
            }
        }
        _reset(rm = true) {
            if (rm && this._curIndex != 1)
                this.removeChildren();
            this._preIndex = this._curIndex = -1;
            this._Pos = this._start;
        }
        _parseFrame(frameIndex) {
            var mc, sp, key, type, tPos, ttype, ifAdd = false;
            var _idOfSprite = this._idOfSprite, _data = this._data, eStr;
            if (this._ended)
                this._reset();
            _data.pos = this._Pos;
            this._ended = false;
            this._playIndex = frameIndex;
            if (this._curIndex > frameIndex && frameIndex < this._preIndex) {
                this._reset(true);
                _data.pos = this._Pos;
            }
            while ((this._curIndex <= frameIndex) && (!this._ended)) {
                type = _data.getUint16();
                switch (type) {
                    case 12:
                        key = _data.getUint16();
                        tPos = this._ids[_data.getUint16()];
                        this._Pos = _data.pos;
                        _data.pos = tPos;
                        if ((ttype = _data.getUint8()) == 0) {
                            var pid = _data.getUint16();
                            sp = _idOfSprite[key];
                            if (!sp) {
                                sp = _idOfSprite[key] = new Laya.Sprite();
                                var spp = new Laya.Sprite();
                                spp.loadImage(this.basePath + pid + ".png");
                                this._loadedImage[this.basePath + pid + ".png"] = true;
                                sp.addChild(spp);
                                spp.size(_data.getFloat32(), _data.getFloat32());
                                var mat = _data._getMatrix();
                                spp.transform = mat;
                            }
                            sp.alpha = 1;
                        }
                        else if (ttype == 1) {
                            mc = _idOfSprite[key];
                            if (!mc) {
                                _idOfSprite[key] = mc = new MovieClip(this);
                                mc.interval = this.interval;
                                mc._ids = this._ids;
                                mc.basePath = this.basePath;
                                mc._setData(_data, tPos);
                                mc._initState();
                                mc.play(0);
                            }
                            mc.alpha = 1;
                        }
                        _data.pos = this._Pos;
                        break;
                    case 3:
                        var node = _idOfSprite[_data.getUint16()];
                        if (node) {
                            this.addChild(node);
                            node.zOrder = _data.getUint16();
                            ifAdd = true;
                        }
                        break;
                    case 4:
                        node = _idOfSprite[_data.getUint16()];
                        node && node.removeSelf();
                        break;
                    case 5:
                        _idOfSprite[_data.getUint16()][MovieClip._ValueList[_data.getUint16()]] = (_data.getFloat32());
                        break;
                    case 6:
                        _idOfSprite[_data.getUint16()].visible = (_data.getUint8() > 0);
                        break;
                    case 7:
                        sp = _idOfSprite[_data.getUint16()];
                        var mt = sp.transform || Laya.Matrix.create();
                        mt.setTo(_data.getFloat32(), _data.getFloat32(), _data.getFloat32(), _data.getFloat32(), _data.getFloat32(), _data.getFloat32());
                        sp.transform = mt;
                        break;
                    case 8:
                        _idOfSprite[_data.getUint16()].setPos(_data.getFloat32(), _data.getFloat32());
                        break;
                    case 9:
                        _idOfSprite[_data.getUint16()].setSize(_data.getFloat32(), _data.getFloat32());
                        break;
                    case 10:
                        _idOfSprite[_data.getUint16()].alpha = _data.getFloat32();
                        break;
                    case 11:
                        _idOfSprite[_data.getUint16()].setScale(_data.getFloat32(), _data.getFloat32());
                        break;
                    case 98:
                        eStr = _data.getString();
                        this.event(eStr);
                        if (eStr == "stop")
                            this.stop();
                        break;
                    case 99:
                        this._curIndex = _data.getUint16();
                        ifAdd && this.updateZOrder();
                        break;
                    case 100:
                        this._count = this._curIndex + 1;
                        this._ended = true;
                        if (this._playing) {
                            this.event(Laya.Event.FRAME);
                            this.event(Laya.Event.END);
                            this.event(Laya.Event.COMPLETE);
                        }
                        this._reset(false);
                        break;
                }
            }
            if (this._playing && !this._ended)
                this.event(Laya.Event.FRAME);
            this._Pos = _data.pos;
        }
        _setData(data, start) {
            this._data = data;
            this._start = start + 3;
        }
        set url(path) {
            this.load(path);
        }
        load(url, atlas = false, atlasPath = null) {
            this._url = url;
            if (atlas)
                this._atlasPath = atlasPath ? atlasPath : url.split(".swf")[0] + ".json";
            this.stop();
            this._clear();
            this._movieClipList = [this];
            var urls;
            urls = [{ url: url, type: Laya.ILaya.Loader.BUFFER }];
            if (this._atlasPath) {
                urls.push({ url: this._atlasPath, type: Laya.ILaya.Loader.ATLAS });
            }
            Laya.ILaya.loader.load(urls, Laya.Handler.create(this, this._onLoaded));
        }
        _onLoaded() {
            var data;
            data = Laya.ILaya.Loader.getRes(this._url);
            if (!data) {
                this.event(Laya.Event.ERROR, "file not find");
                return;
            }
            if (this._atlasPath && !Laya.ILaya.Loader.getAtlas(this._atlasPath)) {
                this.event(Laya.Event.ERROR, "Atlas not find");
                return;
            }
            this.basePath = this._atlasPath ? Laya.ILaya.Loader.getAtlas(this._atlasPath).dir : this._url.split(".swf")[0] + "/image/";
            this._initData(data);
        }
        _initState() {
            this._reset();
            this._ended = false;
            var preState = this._playing;
            this._playing = false;
            this._curIndex = 0;
            while (!this._ended)
                this._parseFrame(++this._curIndex);
            this._playing = preState;
        }
        _initData(data) {
            this._data = new Laya.Byte(data);
            var i, len = this._data.getUint16();
            for (i = 0; i < len; i++)
                this._ids[this._data.getInt16()] = this._data.getInt32();
            this.interval = 1000 / this._data.getUint16();
            this._setData(this._data, this._ids[32767]);
            this._initState();
            this.play(0);
            this.event(Laya.Event.LOADED);
            if (!this._parentMovieClip)
                this.timer.loop(this.interval, this, this.updates, null, true);
        }
        playTo(start, end, complete = null) {
            this._completeHandler = complete;
            this._endFrame = end;
            this.play(start, false);
        }
    }
    MovieClip._ValueList = ["x", "y", "width", "height", "scaleX", "scaleY", "rotation", "alpha"];

    exports.AnimationContent = AnimationContent;
    exports.AnimationNodeContent = AnimationNodeContent;
    exports.AnimationParser01 = AnimationParser01;
    exports.AnimationParser02 = AnimationParser02;
    exports.AnimationPlayer = AnimationPlayer;
    exports.AnimationState = AnimationState;
    exports.AnimationTemplet = AnimationTemplet;
    exports.BezierLerp = BezierLerp;
    exports.Bone = Bone;
    exports.BoneSlot = BoneSlot;
    exports.DeformAniData = DeformAniData;
    exports.DeformSlotData = DeformSlotData;
    exports.DeformSlotDisplayData = DeformSlotDisplayData;
    exports.DrawOrderData = DrawOrderData;
    exports.EventData = EventData;
    exports.GraphicsAni = GraphicsAni;
    exports.IAniLib = IAniLib;
    exports.IkConstraint = IkConstraint;
    exports.IkConstraintData = IkConstraintData;
    exports.KeyFramesContent = KeyFramesContent;
    exports.MeshData = MeshData;
    exports.MovieClip = MovieClip;
    exports.PathConstraint = PathConstraint;
    exports.PathConstraintData = PathConstraintData;
    exports.Skeleton = Skeleton;
    exports.SkinData = SkinData;
    exports.SkinMeshForGraphic = SkinMeshForGraphic;
    exports.SkinSlotDisplayData = SkinSlotDisplayData;
    exports.SlotData = SlotData;
    exports.Templet = Templet;
    exports.TfConstraint = TfConstraint;
    exports.TfConstraintData = TfConstraintData;
    exports.Transform = Transform;
    exports.UVTools = UVTools;

}(window.Laya = window.Laya|| {}, Laya));
