define( [

"./core",
"./core/camelCase",
"./var/document",
"./var/isFunction",
"./var/rcssNum",
"./var/rnothtmlwhite",
"./css/var/cssExpand",
"./css/var/isHiddenWithinTree",
"./css/var/swap",
"./css/adjustCSS",
"./data/var/dataPriv",
"./css/showHide",

"./core/init",
"./queue",
"./deferred",
"./traversing",
"./manipulation",
"./css",
"./effects/Tween"

], function( jQuery, camelCase, document, isFunction, rcssNum, rnothtmlwhite, cssExpand,

isHiddenWithinTree, swap, adjustCSS, dataPriv, showHide ) {

“use strict”;

var

fxNow, inProgress,
rfxtypes = /^(?:toggle|show|hide)$/,
rrun = /queueHooks$/;

function schedule() {

if ( inProgress ) {
        if ( document.hidden === false && window.requestAnimationFrame ) {
                window.requestAnimationFrame( schedule );
        } else {
                window.setTimeout( schedule, jQuery.fx.interval );
        }

        jQuery.fx.tick();
}

}

// Animations created synchronously will run synchronously function createFxNow() {

window.setTimeout( function() {
        fxNow = undefined;
} );
return ( fxNow = Date.now() );

}

// Generate parameters to create a standard animation function genFx( type, includeWidth ) {

var which,
        i = 0,
        attrs = { height: type };

// If we include width, step value is 1 to do all cssExpand values,
// otherwise step value is 2 to skip over Left and Right
includeWidth = includeWidth ? 1 : 0;
for ( ; i < 4; i += 2 - includeWidth ) {
        which = cssExpand[ i ];
        attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
}

if ( includeWidth ) {
        attrs.opacity = attrs.width = type;
}

return attrs;

}

function createTween( value, prop, animation ) {

var tween,
        collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
        index = 0,
        length = collection.length;
for ( ; index < length; index++ ) {
        if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {

                // We're done with this property
                return tween;
        }
}

}

function defaultPrefilter( elem, props, opts ) {

var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
        isBox = "width" in props || "height" in props,
        anim = this,
        orig = {},
        style = elem.style,
        hidden = elem.nodeType && isHiddenWithinTree( elem ),
        dataShow = dataPriv.get( elem, "fxshow" );

// Queue-skipping animations hijack the fx hooks
if ( !opts.queue ) {
        hooks = jQuery._queueHooks( elem, "fx" );
        if ( hooks.unqueued == null ) {
                hooks.unqueued = 0;
                oldfire = hooks.empty.fire;
                hooks.empty.fire = function() {
                        if ( !hooks.unqueued ) {
                                oldfire();
                        }
                };
        }
        hooks.unqueued++;

        anim.always( function() {

                // Ensure the complete handler is called before this completes
                anim.always( function() {
                        hooks.unqueued--;
                        if ( !jQuery.queue( elem, "fx" ).length ) {
                                hooks.empty.fire();
                        }
                } );
        } );
}

// Detect show/hide animations
for ( prop in props ) {
        value = props[ prop ];
        if ( rfxtypes.test( value ) ) {
                delete props[ prop ];
                toggle = toggle || value === "toggle";
                if ( value === ( hidden ? "hide" : "show" ) ) {

                        // Pretend to be hidden if this is a "show" and
                        // there is still data from a stopped show/hide
                        if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
                                hidden = true;

                        // Ignore all other no-op show/hide data
                        } else {
                                continue;
                        }
                }
                orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
        }
}

// Bail out if this is a no-op like .hide().hide()
propTween = !jQuery.isEmptyObject( props );
if ( !propTween && jQuery.isEmptyObject( orig ) ) {
        return;
}

// Restrict "overflow" and "display" styles during box animations
if ( isBox && elem.nodeType === 1 ) {

        // Support: IE <=9 - 11, Edge 12 - 15
        // Record all 3 overflow attributes because IE does not infer the shorthand
        // from identically-valued overflowX and overflowY and Edge just mirrors
        // the overflowX value there.
        opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];

        // Identify a display type, preferring old show/hide data over the CSS cascade
        restoreDisplay = dataShow && dataShow.display;
        if ( restoreDisplay == null ) {
                restoreDisplay = dataPriv.get( elem, "display" );
        }
        display = jQuery.css( elem, "display" );
        if ( display === "none" ) {
                if ( restoreDisplay ) {
                        display = restoreDisplay;
                } else {

                        // Get nonempty value(s) by temporarily forcing visibility
                        showHide( [ elem ], true );
                        restoreDisplay = elem.style.display || restoreDisplay;
                        display = jQuery.css( elem, "display" );
                        showHide( [ elem ] );
                }
        }

        // Animate inline elements as inline-block
        if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
                if ( jQuery.css( elem, "float" ) === "none" ) {

                        // Restore the original display value at the end of pure show/hide animations
                        if ( !propTween ) {
                                anim.done( function() {
                                        style.display = restoreDisplay;
                                } );
                                if ( restoreDisplay == null ) {
                                        display = style.display;
                                        restoreDisplay = display === "none" ? "" : display;
                                }
                        }
                        style.display = "inline-block";
                }
        }
}

if ( opts.overflow ) {
        style.overflow = "hidden";
        anim.always( function() {
                style.overflow = opts.overflow[ 0 ];
                style.overflowX = opts.overflow[ 1 ];
                style.overflowY = opts.overflow[ 2 ];
        } );
}

// Implement show/hide animations
propTween = false;
for ( prop in orig ) {

        // General show/hide setup for this element animation
        if ( !propTween ) {
                if ( dataShow ) {
                        if ( "hidden" in dataShow ) {
                                hidden = dataShow.hidden;
                        }
                } else {
                        dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
                }

                // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
                if ( toggle ) {
                        dataShow.hidden = !hidden;
                }

                // Show elements before animating them
                if ( hidden ) {
                        showHide( [ elem ], true );
                }

                /* eslint-disable no-loop-func */

                anim.done( function() {

                /* eslint-enable no-loop-func */

                        // The final step of a "hide" animation is actually hiding the element
                        if ( !hidden ) {
                                showHide( [ elem ] );
                        }
                        dataPriv.remove( elem, "fxshow" );
                        for ( prop in orig ) {
                                jQuery.style( elem, prop, orig[ prop ] );
                        }
                } );
        }

        // Per-property setup
        propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
        if ( !( prop in dataShow ) ) {
                dataShow[ prop ] = propTween.start;
                if ( hidden ) {
                        propTween.end = propTween.start;
                        propTween.start = 0;
                }
        }
}

}

function propFilter( props, specialEasing ) {

var index, name, easing, value, hooks;

// camelCase, specialEasing and expand cssHook pass
for ( index in props ) {
        name = camelCase( index );
        easing = specialEasing[ name ];
        value = props[ index ];
        if ( Array.isArray( value ) ) {
                easing = value[ 1 ];
                value = props[ index ] = value[ 0 ];
        }

        if ( index !== name ) {
                props[ name ] = value;
                delete props[ index ];
        }

        hooks = jQuery.cssHooks[ name ];
        if ( hooks && "expand" in hooks ) {
                value = hooks.expand( value );
                delete props[ name ];

                // Not quite $.extend, this won't overwrite existing keys.
                // Reusing 'index' because we have the correct "name"
                for ( index in value ) {
                        if ( !( index in props ) ) {
                                props[ index ] = value[ index ];
                                specialEasing[ index ] = easing;
                        }
                }
        } else {
                specialEasing[ name ] = easing;
        }
}

}

function Animation( elem, properties, options ) {

var result,
        stopped,
        index = 0,
        length = Animation.prefilters.length,
        deferred = jQuery.Deferred().always( function() {

                // Don't match elem in the :animated selector
                delete tick.elem;
        } ),
        tick = function() {
                if ( stopped ) {
                        return false;
                }
                var currentTime = fxNow || createFxNow(),
                        remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),

                        // Support: Android 2.3 only
                        // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
                        temp = remaining / animation.duration || 0,
                        percent = 1 - temp,
                        index = 0,
                        length = animation.tweens.length;

                for ( ; index < length; index++ ) {
                        animation.tweens[ index ].run( percent );
                }

                deferred.notifyWith( elem, [ animation, percent, remaining ] );

                // If there's more to do, yield
                if ( percent < 1 && length ) {
                        return remaining;
                }

                // If this was an empty animation, synthesize a final progress notification
                if ( !length ) {
                        deferred.notifyWith( elem, [ animation, 1, 0 ] );
                }

                // Resolve the animation and report its conclusion
                deferred.resolveWith( elem, [ animation ] );
                return false;
        },
        animation = deferred.promise( {
                elem: elem,
                props: jQuery.extend( {}, properties ),
                opts: jQuery.extend( true, {
                        specialEasing: {},
                        easing: jQuery.easing._default
                }, options ),
                originalProperties: properties,
                originalOptions: options,
                startTime: fxNow || createFxNow(),
                duration: options.duration,
                tweens: [],
                createTween: function( prop, end ) {
                        var tween = jQuery.Tween( elem, animation.opts, prop, end,
                                        animation.opts.specialEasing[ prop ] || animation.opts.easing );
                        animation.tweens.push( tween );
                        return tween;
                },
                stop: function( gotoEnd ) {
                        var index = 0,

                                // If we are going to the end, we want to run all the tweens
                                // otherwise we skip this part
                                length = gotoEnd ? animation.tweens.length : 0;
                        if ( stopped ) {
                                return this;
                        }
                        stopped = true;
                        for ( ; index < length; index++ ) {
                                animation.tweens[ index ].run( 1 );
                        }

                        // Resolve when we played the last frame; otherwise, reject
                        if ( gotoEnd ) {
                                deferred.notifyWith( elem, [ animation, 1, 0 ] );
                                deferred.resolveWith( elem, [ animation, gotoEnd ] );
                        } else {
                                deferred.rejectWith( elem, [ animation, gotoEnd ] );
                        }
                        return this;
                }
        } ),
        props = animation.props;

propFilter( props, animation.opts.specialEasing );

for ( ; index < length; index++ ) {
        result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
        if ( result ) {
                if ( isFunction( result.stop ) ) {
                        jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
                                result.stop.bind( result );
                }
                return result;
        }
}

jQuery.map( props, createTween, animation );

if ( isFunction( animation.opts.start ) ) {
        animation.opts.start.call( elem, animation );
}

// Attach callbacks from options
animation
        .progress( animation.opts.progress )
        .done( animation.opts.done, animation.opts.complete )
        .fail( animation.opts.fail )
        .always( animation.opts.always );

jQuery.fx.timer(
        jQuery.extend( tick, {
                elem: elem,
                anim: animation,
                queue: animation.opts.queue
        } )
);

return animation;

}

jQuery.Animation = jQuery.extend( Animation, {

tweeners: {
        "*": [ function( prop, value ) {
                var tween = this.createTween( prop, value );
                adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
                return tween;
        } ]
},

tweener: function( props, callback ) {
        if ( isFunction( props ) ) {
                callback = props;
                props = [ "*" ];
        } else {
                props = props.match( rnothtmlwhite );
        }

        var prop,
                index = 0,
                length = props.length;

        for ( ; index < length; index++ ) {
                prop = props[ index ];
                Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
                Animation.tweeners[ prop ].unshift( callback );
        }
},

prefilters: [ defaultPrefilter ],

prefilter: function( callback, prepend ) {
        if ( prepend ) {
                Animation.prefilters.unshift( callback );
        } else {
                Animation.prefilters.push( callback );
        }
}

} );

jQuery.speed = function( speed, easing, fn ) {

var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
        complete: fn || !fn && easing ||
                isFunction( speed ) && speed,
        duration: speed,
        easing: fn && easing || easing && !isFunction( easing ) && easing
};

// Go to the end state if fx are off
if ( jQuery.fx.off ) {
        opt.duration = 0;

} else {
        if ( typeof opt.duration !== "number" ) {
                if ( opt.duration in jQuery.fx.speeds ) {
                        opt.duration = jQuery.fx.speeds[ opt.duration ];

                } else {
                        opt.duration = jQuery.fx.speeds._default;
                }
        }
}

// Normalize opt.queue - true/undefined/null -> "fx"
if ( opt.queue == null || opt.queue === true ) {
        opt.queue = "fx";
}

// Queueing
opt.old = opt.complete;

opt.complete = function() {
        if ( isFunction( opt.old ) ) {
                opt.old.call( this );
        }

        if ( opt.queue ) {
                jQuery.dequeue( this, opt.queue );
        }
};

return opt;

};

jQuery.fn.extend( {

fadeTo: function( speed, to, easing, callback ) {

        // Show any hidden elements after setting opacity to 0
        return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()

                // Animate to the value specified
                .end().animate( { opacity: to }, speed, easing, callback );
},
animate: function( prop, speed, easing, callback ) {
        var empty = jQuery.isEmptyObject( prop ),
                optall = jQuery.speed( speed, easing, callback ),
                doAnimation = function() {

                        // Operate on a copy of prop so per-property easing won't be lost
                        var anim = Animation( this, jQuery.extend( {}, prop ), optall );

                        // Empty animations, or finishing resolves immediately
                        if ( empty || dataPriv.get( this, "finish" ) ) {
                                anim.stop( true );
                        }
                };
                doAnimation.finish = doAnimation;

        return empty || optall.queue === false ?
                this.each( doAnimation ) :
                this.queue( optall.queue, doAnimation );
},
stop: function( type, clearQueue, gotoEnd ) {
        var stopQueue = function( hooks ) {
                var stop = hooks.stop;
                delete hooks.stop;
                stop( gotoEnd );
        };

        if ( typeof type !== "string" ) {
                gotoEnd = clearQueue;
                clearQueue = type;
                type = undefined;
        }
        if ( clearQueue && type !== false ) {
                this.queue( type || "fx", [] );
        }

        return this.each( function() {
                var dequeue = true,
                        index = type != null && type + "queueHooks",
                        timers = jQuery.timers,
                        data = dataPriv.get( this );

                if ( index ) {
                        if ( data[ index ] && data[ index ].stop ) {
                                stopQueue( data[ index ] );
                        }
                } else {
                        for ( index in data ) {
                                if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
                                        stopQueue( data[ index ] );
                                }
                        }
                }

                for ( index = timers.length; index--; ) {
                        if ( timers[ index ].elem === this &&
                                ( type == null || timers[ index ].queue === type ) ) {

                                timers[ index ].anim.stop( gotoEnd );
                                dequeue = false;
                                timers.splice( index, 1 );
                        }
                }

                // Start the next in the queue if the last step wasn't forced.
                // Timers currently will call their complete callbacks, which
                // will dequeue but only if they were gotoEnd.
                if ( dequeue || !gotoEnd ) {
                        jQuery.dequeue( this, type );
                }
        } );
},
finish: function( type ) {
        if ( type !== false ) {
                type = type || "fx";
        }
        return this.each( function() {
                var index,
                        data = dataPriv.get( this ),
                        queue = data[ type + "queue" ],
                        hooks = data[ type + "queueHooks" ],
                        timers = jQuery.timers,
                        length = queue ? queue.length : 0;

                // Enable finishing flag on private data
                data.finish = true;

                // Empty the queue first
                jQuery.queue( this, type, [] );

                if ( hooks && hooks.stop ) {
                        hooks.stop.call( this, true );
                }

                // Look for any active animations, and finish them
                for ( index = timers.length; index--; ) {
                        if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
                                timers[ index ].anim.stop( true );
                                timers.splice( index, 1 );
                        }
                }

                // Look for any animations in the old queue and finish them
                for ( index = 0; index < length; index++ ) {
                        if ( queue[ index ] && queue[ index ].finish ) {
                                queue[ index ].finish.call( this );
                        }
                }

                // Turn off finishing flag
                delete data.finish;
        } );
}

} );

jQuery.each( [ “toggle”, “show”, “hide” ], function( i, name ) {

var cssFn = jQuery.fn[ name ];
jQuery.fn[ name ] = function( speed, easing, callback ) {
        return speed == null || typeof speed === "boolean" ?
                cssFn.apply( this, arguments ) :
                this.animate( genFx( name, true ), speed, easing, callback );
};

} );

// Generate shortcuts for custom animations jQuery.each( {

slideDown: genFx( "show" ),
slideUp: genFx( "hide" ),
slideToggle: genFx( "toggle" ),
fadeIn: { opacity: "show" },
fadeOut: { opacity: "hide" },
fadeToggle: { opacity: "toggle" }

}, function( name, props ) {

jQuery.fn[ name ] = function( speed, easing, callback ) {
        return this.animate( props, speed, easing, callback );
};

} );

jQuery.timers = []; jQuery.fx.tick = function() {

var timer,
        i = 0,
        timers = jQuery.timers;

fxNow = Date.now();

for ( ; i < timers.length; i++ ) {
        timer = timers[ i ];

        // Run the timer and safely remove it when done (allowing for external removal)
        if ( !timer() && timers[ i ] === timer ) {
                timers.splice( i--, 1 );
        }
}

if ( !timers.length ) {
        jQuery.fx.stop();
}
fxNow = undefined;

};

jQuery.fx.timer = function( timer ) {

jQuery.timers.push( timer );
jQuery.fx.start();

};

jQuery.fx.interval = 13; jQuery.fx.start = function() {

if ( inProgress ) {
        return;
}

inProgress = true;
schedule();

};

jQuery.fx.stop = function() {

inProgress = null;

};

jQuery.fx.speeds = {

slow: 600,
fast: 200,

// Default speed
_default: 400

};

return jQuery; } );