/*!
 * jQuery UI Effects 1.10.4
 * http://jqueryui.com
 *
 * Copyright 2014 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/category/effects-core/
 */
( function ( $, undefined ) {
	const dataSpace = 'ui-effects-';
	$.effects = {
		effect: {},
	};
	/*!
	 * jQuery Color Animations v2.1.2
	 * https://github.com/jquery/jquery-color
	 *
	 * Copyright 2013 jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 *
	 * Date: Wed Jan 16 08:47:09 2013 -0600
	 */
	( function ( jQuery, undefined ) {
		let stepHooks =
				'backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor',
			// plusequals test for += 100 -= 100
			rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
			// a set of RE's that can match strings and generate color tuples.
			stringParsers = [
				{
					re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
					parse( execResult ) {
						return [
							execResult[ 1 ],
							execResult[ 2 ],
							execResult[ 3 ],
							execResult[ 4 ],
						];
					},
				},
				{
					re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
					parse( execResult ) {
						return [
							execResult[ 1 ] * 2.55,
							execResult[ 2 ] * 2.55,
							execResult[ 3 ] * 2.55,
							execResult[ 4 ],
						];
					},
				},
				{
					// this regex ignores A-F because it's compared against an already lowercased string
					re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
					parse( execResult ) {
						return [
							parseInt( execResult[ 1 ], 16 ),
							parseInt( execResult[ 2 ], 16 ),
							parseInt( execResult[ 3 ], 16 ),
						];
					},
				},
				{
					// this regex ignores A-F because it's compared against an already lowercased string
					re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
					parse( execResult ) {
						return [
							parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
							parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
							parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ),
						];
					},
				},
				{
					re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
					space: 'hsla',
					parse( execResult ) {
						return [
							execResult[ 1 ],
							execResult[ 2 ] / 100,
							execResult[ 3 ] / 100,
							execResult[ 4 ],
						];
					},
				},
			],
			// jQuery.Color( )
			color = ( jQuery.Color = function ( color, green, blue, alpha ) {
				return new jQuery.Color.fn.parse( color, green, blue, alpha );
			} ),
			spaces = {
				rgba: {
					props: {
						red: {
							idx: 0,
							type: 'byte',
						},
						green: {
							idx: 1,
							type: 'byte',
						},
						blue: {
							idx: 2,
							type: 'byte',
						},
					},
				},
				hsla: {
					props: {
						hue: {
							idx: 0,
							type: 'degrees',
						},
						saturation: {
							idx: 1,
							type: 'percent',
						},
						lightness: {
							idx: 2,
							type: 'percent',
						},
					},
				},
			},
			propTypes = {
				byte: {
					floor: true,
					max: 255,
				},
				percent: {
					max: 1,
				},
				degrees: {
					mod: 360,
					floor: true,
				},
			},
			support = ( color.support = {} ),
			// element for support tests
			supportElem = jQuery( '<p>' )[ 0 ],
			// colors = jQuery.Color.names
			colors,
			// local aliases of functions called often
			each = jQuery.each;
		// determine rgba support immediately
		supportElem.style.cssText = 'background-color:rgba(1,1,1,.5)';
		support.rgba = supportElem.style.backgroundColor.indexOf( 'rgba' ) > -1;
		// define cache name and alpha properties
		// for rgba and hsla spaces
		each( spaces, function ( spaceName, space ) {
			space.cache = '_' + spaceName;
			space.props.alpha = {
				idx: 3,
				type: 'percent',
				def: 1,
			};
		} );
		function clamp( value, prop, allowEmpty ) {
			const type = propTypes[ prop.type ] || {};
			if ( value == null ) {
				return allowEmpty || ! prop.def ? null : prop.def;
			}
			// ~~ is an short way of doing floor for positive numbers
			value = type.floor ? ~~value : parseFloat( value );
			// IE will pass in empty strings as value for alpha,
			// which will hit this case
			if ( isNaN( value ) ) {
				return prop.def;
			}
			if ( type.mod ) {
				// we add mod before modding to make sure that negatives values
				// get converted properly: -10 -> 350
				return ( value + type.mod ) % type.mod;
			}
			// for now all property types without mod have min and max
			return 0 > value ? 0 : type.max < value ? type.max : value;
		}
		function stringParse( string ) {
			let inst = color(),
				rgba = ( inst._rgba = [] );
			string = string.toLowerCase();
			each( stringParsers, function ( i, parser ) {
				let parsed,
					match = parser.re.exec( string ),
					values = match && parser.parse( match ),
					spaceName = parser.space || 'rgba';
				if ( values ) {
					parsed = inst[ spaceName ]( values );
					// if this was an rgba parse the assignment might happen twice
					// oh well....
					inst[ spaces[ spaceName ].cache ] =
						parsed[ spaces[ spaceName ].cache ];
					rgba = inst._rgba = parsed._rgba;
					// exit each( stringParsers ) here because we matched
					return false;
				}
			} );
			// Found a stringParser that handled it
			if ( rgba.length ) {
				// if this came from a parsed string, force "transparent" when alpha is 0
				// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
				if ( rgba.join() === '0,0,0,0' ) {
					jQuery.extend( rgba, colors.transparent );
				}
				return inst;
			}
			// named colors
			return colors[ string ];
		}
		color.fn = jQuery.extend( color.prototype, {
			parse( red, green, blue, alpha ) {
				if ( red === undefined ) {
					this._rgba = [ null, null, null, null ];
					return this;
				}
				if ( red.jquery || red.nodeType ) {
					red = jQuery( red ).css( green );
					green = undefined;
				}
				let inst = this,
					type = jQuery.type( red ),
					rgba = ( this._rgba = [] );
				// more than 1 argument specified - assume ( red, green, blue, alpha )
				if ( green !== undefined ) {
					red = [ red, green, blue, alpha ];
					type = 'array';
				}
				if ( type === 'string' ) {
					return this.parse( stringParse( red ) || colors._default );
				}
				if ( type === 'array' ) {
					each( spaces.rgba.props, function ( key, prop ) {
						rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
					} );
					return this;
				}
				if ( type === 'object' ) {
					if ( red instanceof color ) {
						each( spaces, function ( spaceName, space ) {
							if ( red[ space.cache ] ) {
								inst[ space.cache ] = red[
									space.cache
								].slice();
							}
						} );
					} else {
						each( spaces, function ( spaceName, space ) {
							const cache = space.cache;
							each( space.props, function ( key, prop ) {
								// if the cache doesn't exist, and we know how to convert
								if ( ! inst[ cache ] && space.to ) {
									// if the value was null, we don't need to copy it
									// if the key was alpha, we don't need to copy it either
									if (
										key === 'alpha' ||
										red[ key ] == null
									) {
										return;
									}
									inst[ cache ] = space.to( inst._rgba );
								}
								// this is the only case where we allow nulls for ALL properties.
								// call clamp with alwaysAllowEmpty
								inst[ cache ][ prop.idx ] = clamp(
									red[ key ],
									prop,
									true
								);
							} );
							// everything defined but alpha?
							if (
								inst[ cache ] &&
								jQuery.inArray(
									null,
									inst[ cache ].slice( 0, 3 )
								) < 0
							) {
								// use the default of 1
								inst[ cache ][ 3 ] = 1;
								if ( space.from ) {
									inst._rgba = space.from( inst[ cache ] );
								}
							}
						} );
					}
					return this;
				}
			},
			is( compare ) {
				let is = color( compare ),
					same = true,
					inst = this;
				each( spaces, function ( _, space ) {
					let localCache,
						isCache = is[ space.cache ];
					if ( isCache ) {
						localCache =
							inst[ space.cache ] ||
							( space.to && space.to( inst._rgba ) ) ||
							[];
						each( space.props, function ( _, prop ) {
							if ( isCache[ prop.idx ] != null ) {
								same =
									isCache[ prop.idx ] ===
									localCache[ prop.idx ];
								return same;
							}
						} );
					}
					return same;
				} );
				return same;
			},
			_space() {
				const used = [],
					inst = this;
				each( spaces, function ( spaceName, space ) {
					if ( inst[ space.cache ] ) {
						used.push( spaceName );
					}
				} );
				return used.pop();
			},
			transition( other, distance ) {
				let end = color( other ),
					spaceName = end._space(),
					space = spaces[ spaceName ],
					startColor =
						this.alpha() === 0 ? color( 'transparent' ) : this,
					start =
						startColor[ space.cache ] ||
						space.to( startColor._rgba ),
					result = start.slice();
				end = end[ space.cache ];
				each( space.props, function ( key, prop ) {
					let index = prop.idx,
						startValue = start[ index ],
						endValue = end[ index ],
						type = propTypes[ prop.type ] || {};
					// if null, don't override start value
					if ( endValue === null ) {
						return;
					}
					// if null - use end
					if ( startValue === null ) {
						result[ index ] = endValue;
					} else {
						if ( type.mod ) {
							if ( endValue - startValue > type.mod / 2 ) {
								startValue += type.mod;
							} else if ( startValue - endValue > type.mod / 2 ) {
								startValue -= type.mod;
							}
						}
						result[ index ] = clamp(
							( endValue - startValue ) * distance + startValue,
							prop
						);
					}
				} );
				return this[ spaceName ]( result );
			},
			blend( opaque ) {
				// if we are already opaque - return ourself
				if ( this._rgba[ 3 ] === 1 ) {
					return this;
				}
				const rgb = this._rgba.slice(),
					a = rgb.pop(),
					blend = color( opaque )._rgba;
				return color(
					jQuery.map( rgb, function ( v, i ) {
						return ( 1 - a ) * blend[ i ] + a * v;
					} )
				);
			},
			toRgbaString() {
				let prefix = 'rgba(',
					rgba = jQuery.map( this._rgba, function ( v, i ) {
						return v == null ? ( i > 2 ? 1 : 0 ) : v;
					} );
				if ( rgba[ 3 ] === 1 ) {
					rgba.pop();
					prefix = 'rgb(';
				}
				return prefix + rgba.join() + ')';
			},
			toHslaString() {
				let prefix = 'hsla(',
					hsla = jQuery.map( this.hsla(), function ( v, i ) {
						if ( v == null ) {
							v = i > 2 ? 1 : 0;
						}
						// catch 1 and 2
						if ( i && i < 3 ) {
							v = Math.round( v * 100 ) + '%';
						}
						return v;
					} );
				if ( hsla[ 3 ] === 1 ) {
					hsla.pop();
					prefix = 'hsl(';
				}
				return prefix + hsla.join() + ')';
			},
			toHexString( includeAlpha ) {
				const rgba = this._rgba.slice(),
					alpha = rgba.pop();
				if ( includeAlpha ) {
					rgba.push( ~~( alpha * 255 ) );
				}
				return (
					'#' +
					jQuery
						.map( rgba, function ( v ) {
							// default to 0 when nulls exist
							v = ( v || 0 ).toString( 16 );
							return v.length === 1 ? '0' + v : v;
						} )
						.join( '' )
				);
			},
			toString() {
				return this._rgba[ 3 ] === 0
					? 'transparent'
					: this.toRgbaString();
			},
		} );
		color.fn.parse.prototype = color.fn;
		// hsla conversions adapted from:
		// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
		function hue2rgb( p, q, h ) {
			h = ( h + 1 ) % 1;
			if ( h * 6 < 1 ) {
				return p + ( q - p ) * h * 6;
			}
			if ( h * 2 < 1 ) {
				return q;
			}
			if ( h * 3 < 2 ) {
				return p + ( q - p ) * ( 2 / 3 - h ) * 6;
			}
			return p;
		}
		spaces.hsla.to = function ( rgba ) {
			if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
				return [ null, null, null, rgba[ 3 ] ];
			}
			let r = rgba[ 0 ] / 255,
				g = rgba[ 1 ] / 255,
				b = rgba[ 2 ] / 255,
				a = rgba[ 3 ],
				max = Math.max( r, g, b ),
				min = Math.min( r, g, b ),
				diff = max - min,
				add = max + min,
				l = add * 0.5,
				h,
				s;
			if ( min === max ) {
				h = 0;
			} else if ( r === max ) {
				h = ( 60 * ( g - b ) ) / diff + 360;
			} else if ( g === max ) {
				h = ( 60 * ( b - r ) ) / diff + 120;
			} else {
				h = ( 60 * ( r - g ) ) / diff + 240;
			}
			// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
			// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
			if ( diff === 0 ) {
				s = 0;
			} else if ( l <= 0.5 ) {
				s = diff / add;
			} else {
				s = diff / ( 2 - add );
			}
			return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
		};
		spaces.hsla.from = function ( hsla ) {
			if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
				return [ null, null, null, hsla[ 3 ] ];
			}
			const h = hsla[ 0 ] / 360,
				s = hsla[ 1 ],
				l = hsla[ 2 ],
				a = hsla[ 3 ],
				q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
				p = 2 * l - q;
			return [
				Math.round( hue2rgb( p, q, h + 1 / 3 ) * 255 ),
				Math.round( hue2rgb( p, q, h ) * 255 ),
				Math.round( hue2rgb( p, q, h - 1 / 3 ) * 255 ),
				a,
			];
		};
		each( spaces, function ( spaceName, space ) {
			const props = space.props,
				cache = space.cache,
				to = space.to,
				from = space.from;
			// makes rgba() and hsla()
			color.fn[ spaceName ] = function ( value ) {
				// generate a cache for this space if it doesn't exist
				if ( to && ! this[ cache ] ) {
					this[ cache ] = to( this._rgba );
				}
				if ( value === undefined ) {
					return this[ cache ].slice();
				}
				let ret,
					type = jQuery.type( value ),
					arr =
						type === 'array' || type === 'object'
							? value
							: arguments,
					local = this[ cache ].slice();
				each( props, function ( key, prop ) {
					let val = arr[ type === 'object' ? key : prop.idx ];
					if ( val == null ) {
						val = local[ prop.idx ];
					}
					local[ prop.idx ] = clamp( val, prop );
				} );
				if ( from ) {
					ret = color( from( local ) );
					ret[ cache ] = local;
					return ret;
				}
				return color( local );
			};
			// makes red() green() blue() alpha() hue() saturation() lightness()
			each( props, function ( key, prop ) {
				// alpha is included in more than one space
				if ( color.fn[ key ] ) {
					return;
				}
				color.fn[ key ] = function ( value ) {
					let vtype = jQuery.type( value ),
						fn =
							key === 'alpha'
								? this._hsla
									? 'hsla'
									: 'rgba'
								: spaceName,
						local = this[ fn ](),
						cur = local[ prop.idx ],
						match;
					if ( vtype === 'undefined' ) {
						return cur;
					}
					if ( vtype === 'function' ) {
						value = value.call( this, cur );
						vtype = jQuery.type( value );
					}
					if ( value == null && prop.empty ) {
						return this;
					}
					if ( vtype === 'string' ) {
						match = rplusequals.exec( value );
						if ( match ) {
							value =
								cur +
								parseFloat( match[ 2 ] ) *
									( match[ 1 ] === '+' ? 1 : -1 );
						}
					}
					local[ prop.idx ] = value;
					return this[ fn ]( local );
				};
			} );
		} );
		// add cssHook and .fx.step function for each named hook.
		// accept a space separated string of properties
		color.hook = function ( hook ) {
			const hooks = hook.split( ' ' );
			each( hooks, function ( i, hook ) {
				jQuery.cssHooks[ hook ] = {
					set( elem, value ) {
						let parsed,
							curElem,
							backgroundColor = '';
						if (
							value !== 'transparent' &&
							( jQuery.type( value ) !== 'string' ||
								( parsed = stringParse( value ) ) )
						) {
							value = color( parsed || value );
							if ( ! support.rgba && value._rgba[ 3 ] !== 1 ) {
								curElem =
									hook === 'backgroundColor'
										? elem.parentNode
										: elem;
								while (
									( backgroundColor === '' ||
										backgroundColor === 'transparent' ) &&
									curElem &&
									curElem.style
								) {
									try {
										backgroundColor = jQuery.css(
											curElem,
											'backgroundColor'
										);
										curElem = curElem.parentNode;
									} catch ( e ) {}
								}
								value = value.blend(
									backgroundColor &&
										backgroundColor !== 'transparent'
										? backgroundColor
										: '_default'
								);
							}
							value = value.toRgbaString();
						}
						try {
							elem.style[ hook ] = value;
						} catch ( e ) {
							// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
						}
					},
				};
				jQuery.fx.step[ hook ] = function ( fx ) {
					if ( ! fx.colorInit ) {
						fx.start = color( fx.elem, hook );
						fx.end = color( fx.end );
						fx.colorInit = true;
					}
					jQuery.cssHooks[ hook ].set(
						fx.elem,
						fx.start.transition( fx.end, fx.pos )
					);
				};
			} );
		};
		color.hook( stepHooks );
		jQuery.cssHooks.borderColor = {
			expand( value ) {
				const expanded = {};
				each(
					[ 'Top', 'Right', 'Bottom', 'Left' ],
					function ( i, part ) {
						expanded[ 'border' + part + 'Color' ] = value;
					}
				);
				return expanded;
			},
		};
		// Basic color names only.
		// Usage of any of the other color names requires adding yourself or including
		// jquery.color.svg-names.js.
		colors = jQuery.Color.names = {
			// 4.1. Basic color keywords
			aqua: '#00ffff',
			black: '#000000',
			blue: '#0000ff',
			fuchsia: '#ff00ff',
			gray: '#808080',
			green: '#008000',
			lime: '#00ff00',
			maroon: '#800000',
			navy: '#000080',
			olive: '#808000',
			purple: '#800080',
			red: '#ff0000',
			silver: '#c0c0c0',
			teal: '#008080',
			white: '#ffffff',
			yellow: '#ffff00',
			// 4.2.3. "transparent" color keyword
			transparent: [ null, null, null, 0 ],
			_default: '#ffffff',
		};
	} )( jQuery );
	/******************************************************************************/
	/****************************** CLASS ANIMATIONS ******************************/
	/******************************************************************************/
	( function () {
		const classAnimationActions = [ 'add', 'remove', 'toggle' ],
			shorthandStyles = {
				border: 1,
				borderBottom: 1,
				borderColor: 1,
				borderLeft: 1,
				borderRight: 1,
				borderTop: 1,
				borderWidth: 1,
				margin: 1,
				padding: 1,
			};
		$.each(
			[
				'borderLeftStyle',
				'borderRightStyle',
				'borderBottomStyle',
				'borderTopStyle',
			],
			function ( _, prop ) {
				$.fx.step[ prop ] = function ( fx ) {
					if (
						( fx.end !== 'none' && ! fx.setAttr ) ||
						( fx.pos === 1 && ! fx.setAttr )
					) {
						jQuery.style( fx.elem, prop, fx.end );
						fx.setAttr = true;
					}
				};
			}
		);
		function getElementStyles( elem ) {
			let key,
				len,
				style = elem.ownerDocument.defaultView
					? elem.ownerDocument.defaultView.getComputedStyle(
							elem,
							null
					  )
					: elem.currentStyle,
				styles = {};
			if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
				len = style.length;
				while ( len-- ) {
					key = style[ len ];
					if ( typeof style[ key ] === 'string' ) {
						styles[ $.camelCase( key ) ] = style[ key ];
					}
				}
				// support: Opera, IE <9
			} else {
				for ( key in style ) {
					if ( typeof style[ key ] === 'string' ) {
						styles[ key ] = style[ key ];
					}
				}
			}
			return styles;
		}
		function styleDifference( oldStyle, newStyle ) {
			let diff = {},
				name,
				value;
			for ( name in newStyle ) {
				value = newStyle[ name ];
				if ( oldStyle[ name ] !== value ) {
					if ( ! shorthandStyles[ name ] ) {
						if (
							$.fx.step[ name ] ||
							! isNaN( parseFloat( value ) )
						) {
							diff[ name ] = value;
						}
					}
				}
			}
			return diff;
		}
		// support: jQuery <1.8
		if ( ! $.fn.addBack ) {
			$.fn.addBack = function ( selector ) {
				return this.add(
					selector == null
						? this.prevObject
						: this.prevObject.filter( selector )
				);
			};
		}
		$.effects.animateClass = function (
			value,
			duration,
			easing,
			callback
		) {
			const o = $.speed( duration, easing, callback );
			return this.queue( function () {
				let animated = $( this ),
					baseClass = animated.attr( 'class' ) || '',
					applyClassChange,
					allAnimations = o.children
						? animated.find( '*' ).addBack()
						: animated;
				// map the animated objects to store the original styles.
				allAnimations = allAnimations.map( function () {
					const el = $( this );
					return {
						el,
						start: getElementStyles( this ),
					};
				} );
				// apply class change
				applyClassChange = function () {
					$.each( classAnimationActions, function ( i, action ) {
						if ( value[ action ] ) {
							animated[ action + 'Class' ]( value[ action ] );
						}
					} );
				};
				applyClassChange();
				// map all animated objects again - calculate new styles and diff
				allAnimations = allAnimations.map( function () {
					this.end = getElementStyles( this.el[ 0 ] );
					this.diff = styleDifference( this.start, this.end );
					return this;
				} );
				// apply original class
				animated.attr( 'class', baseClass );
				// map all animated objects again - this time collecting a promise
				allAnimations = allAnimations.map( function () {
					const styleInfo = this,
						dfd = $.Deferred(),
						opts = $.extend( {}, o, {
							queue: false,
							complete() {
								dfd.resolve( styleInfo );
							},
						} );
					this.el.animate( this.diff, opts );
					return dfd.promise();
				} );
				// once all animations have completed:
				$.when.apply( $, allAnimations.get() ).done( function () {
					// set the final class
					applyClassChange();
					// for each animated element,
					// clear all css properties that were animated
					$.each( arguments, function () {
						const el = this.el;
						$.each( this.diff, function ( key ) {
							el.css( key, '' );
						} );
					} );
					// this is guarnteed to be there if you use jQuery.speed()
					// it also handles dequeuing the next anim...
					o.complete.call( animated[ 0 ] );
				} );
			} );
		};
		$.fn.extend( {
			addClass: ( function ( orig ) {
				return function ( classNames, speed, easing, callback ) {
					return speed
						? $.effects.animateClass.call(
								this,
								{ add: classNames },
								speed,
								easing,
								callback
						  )
						: orig.apply( this, arguments );
				};
			} )( $.fn.addClass ),
			removeClass: ( function ( orig ) {
				return function ( classNames, speed, easing, callback ) {
					return arguments.length > 1
						? $.effects.animateClass.call(
								this,
								{ remove: classNames },
								speed,
								easing,
								callback
						  )
						: orig.apply( this, arguments );
				};
			} )( $.fn.removeClass ),
			toggleClass: ( function ( orig ) {
				return function ( classNames, force, speed, easing, callback ) {
					if ( typeof force === 'boolean' || force === undefined ) {
						if ( ! speed ) {
							// without speed parameter
							return orig.apply( this, arguments );
						}
						return $.effects.animateClass.call(
							this,
							force
								? { add: classNames }
								: { remove: classNames },
							speed,
							easing,
							callback
						);
					}
					// without force parameter
					return $.effects.animateClass.call(
						this,
						{ toggle: classNames },
						force,
						speed,
						easing
					);
				};
			} )( $.fn.toggleClass ),
			switchClass( remove, add, speed, easing, callback ) {
				return $.effects.animateClass.call(
					this,
					{
						add,
						remove,
					},
					speed,
					easing,
					callback
				);
			},
		} );
	} )();
	/******************************************************************************/
	/*********************************** EFFECTS **********************************/
	/******************************************************************************/
	( function () {
		$.extend( $.effects, {
			version: '1.10.4',
			// Saves a set of properties in a data storage
			save( element, set ) {
				for ( let i = 0; i < set.length; i++ ) {
					if ( set[ i ] !== null ) {
						element.data(
							dataSpace + set[ i ],
							element[ 0 ].style[ set[ i ] ]
						);
					}
				}
			},
			// Restores a set of previously saved properties from a data storage
			restore( element, set ) {
				let val, i;
				for ( i = 0; i < set.length; i++ ) {
					if ( set[ i ] !== null ) {
						val = element.data( dataSpace + set[ i ] );
						// support: jQuery 1.6.2
						// http://bugs.jquery.com/ticket/9917
						// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
						// We can't differentiate between "" and 0 here, so we just assume
						// empty string since it's likely to be a more common value...
						if ( val === undefined ) {
							val = '';
						}
						element.css( set[ i ], val );
					}
				}
			},
			setMode( el, mode ) {
				if ( mode === 'toggle' ) {
					mode = el.is( ':hidden' ) ? 'show' : 'hide';
				}
				return mode;
			},
			// Translates a [top,left] array into a baseline value
			// this should be a little more flexible in the future to handle a string & hash
			getBaseline( origin, original ) {
				let y, x;
				switch ( origin[ 0 ] ) {
					case 'top':
						y = 0;
						break;
					case 'middle':
						y = 0.5;
						break;
					case 'bottom':
						y = 1;
						break;
					default:
						y = origin[ 0 ] / original.height;
				}
				switch ( origin[ 1 ] ) {
					case 'left':
						x = 0;
						break;
					case 'center':
						x = 0.5;
						break;
					case 'right':
						x = 1;
						break;
					default:
						x = origin[ 1 ] / original.width;
				}
				return {
					x,
					y,
				};
			},
			// Wraps the element around a wrapper that copies position properties
			createWrapper( element ) {
				// if the element is already wrapped, return it
				if ( element.parent().is( '.ui-effects-wrapper' ) ) {
					return element.parent();
				}
				// wrap the element
				let props = {
						width: element.outerWidth( true ),
						height: element.outerHeight( true ),
						float: element.css( 'float' ),
					},
					wrapper = $( '<div></div>' )
						.addClass( 'ui-effects-wrapper' )
						.css( {
							fontSize: '100%',
							background: 'transparent',
							border: 'none',
							margin: 0,
							padding: 0,
						} ),
					// Store the size in case width/height are defined in % - Fixes #5245
					size = {
						width: element.width(),
						height: element.height(),
					},
					active = document.activeElement;
				// support: Firefox
				// Firefox incorrectly exposes anonymous content
				// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
				try {
					active.id;
				} catch ( e ) {
					active = document.body;
				}
				element.wrap( wrapper );
				// Fixes #7595 - Elements lose focus when wrapped.
				if (
					element[ 0 ] === active ||
					$.contains( element[ 0 ], active )
				) {
					$( active ).focus();
				}
				wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
				// transfer positioning properties to the wrapper
				if ( element.css( 'position' ) === 'static' ) {
					wrapper.css( { position: 'relative' } );
					element.css( { position: 'relative' } );
				} else {
					$.extend( props, {
						position: element.css( 'position' ),
						zIndex: element.css( 'z-index' ),
					} );
					$.each(
						[ 'top', 'left', 'bottom', 'right' ],
						function ( i, pos ) {
							props[ pos ] = element.css( pos );
							if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
								props[ pos ] = 'auto';
							}
						}
					);
					element.css( {
						position: 'relative',
						top: 0,
						left: 0,
						right: 'auto',
						bottom: 'auto',
					} );
				}
				element.css( size );
				return wrapper.css( props ).show();
			},
			removeWrapper( element ) {
				const active = document.activeElement;
				if ( element.parent().is( '.ui-effects-wrapper' ) ) {
					element.parent().replaceWith( element );
					// Fixes #7595 - Elements lose focus when wrapped.
					if (
						element[ 0 ] === active ||
						$.contains( element[ 0 ], active )
					) {
						$( active ).focus();
					}
				}
				return element;
			},
			setTransition( element, list, factor, value ) {
				value = value || {};
				$.each( list, function ( i, x ) {
					const unit = element.cssUnit( x );
					if ( unit[ 0 ] > 0 ) {
						value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
					}
				} );
				return value;
			},
		} );
		// return an effect options object for the given parameters:
		function _normalizeArguments( effect, options, speed, callback ) {
			// allow passing all options as the first parameter
			if ( $.isPlainObject( effect ) ) {
				options = effect;
				effect = effect.effect;
			}
			// convert to an object
			effect = { effect };
			// catch (effect, null, ...)
			if ( options == null ) {
				options = {};
			}
			// catch (effect, callback)
			if ( $.isFunction( options ) ) {
				callback = options;
				speed = null;
				options = {};
			}
			// catch (effect, speed, ?)
			if ( typeof options === 'number' || $.fx.speeds[ options ] ) {
				callback = speed;
				speed = options;
				options = {};
			}
			// catch (effect, options, callback)
			if ( $.isFunction( speed ) ) {
				callback = speed;
				speed = null;
			}
			// add options to effect
			if ( options ) {
				$.extend( effect, options );
			}
			speed = speed || options.duration;
			effect.duration = $.fx.off
				? 0
				: typeof speed === 'number'
				? speed
				: speed in $.fx.speeds
				? $.fx.speeds[ speed ]
				: $.fx.speeds._default;
			effect.complete = callback || options.complete;
			return effect;
		}
		function standardAnimationOption( option ) {
			// Valid standard speeds (nothing, number, named speed)
			if (
				! option ||
				typeof option === 'number' ||
				$.fx.speeds[ option ]
			) {
				return true;
			}
			// Invalid strings - treat as "normal" speed
			if ( typeof option === 'string' && ! $.effects.effect[ option ] ) {
				return true;
			}
			// Complete callback
			if ( $.isFunction( option ) ) {
				return true;
			}
			// Options hash (but not naming an effect)
			if ( typeof option === 'object' && ! option.effect ) {
				return true;
			}
			// Didn't match any standard API
			return false;
		}
		$.fn.extend( {
			effect(/* effect, options, speed, callback */) {
				const args = _normalizeArguments.apply( this, arguments ),
					mode = args.mode,
					queue = args.queue,
					effectMethod = $.effects.effect[ args.effect ];
				if ( $.fx.off || ! effectMethod ) {
					// delegate to the original method (e.g., .show()) if possible
					if ( mode ) {
						return this[ mode ]( args.duration, args.complete );
					}
					return this.each( function () {
						if ( args.complete ) {
							args.complete.call( this );
						}
					} );
				}
				function run( next ) {
					const elem = $( this ),
						complete = args.complete,
						mode = args.mode;
					function done() {
						if ( $.isFunction( complete ) ) {
							complete.call( elem[ 0 ] );
						}
						if ( $.isFunction( next ) ) {
							next();
						}
					}
					// If the element already has the correct final state, delegate to
					// the core methods so the internal tracking of "olddisplay" works.
					if (
						elem.is( ':hidden' ) ? mode === 'hide' : mode === 'show'
					) {
						elem[ mode ]();
						done();
					} else {
						effectMethod.call( elem[ 0 ], args, done );
					}
				}
				return queue === false
					? this.each( run )
					: this.queue( queue || 'fx', run );
			},
			show: ( function ( orig ) {
				return function ( option ) {
					if ( standardAnimationOption( option ) ) {
						return orig.apply( this, arguments );
					}
					const args = _normalizeArguments.apply( this, arguments );
					args.mode = 'show';
					return this.effect.call( this, args );
				};
			} )( $.fn.show ),
			hide: ( function ( orig ) {
				return function ( option ) {
					if ( standardAnimationOption( option ) ) {
						return orig.apply( this, arguments );
					}
					const args = _normalizeArguments.apply( this, arguments );
					args.mode = 'hide';
					return this.effect.call( this, args );
				};
			} )( $.fn.hide ),
			toggle: ( function ( orig ) {
				return function ( option ) {
					if (
						standardAnimationOption( option ) ||
						typeof option === 'boolean'
					) {
						return orig.apply( this, arguments );
					}
					const args = _normalizeArguments.apply( this, arguments );
					args.mode = 'toggle';
					return this.effect.call( this, args );
				};
			} )( $.fn.toggle ),
			// helper functions
			cssUnit( key ) {
				let style = this.css( key ),
					val = [];
				$.each( [ 'em', 'px', '%', 'pt' ], function ( i, unit ) {
					if ( style.indexOf( unit ) > 0 ) {
						val = [ parseFloat( style ), unit ];
					}
				} );
				return val;
			},
		} );
	} )();
	/******************************************************************************/
	/*********************************** EASING ***********************************/
	/******************************************************************************/
	( function () {
		// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
		const baseEasings = {};
		$.each(
			[ 'Quad', 'Cubic', 'Quart', 'Quint', 'Expo' ],
			function ( i, name ) {
				baseEasings[ name ] = function ( p ) {
					return Math.pow( p, i + 2 );
				};
			}
		);
		$.extend( baseEasings, {
			Sine( p ) {
				return 1 - Math.cos( ( p * Math.PI ) / 2 );
			},
			Circ( p ) {
				return 1 - Math.sqrt( 1 - p * p );
			},
			Elastic( p ) {
				return p === 0 || p === 1
					? p
					: -Math.pow( 2, 8 * ( p - 1 ) ) *
							Math.sin(
								( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI ) / 15
							);
			},
			Back( p ) {
				return p * p * ( 3 * p - 2 );
			},
			Bounce( p ) {
				let pow2,
					bounce = 4;
				while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
				return (
					1 / Math.pow( 4, 3 - bounce ) -
					7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 )
				);
			},
		} );
		$.each( baseEasings, function ( name, easeIn ) {
			$.easing[ 'easeIn' + name ] = easeIn;
			$.easing[ 'easeOut' + name ] = function ( p ) {
				return 1 - easeIn( 1 - p );
			};
			$.easing[ 'easeInOut' + name ] = function ( p ) {
				return p < 0.5
					? easeIn( p * 2 ) / 2
					: 1 - easeIn( p * -2 + 2 ) / 2;
			};
		} );
	} )();
} )( jQuery );
