    /** * @private */Ext.define('Ext.fx.animation.Abstract', {     extend: 'Ext.Evented',     isAnimation: true,     requires: [        'Ext.fx.State'    ],     config: {        name: '',         element: null,         /**         * @cfg         * Before configuration.         */        before: null,         from: {},         to: {},         after: null,         states: {},         duration:  300,         /**         * @cfg         * Easing type.         */        easing: 'linear',         iteration: 1,         direction: 'normal',         delay: 0,         onBeforeStart: null,         callback: null,         onEnd: null,         onBeforeEnd: null,         scope: null,         reverse: null,         preserveEndState: false,         replacePrevious: true    },     STATE_FROM: '0%',     STATE_TO: '100%',     DIRECTION_UP: 'up',     DIRECTION_DOWN: 'down',     DIRECTION_LEFT: 'left',     DIRECTION_RIGHT: 'right',     stateNameRegex: /^(?:[\d\.]+)%$/,     constructor: function() {        this.states = {};         this.callParent(arguments);         return this;    },     applyElement: function(element) {        return Ext.get(element);    },     applyBefore: function(before, current) {        if (before) {            return Ext.factory(before, Ext.fx.State, current);        }    },     applyAfter: function(after, current) {        if (after) {            return Ext.factory(after, Ext.fx.State, current);        }    },     setFrom: function(from) {        return this.setState(this.STATE_FROM, from);    },     setTo: function(to) {        return this.setState(this.STATE_TO, to);    },     getFrom: function() {        return this.getState(this.STATE_FROM);    },     getTo: function() {        return this.getState(this.STATE_TO);    },     setStates: function(states) {        var validNameRegex = this.stateNameRegex,            name;         for (name in states) {            if (validNameRegex.test(name)) {                this.setState(name, states[name]);            }        }         return this;    },     getStates: function() {        return this.states;    },     updateCallback: function(callback) {        if (callback) {            this.setOnEnd(callback);        }    },     end: function() {        // alias for stop so that the following api is the same between ext/touch:         // element.getActiveAnimation().end()         this.stop();    },     stop: function() {        this.fireEvent('stop', this);    },     destroy: function() {        this.stop();        this.callParent();    },     setState: function(name, state) {        var states = this.getStates(),            stateInstance;         stateInstance = Ext.factory(state, Ext.fx.State, states[name]);         if (stateInstance) {            states[name] = stateInstance;        }        //<debug>         else if (name === this.STATE_TO) {            Ext.Logger.error("Setting and invalid '100%' / 'to' state of: " + state);        }        //</debug>          return this;    },     getState: function(name) {        return this.getStates()[name];    },     getData: function() {        var me = this,            states = me.getStates(),            statesData = {},            before = me.getBefore(),            after = me.getAfter(),            from = states[me.STATE_FROM],            to = states[me.STATE_TO],            fromData = from.getData(),            toData = to.getData(),            data, name, state;         for (name in states) {            if (states.hasOwnProperty(name)) {                state = states[name];                data = state.getData();                statesData[name] = data;            }        }         return {            before: before ? before.getData() : {},            after: after ? after.getData() : {},            states: statesData,            from: fromData,            to: toData,            duration: me.getDuration(),            iteration: me.getIteration(),            direction: me.getDirection(),            easing: me.getEasing(),            delay: me.getDelay(),            onEnd: me.getOnEnd(),            onBeforeEnd: me.getOnBeforeEnd(),            onBeforeStart: me.getOnBeforeStart(),            scope: me.getScope(),            preserveEndState: me.getPreserveEndState(),            replacePrevious: me.getReplacePrevious()        };    }});