PageSourceSearch

https://mylibidodoc.com/wp-content/themes/magnetique/assets/js/vendors-libs/TweenMax.js?ver=2.0.2

js mylibidodoc.com collected 2026-09-24 19:04:46 UTC 371,777 bytes, 8,014 lines download raw bytes

1/*!
2 * VERSION: 2.0.2
3 * DATE: 2018-08-27
4 * UPDATES AND DOCS AT: http://greensock.com
5 * 
6 * Includes all of the following: TweenLite, TweenMax, TimelineLite, TimelineMax, EasePack, CSSPlugin, RoundPropsPlugin, BezierPlugin, AttrPlugin, DirectionalRotationPlugin
7 *
8 * @license Copyright (c) 2008-2018, GreenSock. All rights reserved.
9 * This work is subject to the terms at http://greensock.com/standard-license or for
10 * Club GreenSock members, the software agreement that was issued with your membership.
11 * 
12 * @author: Jack Doyle, [email protected]
13 **/
14var _gsScope = (typeof(module) !== "undefined" && module.exports && typeof(global) !== "undefined") ? global : this || window; //helps ensure compatibility with AMD/RequireJS and CommonJS/Node
15(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push( function() {
16
17	"use strict";
18
19	_gsScope._gsDefine("TweenMax", ["core.Animation","core.SimpleTimeline","TweenLite"], function(Animation, SimpleTimeline, TweenLite) {
20
21		var _slice = function(a) { //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
22				var b = [],
23					l = a.length,
24					i;
25				for (i = 0; i !== l; b.push(a[i++]));
26				return b;
27			},
28			_applyCycle = function(vars, targets, i) {
29				var alt = vars.cycle,
30					p, val;
31				for (p in alt) {
32					val = alt[p];
33					vars[p] = (typeof(val) === "function") ? val(i, targets[i]) : val[i % val.length];
34				}
35				delete vars.cycle;
36			},
37			TweenMax = function(target, duration, vars) {
38				TweenLite.call(this, target, duration, vars);
39				this._cycle = 0;
40				this._yoyo = (this.vars.yoyo === true || !!this.vars.yoyoEase);
41				this._repeat = this.vars.repeat || 0;
42				this._repeatDelay = this.vars.repeatDelay || 0;
43				if (this._repeat) {
44					this._uncache(true); //ensures that if there is any repeat, the totalDuration will get recalculated to accurately report it.
45				}
46				this.render = TweenMax.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method)
47			},
48			_tinyNum = 0.0000000001,
49			TweenLiteInternals = TweenLite._internals,
50			_isSelector = TweenLiteInternals.isSelector,
51			_isArray = TweenLiteInternals.isArray,
52			p = TweenMax.prototype = TweenLite.to({}, 0.1, {}),
53			_blankArray = [];
54
55		TweenMax.version = "2.0.2";
56		p.constructor = TweenMax;
57		p.kill()._gc = false;
58		TweenMax.killTweensOf = TweenMax.killDelayedCallsTo = TweenLite.killTweensOf;
59		TweenMax.getTweensOf = TweenLite.getTweensOf;
60		TweenMax.lagSmoothing = TweenLite.lagSmoothing;
61		TweenMax.ticker = TweenLite.ticker;
62		TweenMax.render = TweenLite.render;
63
64		p.invalidate = function() {
65			this._yoyo = (this.vars.yoyo === true || !!this.vars.yoyoEase);
66			this._repeat = this.vars.repeat || 0;
67			this._repeatDelay = this.vars.repeatDelay || 0;
68			this._yoyoEase = null;
69			this._uncache(true);
70			return TweenLite.prototype.invalidate.call(this);
71		};
72		
73		p.updateTo = function(vars, resetDuration) {
74			var curRatio = this.ratio,
75				immediate = this.vars.immediateRender || vars.immediateRender,
76				p;
77			if (resetDuration && this._startTime < this._timeline._time) {
78				this._startTime = this._timeline._time;
79				this._uncache(false);
80				if (this._gc) {
81					this._enabled(true, false);
82				} else {
83					this._timeline.insert(this, this._startTime - this._delay); //ensures that any necessary re-sequencing of Animations in the timeline occurs to make sure the rendering order is correct.
84				}
85			}
86			for (p in vars) {
87				this.vars[p] = vars[p];
88			}
89			if (this._initted || immediate) {
90				if (resetDuration) {
91					this._initted = false;
92					if (immediate) {
93						this.render(0, true, true);
94					}
95				} else {
96					if (this._gc) {
97						this._enabled(true, false);
98					}
99					if (this._notifyPluginsOfEnabled && this._firstPT) {
100						TweenLite._onPluginEvent("_onDisable", this); //in case a plugin like MotionBlur must perform some cleanup tasks
101					}
102					if (this._time / this._duration > 0.998) { //if the tween has finished (or come extremely close to finishing), we just need to rewind it to 0 and then render it again at the end which forces it to re-initialize (parsing the new vars). We allow tweens that are close to finishing (but haven't quite finished) to work this way too because otherwise, the values are so small when determining where to project the starting values that binary math issues creep in and can make the tween appear to render incorrectly when run backwards. 
103						var prevTime = this._totalTime;
104						this.render(0, true, false);
105						this._initted = false;
106						this.render(prevTime, true, false);
107					} else {
108						this._initted = false;
109						this._init();
110						if (this._time > 0 || immediate) {
111							var inv = 1 / (1 - curRatio),
112								pt = this._firstPT, endValue;
113							while (pt) {
114								endValue = pt.s + pt.c;
115								pt.c *= inv;
116								pt.s = endValue - pt.c;
117								pt = pt._next;
118							}
119						}
120					}
121				}
122			}
123			return this;
124		};
125				
126		p.render = function(time, suppressEvents, force) {
127			if (!this._initted) if (this._duration === 0 && this.vars.repeat) { //zero duration tweens that render immediately have render() called from TweenLite's constructor, before TweenMax's constructor has finished setting _repeat, _repeatDelay, and _yoyo which are critical in determining totalDuration() so we need to call invalidate() which is a low-kb way to get those set properly.
128				this.invalidate();
129			}
130			var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(),
131				prevTime = this._time,
132				prevTotalTime = this._totalTime, 
133				prevCycle = this._cycle,
134				duration = this._duration,
135				prevRawPrevTime = this._rawPrevTime,
136				isComplete, callback, pt, cycleDuration, r, type, pow, rawPrevTime, yoyoEase;
137			if (time >= totalDur - 0.0000001 && time >= 0) { //to work around occasional floating point math artifacts.
138				this._totalTime = totalDur;
139				this._cycle = this._repeat;
140				if (this._yoyo && (this._cycle & 1) !== 0) {
141					this._time = 0;
142					this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
143				} else {
144					this._time = duration;
145					this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1;
146				}
147				if (!this._reversed) {
148					isComplete = true;
149					callback = "onComplete";
150					force = (force || this._timeline.autoRemoveChildren); //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
151				}
152				if (duration === 0) if (this._initted || !this.vars.lazy || force) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
153					if (this._startTime === this._timeline._duration) { //if a zero-duration tween is at the VERY end of a timeline and that timeline renders at its end, it will typically add a tiny bit of cushion to the render time to prevent rounding errors from getting in the way of tweens rendering their VERY end. If we then reverse() that timeline, the zero-duration tween will trigger its onReverseComplete even though technically the playhead didn't pass over it again. It's a very specific edge case we must accommodate.
154						time = 0;
155					}
156					if (prevRawPrevTime < 0 || (time <= 0 && time >= -0.0000001) || (prevRawPrevTime === _tinyNum && this.data !== "isPause")) if (prevRawPrevTime !== time) { //note: when this.data is "isPause", it's a callback added by addPause() on a timeline that we should not be triggered when LEAVING its exact start time. In other words, tl.addPause(1).play(1) shouldn't pause.
157						force = true;
158						if (prevRawPrevTime > _tinyNum) {
159							callback = "onReverseComplete";
160						}
161					}
162					this._rawPrevTime = rawPrevTime = (!suppressEvents || time || prevRawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
163				}
164				
165			} else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0.
166				this._totalTime = this._time = this._cycle = 0;
167				this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
168				if (prevTotalTime !== 0 || (duration === 0 && prevRawPrevTime > 0)) {
169					callback = "onReverseComplete";
170					isComplete = this._reversed;
171				}
172				if (time < 0) {
173					this._active = false;
174					if (duration === 0) if (this._initted || !this.vars.lazy || force) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
175						if (prevRawPrevTime >= 0) {
176							force = true;
177						}
178						this._rawPrevTime = rawPrevTime = (!suppressEvents || time || prevRawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
179					}
180				}
181				if (!this._initted) { //if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately.
182					force = true;
183				}
184			} else {
185				this._totalTime = this._time = time;
186				if (this._repeat !== 0) {
187					cycleDuration = duration + this._repeatDelay;
188					this._cycle = (this._totalTime / cycleDuration) >> 0; //originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!)
189					if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) {
190						this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning)
191					}
192					this._time = this._totalTime - (this._cycle * cycleDuration);
193					if (this._yoyo) if ((this._cycle & 1) !== 0) {
194						this._time = duration - this._time;
195						yoyoEase = this._yoyoEase || this.vars.yoyoEase; //note: we don't set this._yoyoEase in _init() like we do other properties because it's TweenMax-specific and doing it here allows us to optimize performance (most tweens don't have a yoyoEase). Note that we also must skip the this.ratio calculation further down right after we _init() in this function, because we're doing it here.
196						if (yoyoEase) {
197							if (!this._yoyoEase) {
198								if (yoyoEase === true && !this._initted) { //if it's not initted and yoyoEase is true, this._ease won't have been populated yet so we must discern it here.
199									yoyoEase = this.vars.ease;
200									this._yoyoEase = yoyoEase = !yoyoEase ? TweenLite.defaultEase : (yoyoEase instanceof Ease) ? yoyoEase : (typeof(yoyoEase) === "function") ? new Ease(yoyoEase, this.vars.easeParams) : Ease.map[yoyoEase] || TweenLite.defaultEase;
201								} else {
202									this._yoyoEase = yoyoEase = (yoyoEase === true) ? this._ease : (yoyoEase instanceof Ease) ? yoyoEase : Ease.map[yoyoEase];
203								}
204							}
205							this.ratio = yoyoEase ? 1 - yoyoEase.getRatio((duration - this._time) / duration) : 0;
206						}
207					}
208					if (this._time > duration) {
209						this._time = duration;
210					} else if (this._time < 0) {
211						this._time = 0;
212					}
213				}
214				if (this._easeType && !yoyoEase) {
215					r = this._time / duration;
216					type = this._easeType;
217					pow = this._easePower;
218					if (type === 1 || (type === 3 && r >= 0.5)) {
219						r = 1 - r;
220					}
221					if (type === 3) {
222						r *= 2;
223					}
224					if (pow === 1) {
225						r *= r;
226					} else if (pow === 2) {
227						r *= r * r;
228					} else if (pow === 3) {
229						r *= r * r * r;
230					} else if (pow === 4) {
231						r *= r * r * r * r;
232					}
233
234					if (type === 1) {
235						this.ratio = 1 - r;
236					} else if (type === 2) {
237						this.ratio = r;
238					} else if (this._time / duration < 0.5) {
239						this.ratio = r / 2;
240					} else {
241						this.ratio = 1 - (r / 2);
242					}
243
244				} else if (!yoyoEase) {
245					this.ratio = this._ease.getRatio(this._time / duration);
246				}
247				
248			}
249				
250			if (prevTime === this._time && !force && prevCycle === this._cycle) {
251				if (prevTotalTime !== this._totalTime) if (this._onUpdate) if (!suppressEvents) { //so that onUp
251date fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate.
252					this._callback("onUpdate");
253				}
254				return;
255			} else if (!this._initted) {
256				this._init();
257				if (!this._initted || this._gc) { //immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that overwriting occurs properly. Also, if all of the tweening properties have been overwritten (which would cause _gc to be true, as set in _init()), we shouldn't continue otherwise an onStart callback could be called for example.
258					return;
259				} else if (!force && this._firstPT && ((this.vars.lazy !== false && this._duration) || (this.vars.lazy && !this._duration))) { //we stick it in the queue for rendering at the very end of the tick - this is a performance optimization because browsers invalidate styles and force a recalculation if you read, write, and then read style data (so it's better to read/read/read/write/write/write than read/write/read/write/read/write). The down side, of course, is that usually you WANT things to render immediately because you may have code running right after that which depends on the change. Like imagine running TweenLite.set(...) and then immediately after that, creating a nother tween that animates the same property to another value; the starting values of that 2nd tween wouldn't be accurate if lazy is true.
260					this._time = prevTime;
261					this._totalTime = prevTotalTime;
262					this._rawPrevTime = prevRawPrevTime;
263					this._cycle = prevCycle;
264					TweenLiteInternals.lazyTweens.push(this);
265					this._lazy = [time, suppressEvents];
266					return;
267				}
268				//_ease is initially set to defaultEase, so now that init() has run, _ease is set properly and we need to recalculate the ratio. Overall this is faster than using conditional logic earlier in the method to avoid having to set ratio twice because we only init() once but renderTime() gets called VERY frequently.
269				if (this._time && !isComplete && !yoyoEase) {
270					this.ratio = this._ease.getRatio(this._time / duration);
271				} else if (isComplete && this._ease._calcEnd && !yoyoEase) {
272					this.ratio = this._ease.getRatio((this._time === 0) ? 0 : 1);
273				}
274			}
275			if (this._lazy !== false) {
276				this._lazy = false;
277			}
278
279			if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) {
280				this._active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done.
281			}
282			if (prevTotalTime === 0) {
283				if (this._initted === 2 && time > 0) {
284					//this.invalidate();
285					this._init(); //will just apply overwriting since _initted of (2) means it was a from() tween that had immediateRender:true
286				}
287				if (this._startAt) {
288					if (time >= 0) {
289						this._startAt.render(time, true, force);
290					} else if (!callback) {
291						callback = "_dummyGS"; //if no callback is defined, use a dummy value just so that the condition at the end evaluates as true because _startAt should render AFTER the normal render loop when the time is negative. We could handle this in a more intuitive way, of course, but the render loop is the MOST important thing to optimize, so this technique allows us to avoid adding extra conditional logic in a high-frequency area.
292					}
293				}
294				if (this.vars.onStart) if (this._totalTime !== 0 || duration === 0) if (!suppressEvents) {
295					this._callback("onStart");
296				}
297			}
298			
299			pt = this._firstPT;
300			while (pt) {
301				if (pt.f) {
302					pt.t[pt.p](pt.c * this.ratio + pt.s);
303				} else {
304					pt.t[pt.p] = pt.c * this.ratio + pt.s;
305				}
306				pt = pt._next;
307			}
308			
309			if (this._onUpdate) {
310				if (time < 0) if (this._startAt && this._startTime) { //if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values.
311					this._startAt.render(time, true, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete.
312				}
313				if (!suppressEvents) if (this._totalTime !== prevTotalTime || callback) {
314					this._callback("onUpdate");
315				}
316			}
317			if (this._cycle !== prevCycle) if (!suppressEvents) if (!this._gc) if (this.vars.onRepeat) {
318				this._callback("onRepeat");
319			}
320			if (callback) if (!this._gc || force) { //check gc because there's a chance that kill() could be called in an onUpdate
321				if (time < 0 && this._startAt && !this._onUpdate && this._startTime) { //if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values.
322					this._startAt.render(time, true, force);
323				}
324				if (isComplete) {
325					if (this._timeline.autoRemoveChildren) {
326						this._enabled(false, false);
327					}
328					this._active = false;
329				}
330				if (!suppressEvents && this.vars[callback]) {
331					this._callback(callback);
332				}
333				if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) { //the onComplete or onReverseComplete could trigger movement of the playhead and for zero-duration tweens (which must discern direction) that land directly back on their start time, we don't want to fire again on the next render. Think of several addPause()'s in a timeline that forces the playhead to a certain spot, but what if it's already paused and another tween is tweening the "time" of the timeline? Each time it moves [forward] past that spot, it would move back, and since suppressEvents is true, it'd reset _rawPrevTime to _tinyNum so that when it begins again, the callback would fire (so ultimately it could bounce back and forth during that tween). Again, this is a very uncommon sce
333nario, but possible nonetheless.
334					this._rawPrevTime = 0;
335				}
336			}
337		};
338		
339//---- STATIC FUNCTIONS -----------------------------------------------------------------------------------------------------------
340		
341		TweenMax.to = function(target, duration, vars) {
342			return new TweenMax(target, duration, vars);
343		};
344		
345		TweenMax.from = function(target, duration, vars) {
346			vars.runBackwards = true;
347			vars.immediateRender = (vars.immediateRender != false);
348			return new TweenMax(target, duration, vars);
349		};
350		
351		TweenMax.fromTo = function(target, duration, fromVars, toVars) {
352			toVars.startAt = fromVars;
353			toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false);
354			return new TweenMax(target, duration, toVars);
355		};
356		
357		TweenMax.staggerTo = TweenMax.allTo = function(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
358			stagger = stagger || 0;
359			var delay = 0,
360				a = [],
361				finalComplete = function() {
362					if (vars.onComplete) {
363						vars.onComplete.apply(vars.onCompleteScope || this, arguments);
364					}
365					onCompleteAll.apply(onCompleteAllScope || vars.callbackScope || this, onCompleteAllParams || _blankArray);
366				},
367				cycle = vars.cycle,
368				fromCycle = (vars.startAt && vars.startAt.cycle),
369				l, copy, i, p;
370			if (!_isArray(targets)) {
371				if (typeof(targets) === "string") {
372					targets = TweenLite.selector(targets) || targets;
373				}
374				if (_isSelector(targets)) {
375					targets = _slice(targets);
376				}
377			}
378			targets = targets || [];
379			if (stagger < 0) {
380				targets = _slice(targets);
381				targets.reverse();
382				stagger *= -1;
383			}
384			l = targets.length - 1;
385			for (i = 0; i <= l; i++) {
386				copy = {};
387				for (p in vars) {
388					copy[p] = vars[p];
389				}
390				if (cycle) {
391					_applyCycle(copy, targets, i);
392					if (copy.duration != null) {
393						duration = copy.duration;
394						delete copy.duration;
395					}
396				}
397				if (fromCycle) {
398					fromCycle = copy.startAt = {};
399					for (p in vars.startAt) {
400						fromCycle[p] = vars.startAt[p];
401					}
402					_applyCycle(copy.startAt, targets, i);
403				}
404				copy.delay = delay + (copy.delay || 0);
405				if (i === l && onCompleteAll) {
406					copy.onComplete = finalComplete;
407				}
408				a[i] = new TweenMax(targets[i], duration, copy);
409				delay += stagger;
410			}
411			return a;
412		};
413		
414		TweenMax.staggerFrom = TweenMax.allFrom = function(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
415			vars.runBackwards = true;
416			vars.immediateRender = (vars.immediateRender != false);
417			return TweenMax.staggerTo(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
418		};
419		
420		TweenMax.staggerFromTo = TweenMax.allFromTo = function(targets, duration, fromVars, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
421			toVars.startAt = fromVars;
422			toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false);
423			return TweenMax.staggerTo(targets, duration, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
424		};
425				
426		TweenMax.delayedCall = function(delay, callback, params, scope, useFrames) {
427			return new TweenMax(callback, 0, {delay:delay, onComplete:callback, onCompleteParams:params, callbackScope:scope, onReverseComplete:callback, onReverseCompleteParams:params, immediateRender:false, useFrames:useFrames, overwrite:0});
428		};
429		
430		TweenMax.set = function(target, vars) {
431			return new TweenMax(target, 0, vars);
432		};
433		
434		TweenMax.isTweening = function(target) {
435			return (TweenLite.getTweensOf(target, true).length > 0);
436		};
437		
438		var _getChildrenOf = function(timeline, includeTimelines) {
439				var a = [],
440					cnt = 0,
441					tween = timeline._first;
442				while (tween) {
443					if (tween instanceof TweenLite) {
444						a[cnt++] = tween;
445					} else {
446						if (includeTimelines) {
447							a[cnt++] = tween;
448						}
449						a = a.concat(_getChildrenOf(tween, includeTimelines));
450						cnt = a.length;
451					}
452					tween = tween._next;
453				}
454				return a;
455			}, 
456			getAllTweens = TweenMax.getAllTweens = function(includeTimelines) {
457				return _getChildrenOf(Animation._rootTimeline, includeTimelines).concat( _getChildrenOf(Animation._rootFramesTimeline, includeTimelines) );
458			};
459		
460		TweenMax.killAll = function(complete, tweens, delayedCalls, timelines) {
461			if (tweens == null) {
462				tweens = true;
463			}
464			if (delayedCalls == null) {
465				delayedCalls = true;
466			}
467			var a = getAllTweens((timelines != false)),
468				l = a.length,
469				allTrue = (tweens && delayedCalls && timelines),
470				isDC, tween, i;
471			for (i = 0; i < l; i++) {
472				tween = a[i];
473				if (allTrue || (tween instanceof SimpleTimeline) || ((isDC = (tween.target === tween.vars.onComplete)) && delayedCalls) || (tweens && !isDC)) {
474					if (complete) {
475						tween.totalTime(tween._reversed ? 0 : tween.totalDuration());
476					} else {
477						tween._enabled(false, false);
478					}
479				}
480			}
481		};
482		
483		TweenMax.killChildTweensOf = function(parent, complete) {
484			if (parent == null) {
485				return;
486			}
487			var tl = TweenLiteInternals.tweenLookup,
488				a, curParent, p, i, l;
489			if (typeof(parent) === "string") {
490				parent = TweenLite.selector(parent) || parent;
491			}
492			if (_isSelector(parent)) {
493				parent = _slice(parent);
494			}
495			if (_isArray(parent)) {
496				i = parent.length;
497				while (--i > -1) {
498					TweenMax.killChildTweensOf(parent[i], complete);
499				}
500				return;
501			}
502			a = [];
503			for (p in tl) {
504				curParent = tl[p].target.parentNode;
505				while (curParent) {
506					if (curParent === parent) {
507						a = a.concat(tl[p].tweens);
508					}
509					curParent = curParent.parentNode;
510				}
511			}
512			l = a.length;
513			for (i = 0; i < l; i++) {
514				if (complete) {
515					a[i].totalTime(a[i].totalDuration());
516				}
517				a[i]._enabled(false, false);
518			}
519		};
520
521		var _changePause = function(pause, tweens, delayedCalls, timelines) {
522			tweens = (tweens !== false);
523			delayedCalls = (delayedCalls !== false);
524			timelines = (timelines !== false);
525			var a = getAllTweens(timelines),
526				allTrue = (tweens && delayedCalls && timelines),
527				i = a.length,
528				isDC, tween;
529			while (--i > -1) {
530				tween = a[i];
531				if (allTrue || (tween instanceof SimpleTimeline) || ((isDC = (tween.target === tween.vars.onComplete)) && delayedCalls) || (tweens && !isDC)) {
532					tween.paused(pause);
533				}
534			}
535		};
536		
537		TweenMax.pauseAll = function(tweens, delayedCalls, timelines) {
538			_changePause(true, tweens, delayedCalls, timelines);
539		};
540		
541		TweenMax.resumeAll = function(tweens, delayedCalls, timelines) {
542			_changePause(false, tweens, delayedCalls, timelines);
543		};
544
545		TweenMax.globalTimeScale = function(value) {
546			var tl = Animation._rootTimeline,
547				t = TweenLite.ticker.time;
548			if (!arguments.length) {
549				return tl._timeScale;
550			}
551			value = value || _tinyNum; //can't allow zero because it'll throw the math off
552			tl._startTime = t - ((t - tl._startTime) * tl._timeScale / value);
553			tl = Animation._rootFramesTimeline;
554			t = TweenLite.ticker.frame;
555			tl._startTime = t - ((t - tl._startTime) * tl._timeScale / value);
556			tl._timeScale = Animation._rootTimeline._timeScale = value;
557			return value;
558		};
559		
560	
561//---- GETTERS / SETTERS ----------------------------------------------------------------------------------------------------------
562		
563		p.progress = function(value, suppressEvents) {
564			return (!arguments.length) ? this._time / this.duration() : this.totalTime( this.duration() * ((this._yoyo && (this._cycle & 1) !== 0) ? 1 - value : value) + (this._cycle * (this._duration + this._repeatDelay)), suppressEvents);
565		};
566		
567		p.totalProgress = function(value, suppressEvents) {
568			return (!arguments.length) ? this._totalTime / this.totalDuration() : this.totalTime( this.totalDuration() * value, suppressEvents);
569		};
570		
571		p.time = function(value, suppressEvents) {
572			if (!arguments.length) {
573				return this._time;
574			}
575			if (this._dirty) {
576				this.totalDuration();
577			}
578			if (value > this._duration) {
579				value = this._duration;
580			}
581			if (this._yoyo && (this._cycle & 1) !== 0) {
582				value = (this._duration - value) + (this._cycle * (this._duration + this._repeatDelay));
583			} else if (this._repeat !== 0) {
584				value += this._cycle * (this._duration + this._repeatDelay);
585			}
586			return this.totalTime(value, suppressEvents);
587		};
588
589		p.duration = function(value) {
590			if (!arguments.length) {
591				return this._duration; //don't set _dirty = false because there could be repeats that haven't been factored into the _totalDuration yet. Otherwise, if you create a repeated TweenMax and then immediately check its duration(), it would cache the value and the totalDuration would not be correct, thus repeats wouldn't take effect.
592			}
593			return Animation.prototype.duration.call(this, value);
594		};
595
596		p.totalDuration = function(value) {
597			if (!arguments.length) {
598				if (this._dirty) {
599					//instead of Infinity, we use 999999999999 so that we can accommodate reverses
600					this._totalDuration = (this._repeat === -1) ? 999999999999 : this._duration * (this._repeat + 1) + (this._repeatDelay * this._repeat);
601					this._dirty = false;
602				}
603				return this._totalDuration;
604			}
605			return (this._repeat === -1) ? this : this.duration( (value - (this._repeat * this._repeatDelay)) / (this._repeat + 1) );
606		};
607		
608		p.repeat = function(value) {
609			if (!arguments.length) {
610				return this._repeat;
611			}
612			this._repeat = value;
613			return this._uncache(true);
614		};
615		
616		p.repeatDelay = function(value) {
617			if (!arguments.length) {
618				return this._repeatDelay;
619			}
620			this._repeatDelay = value;
621			return this._uncache(true);
622		};
623		
624		p.yoyo = function(value) {
625			if (!arguments.length) {
626				return this._yoyo;
627			}
628			this._yoyo = value;
629			return this;
630		};
631		
632		
633		return TweenMax;
634		
635	}, true);
636
637
638
639
640
641
642
643
644/*
645 * ----------------------------------------------------------------
646 * TimelineLite
647 * ----------------------------------------------------------------
648 */
649	_gsScope._gsDefine("TimelineLite", ["core.Animation","core.SimpleTimeline","TweenLite"], function(Animation, SimpleTimeline, TweenLite) {
650
651		var TimelineLite = function(vars) {
652				SimpleTimeline.call(this, vars);
653				this._labels = {};
654				this.autoRemoveChildren = (this.vars.autoRemoveChildren === true);
655				this.smoothChildTiming = (this.vars.smoothChildTiming === true);
656				this._sortChildren = true;
657				this._onUpdate = this.vars.onUpdate;
658				var v = this.vars,
659					val, p;
660				for (p in v) {
661					val = v[p];
662					if (_isArray(val)) if (val.join("").indexOf("{self}") !== -1) {
663						v[p] = this._swapSelfInParams(val);
664					}
665				}
666				if (_isArray(v.tweens)) {
667					this.add(v.tweens, 0, v.align, v.stagger);
668				}
669			},
670			_tinyNum = 0.0000000001,
671			TweenLiteInternals = TweenLite._internals,
672			_internals = TimelineLite._internals = {},
673			_isSelector = TweenLiteInternals.isSelector,
674			_isArray = TweenLiteInternals.isArray,
675			_lazyTweens = TweenLiteInternals.lazyTweens,
676			_lazyRender = TweenLiteInternals.lazyRender,
677			_globals = _gsScope._gsDefine.globals,
678			_copy = function(vars) {
679				var copy = {}, p;
680				for (p in vars) {
681					copy[p] = vars[p];
682				}
683				return copy;
684			},
685			_applyCycle = function(vars, targets, i) {
686				var alt = vars.cycle,
687					p, val;
688				for (p in alt) {
689					val = alt[p];
690					vars[p] = (typeof(val) === "function") ? val(i, targets[i]) : val[i % val.length];
691				}
692				delete vars.cycle;
693			},
694			_pauseCallback = _internals.pauseCallback = function() {},
695			_slice = function(a) { //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
696				var b = [],
697					l = a.length,
698					i;
699				for (i = 0; i !== l; b.push(a[i++]));
700				return b;
701			},
702			p = TimelineLite.prototype = new SimpleTimeline();
703
704		TimelineLite.version = "2.0.2";
705		p.constructor = TimelineLite;
706		p.kill()._gc = p._forcingPlayhead = p._hasPause = false;
707
708		/* might use later...
709		//translates a local time inside an animation to the corresponding time on the root/global timeline, factoring in all nesting and timeScales.
710		function localToGlobal(time, animation) {
711			while (animation) {
712				time = (time / animation._timeScale) + animation._startTime;
713				animation = animation.timeline;
714			}
715			return time;
716		}
717
718		//translates the supplied time on the root/global timeline into the corresponding local time inside a particular animation, factoring in all nesting and timeScales
719		function globalToLocal(time, animation) {
720			var scale = 1;
721			time -= localToGlobal(0, animation);
722			while (animation) {
723				scale *= animation._timeScale;
724				animation = animation.timeline;
725			}
726			return time * scale;
727		}
728		*/
729
730		p.to = function(target, duration, vars, position) {
731			var Engine = (vars.repeat && _globals.TweenMax) || TweenLite;
732			return duration ? this.add( new Engine(target, duration, vars), position) : this.set(target, vars, position);
733		};
734
735		p.from = function(target, duration, vars, position) {
736			return this.add( ((vars.repeat && _globals.TweenMax) || TweenLite).from(target, duration, vars), position);
737		};
738
739		p.fromTo = function(target, duration, fromVars, toVars, position) {
740			var Engine = (toVars.repeat && _globals.TweenMax) || TweenLite;
741			return duration ? this.add( Engine.fromTo(target, duration, fromVars, toVars), position) : this.set(target, toVars, position);
742		};
743
744		p.staggerTo = function(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
745			var tl = new TimelineLite({onComplete:onCompleteAll, onCompleteParams:onCompleteAllParams, callbackScope:onCompleteAllScope, smoothChildTiming:this.smoothChildTiming}),
746				cycle = vars.cycle,
747				copy, i;
748			if (typeof(targets) === "string") {
749				targets = TweenLite.selector(targets) || targets;
750			}
751			targets = targets || [];
752			if (_isSelector(targets)) { //senses if the targets object is a selector. If it is, we should translate it into an array.
753				targets = _slice(targets);
754			}
755			stagger = stagger || 0;
756			if (stagger < 0) {
757				targets = _slice(targets);
758				targets.reverse();
759				stagger *= -1;
760			}
761			for (i = 0; i < targets.length; i++) {
762				copy = _copy(vars);
763				if (copy.startAt) {
764					copy.startAt = _copy(copy.startAt);
765					if (copy.startAt.cycle) {
766						_applyCycle(copy.startAt, targets, i);
767					}
768				}
769				if (cycle) {
770					_applyCycle(copy, targets, i);
771					if (copy.duration != null) {
772						duration = copy.duration;
773						delete copy.duration;
774					}
775				}
776				tl.to(targets[i], duration, copy, i * stagger);
777			}
778			return this.add(tl, position);
779		};
780
781		p.staggerFrom = function(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
782			vars.immediateRender = (vars.immediateRender != false);
783			vars.runBackwards = true;
784			return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
785		};
786
787		p.staggerFromTo = function(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
788			toVars.startAt = fromVars;
789			toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false);
790			return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
791		};
792
793		p.call = function(callback, params, scope, position) {
794			return this.add( TweenLite.delayedCall(0, callback, params, scope), position);
795		};
796
797		p.set = function(target, vars, position) {
798			position = this._parseTimeOrLabel(position, 0, true);
799			if (vars.immediateRender == null) {
800				vars.immediateRender = (position === this._time && !this._paused);
801			}
802			return this.add( new TweenLite(target, 0, vars), position);
803		};
804
805		TimelineLite.exportRoot = function(vars, ignoreDelayedCalls) {
806			vars = vars || {};
807			if (vars.smoothChildTiming == null) {
808				vars.smoothChildTiming = true;
809			}
810			var tl = new TimelineLite(vars),
811				root = tl._timeline,
812				hasNegativeStart, time,	tween, next;
813			if (ignoreDelayedCalls == null) {
814				ignoreDelayedCalls = true;
815			}
816			root._remove(tl, true);
817			tl._startTime = 0;
818			tl._rawPrevTime = tl._time = tl._totalTime = root._time;
819			tween = root._first;
820			while (tween) {
821				next = tween._next;
822				if (!ignoreDelayedCalls || !(tween instanceof TweenLite && tween.target === tween.vars.onComplete)) {
823					time = tween._startTime - tween._delay;
824					if (time < 0) {
825						hasNegativeStart = 1;
826					}
827					tl.add(tween, time);
828				}
829				tween = next;
830			}
831			root.add(tl, 0);
832			if (hasNegativeStart) { //calling totalDuration() will force the adjustment necessary to shift the children forward so none of them start before zero, and moves the timeline backwards the same amount, so the playhead is still aligned where it should be globally, but the timeline doesn't have illegal children that start before zero.
833				tl.totalDuration();
834			}
835			return tl;
836		};
837
838		p.add = function(value, position, align, stagger) {
839			var curTime, l, i, child, tl, beforeRawTime;
840			if (typeof(position) !== "number") {
841				position = this._parseTimeOrLabel(position, 0, true, value);
842			}
843			if (!(value instanceof Animation)) {
844				if ((value instanceof Array) || (value && value.push && _isArray(value))) {
845					align = align || "normal";
846					stagger = stagger || 0;
847					curTime = position;
848					l = value.length;
849					for (i = 0; i < l; i++) {
850						if (_isArray(child = value[i])) {
851							child = new TimelineLite({tweens:child});
852						}
853						this.add(child, curTime);
854						if (typeof(child) !== "string" && typeof(child) !== "function") {
855							if (align === "sequence") {
856								curTime = child._startTime + (child.totalDuration() / child._timeScale);
857							} else if (align === "start") {
858								child._startTime -= child.delay();
859							}
860						}
861						curTime += stagger;
862					}
863					return this._uncache(true);
864				} else if (typeof(value) === "string") {
865					return this.addLabel(value, position);
866				} else if (typeof(value) === "function") {
867					value = TweenLite.delayedCall(0, value);
868				} else {
869					throw("Cannot add " + value + " into the timeline; it is not a tween, timeline, function, or string.");
870				}
871			}
872
873			SimpleTimeline.prototype.add.call(this, value, position);
874
875			if (value._time) { //in case, for example, the _startTime is moved on a tween that has already rendered. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning.
876				curTime = Math.max(0, Math.min(value.totalDuration(), (this.rawTime() - value._startTime) * value._timeScale));
877				if (Math.abs(curTime - value._totalTime) > 0.00001) { //if an onComplete restarts the tween in a nested timeline, for example, there could be an endless loop without this logic (v2.0.2), like var masterTL = new TimelineMax({autoRemoveChildren: true}), tl = new TimelineMax(); tl.eventCallback("onComplete", function() { tl.restart() } );tl.fromTo('div', 1.1, { rotation: 0 }, { rotation: 360 }, 0);masterTL.add(tl);
878					value.render(curTime, false, false);
879				}
880			}
881
882			//if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate.
883			if (this._gc || this._time === this._duration) if (!this._paused) if (this._duration < this.duration()) {
884				//in case any of the ancestors had completed but should now be enabled...
885				tl = this;
886				beforeRawTime = (tl.rawTime() > value._startTime); //if the tween is placed on the timeline so that it starts BEFORE the current rawTime, we should align the playhead (move the timeline). This is because sometimes users will create a timeline, let it finish, and much later append a tween and expect it to run instead of jumping to its end state. While technically one could argue that it should jump to its end state, that's not what users intuitively expect.
887				while (tl._timeline) {
888					if (beforeRawTime && tl._timeline.smoothChildTiming) {
889						tl.totalTime(tl._totalTime, true); //moves the timeline (shifts its startTime) if necessary, and also enables it.
890					} else if (tl._gc) {
891						tl._enabled(true, false);
892					}
893					tl = tl._timeline;
894				}
895			}
896
897			return this;
898		};
899
900		p.remove = function(value) {
901			if (value instanceof Animation) {
902				this._remove(value, false);
903				var tl = value._timeline = value.vars.useFrames ? Animation._rootFramesTimeline : Animation._rootTimeline; //now that it's removed, default it to the root timeline so that if it gets played again, it doesn't jump back into this timeline.
904				value._startTime = (value._paused ? value._pauseTime : tl._time) - ((!value._reversed ? value._totalTime : value.totalDuration() - value._totalTime) / value._timeScale); //ensure that if it gets played again, the timing is correct.
905				return this;
906			} else if (value instanceof Array || (value && value.push && _isArray(value))) {
907				var i = value.length;
908				while (--i > -1) {
909					this.remove(value[i]);
910				}
911				return this;
912			} else if (typeof(value) === "string") {
913				return this.removeLabel(value);
914			}
915			return this.kill(null, value);
916		};
917
918		p._remove = function(tween, skipDisable) {
919			SimpleTimeline.prototype._remove.call(this, tween, skipDisable);
920			var last = this._last;
921			if (!last) {
922				this._time = this._totalTime = this._duration = this._totalDuration = 0;
923			} else if (this._time > this.duration()) {
924				this._time = this._duration;
925				this._totalTime = this._totalDuration;
926			}
927			return this;
928		};
929
930		p.append = function(value, offsetOrLabel) {
931			return this.add(value, this._parseTimeOrLabel(null, offsetOrLabel, true, value));
932		};
933
934		p.insert = p.insertMultiple = function(value, position, align, stagger) {
935			return this.add(value, position || 0, align, stagger);
936		};
937
938		p.appendMultiple = function(tweens, offsetOrLabel, align, stagger) {
939			return this.add(tweens, this._parseTimeOrLabel(null, offsetOrLabel, true, tweens), align, stagger);
940		};
941
942		p.addLabel = function(label, position) {
943			this._labels[label] = this._parseTimeOrLabel(position);
944			return this;
945		};
946
947		p.addPause = function(position, callback, params, scope) {
948			var t = TweenLite.delayedCall(0, _pauseCallback, params, scope || this);
949			t.vars.onComplete = t.vars.onReverseComplete = callback;
950			t.data = "isPause";
951			this._hasPause = true;
952			return this.add(t, position);
953		};
954
955		p.removeLabel = function(label) {
956			delete this._labels[label];
957			return this;
958		};
959
960		p.getLabelTime = function(label) {
961			return (this._labels[label] != null) ? this._labels[label] : -1;
962		};
963
964		p._parseTimeOrLabel = function(timeOrLabel, offsetOrLabel, appendIfAbsent, ignore) {
965			var clippedDuration, i;
966			//if we're about to add a tween/timeline (or an array of them) that's already a child of this timeline, we should remove it first so that it doesn't contaminate the duration().
967			if (ignore instanceof Animation && ignore.timeline === this) {
968				this.remove(ignore);
969			} else if (ignore && ((ignore instanceof Array) || (ignore.push && _isArray(ignore)))) {
970				i = ignore.length;
971				while (--i > -1) {
972					if (ignore[i] instanceof Animation && ignore[i].timeline === this) {
973						this.remove(ignore[i]);
974					}
975				}
976			}
977			clippedDuration = (typeof(timeOrLabel) === "number" && !offsetOrLabel) ? 0 : (this.duration() > 99999999999) ? this.recent().endTime(false) : this._duration; //in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead.
978			if (typeof(offsetOrLabel) === "string") {
979				return this._parseTimeOrLabel(offsetOrLabel, (appendIfAbsent && typeof(timeOrLabel) === "number" && this._labels[offsetOrLabel] == null) ? timeOrLabel - clippedDuration : 0, appendIfAbsent);
980			}
981			offsetOrLabel = offsetOrLabel || 0;
982			if (typeof(timeOrLabel) === "string" && (isNaN(timeOrLabel) || this._labels[timeOrLabel] != null)) { //if the string is a number like "1", check to see if there's a label with that name, otherwise interpret it as a number (absolute value).
983				i = timeOrLabel.indexOf("=");
984				if (i === -1) {
985					if (this._labels[timeOrLabel] == null) {
986						return appendIfAbsent ? (this._labels[timeOrLabel] = clippedDuration + offsetOrLabel) : offsetOrLabel;
987					}
988					return this._labels[timeOrLabel] + offsetOrLabel;
989				}
990				offsetOrLabel = parseInt(timeOrLabel.charAt(i-1) + "1", 10) * Number(timeOrLabel.substr(i+1));
991				timeOrLabel = (i > 1) ? this._parseTimeOrLabel(timeOrLabel.substr(0, i-1), 0, appendIfAbsent) : clippedDuration;
992			} else if (timeOrLabel == null) {
993				timeOrLabel = clippedDuration;
994			}
995			return Number(timeOrLabel) + offsetOrLabel;
996		};
997
998		p.seek = function(position, suppressEvents) {
999			return this.totalTime((typeof(position) === "number") ? position : this._parseTimeOrLabel(position), (suppressEvents !== false));
1000		};
1001
1002		p.stop = function() {
1003			return this.paused(true);
1004		};
1005
1006		p.gotoAndPlay = function(position, suppressEvents) {
1007			return this.play(position, suppressEvents);
1008		};
1009
1010		p.gotoAndStop = function(position, suppressEvents) {
1011			return this.pause(position, suppressEvents);
1012		};
1013
1014		p.render = function(time, suppressEvents, force) {
1015			if (this._gc) {
1016				this._enabled(true, false);
1017			}
1018			var prevTime = this._time,
1019				totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(),
1020				prevStart = this._startTime,
1021				prevTimeScale = this._timeScale,
1022				prevPaused = this._paused,
1023				tween, isComplete, next, callback, internalForce, pauseTween, curTime;
1024			if (prevTime !== this._time) { //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump).
1025				time += this._time - prevTime;
1026			}
1027			if (time >= totalDur - 0.0000001 && time >= 0) { //to work around occasional floating point math artifacts.
1028				this._totalTime = this._time = totalDur;
1029				if (!this._reversed) if (!this._hasPausedChild()) {
1030					isComplete = true;
1031					callback = "onComplete";
1032					internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
1033					if (this._duration === 0) if ((time <= 0 && time >= -0.0000001) || this._rawPrevTime < 0 || this._rawPrevTime === _tinyNum) if (this._rawPrevTime !== time && this._first) {
1034						internalForce = true;
1035						if (this._rawPrevTime > _tinyNum) {
1036							callback = "onReverseComplete";
1037						}
1038					}
1039				}
1040				this._rawPrevTime = (this._duration || !suppressEvents || time || this._rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
1041				time = totalDur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7.
1042
1043			} else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0.
1044				this._totalTime = this._time = 0;
1045				if (prevTime !== 0 || (this._duration === 0 && this._rawPrevTime !== _tinyNum && (this._rawPrevTime > 0 || (time < 0 && this._rawPrevTime >= 0)))) {
1046					callback = "onReverseComplete";
1047					isComplete = this._reversed;
1048				}
1049				if (time < 0) {
1050					this._active = false;
1051					if (this._timeline.autoRemoveChildren && this._reversed) { //ensures proper GC if a timeline is resumed after it's finished reversing.
1052						internalForce = isComplete = true;
1053						callback = "onReverseComplete";
1054					} else if (this._rawPrevTime >= 0 && this._first) { //when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state.
1055						internalForce = true;
1056					}
1057					this._rawPrevTime = time;
1058				} else {
1059					this._rawPrevTime = (this._duration || !suppressEvents || time || this._rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
1060					if (time === 0 && isComplete) { //if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good).
1061						tween = this._first;
1062						while (tween && tween._startTime === 0) {
1063							if (!tween._duration) {
1064								isComplete = false;
1065							}
1066							tween = tween._next;
1067						}
1068					}
1069					time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
1070					if (!this._initted) {
1071						internalForce = true;
1072					}
1073				}
1074
1075			} else {
1076
1077				if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
1078					if (time >= prevTime) {
1079						tween = this._first;
1080						while (tween && tween._startTime <= time && !pauseTween) {
1081							if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
1082								pauseTween = tween;
1083							}
1084							tween = tween._next;
1085						}
1086					} else {
1087						tween = this._last;
1088						while (tween && tween._startTime >= time && !pauseTween) {
1089							if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) {
1090								pauseTween = tween;
1091							}
1092							tween = tween._prev;
1093						}
1094					}
1095					if (pauseTween) {
1096						this._time = time = pauseTween._startTime;
1097						this._totalTime = time + (this._cycle * (this._totalDuration + this._repeatDelay));
1098					}
1099				}
1100
1101				this._totalTime = this._time = this._rawPrevTime = time;
1102			}
1103			if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
1104				return;
1105			} else if (!this._initted) {
1106				this._initted = true;
1107			}
1108
1109			if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) {
1110				this._active = true;  //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example.
1111			}
1112
1113			if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0 || !this._duration) if (!suppressEvents) {
1114				this._callback("onStart");
1115			}
1116
1117			curTime = this._time;
1118			if (curTime >= prevTime) {
1119				tween = this._first;
1120				while (tween) {
1121					next = tween._next; //record it here because the value could change after rendering...
1122					if (curTime !== this._time || (this._paused && !prevPaused)) { //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
1123						break;
1124					} else if (tween._active || (tween._startTime <= curTime && !tween._paused && !tween._gc)) {
1125						if (pauseTween === tween) {
1126							this.pause();
1127						}
1128						if (!tween._reversed) {
1129							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
1130						} else {
1131							tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force);
1132						}
1133					}
1134					tween = next;
1135				}
1136			} else {
1137				tween = this._last;
1138				while (tween) {
1139					next = tween._prev; //record it here because the value could change after rendering...
1140					if (curTime !== this._time || (this._paused && !prevPaused)) { //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
1141						break;
1142					} else if (tween._active || (tween._startTime <= prevTime && !tween._paused && !tween._gc)) {
1143						if (pauseTween === tween) {
1144							pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse.
1145							while (pauseTween && pauseTween.endTime() > this._time) {
1146								pauseTween.render( (pauseTween._reversed ? pauseTween.totalDuration() - ((time - pauseTween._startTime) * pauseTween._timeScale) : (time - pauseTween._startTime) * pauseTween._timeScale), suppressEvents, force);
1147								pauseTween = pauseTween._prev;
1148							}
1149							pauseTween = null;
1150							this.pause();
1151						}
1152						if (!tween._reversed) {
1153							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
1154						} else {
1155							tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force);
1156						}
1157					}
1158					tween = next;
1159				}
1160			}
1161
1162			if (this._onUpdate) if (!suppressEvents) {
1163				if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.
1164					_lazyRender();
1165				}
1166				this._callback("onUpdate");
1167			}
1168
1169			if (callback) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) { //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate
1170				if (isComplete) {
1171					if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values.
1172						_lazyRender();
1173					}
1174					if (this._timeline.autoRemoveChildren) {
1175						this._enabled(false, false);
1176					}
1177					this._active = false;
1178				}
1179				if (!suppressEvents && this.vars[callback]) {
1180					this._callback(callback);
1181				}
1182			}
1183		};
1184
1185		p._hasPausedChild = function() {
1186			var tween = this._first;
1187			while (tween) {
1188				if (tween._paused || ((tween instanceof TimelineLite) && tween._hasPausedChild())) {
1189					return true;
1190				}
1191				tween = tween._next;
1192			}
1193			return false;
1194		};
1195
1196		p.getChildren = function(nested, tweens, timelines, ignoreBeforeTime) {
1197			ignoreBeforeTime = ignoreBeforeTime || -9999999999;
1198			var a = [],
1199				tween = this._first,
1200				cnt = 0;
1201			while (tween) {
1202				if (tween._startTime < ignoreBeforeTime) {
1203					//do nothing
1204				} else if (tween instanceof TweenLite) {
1205					if (tweens !== false) {
1206						a[cnt++] = tween;
1207					}
1208				} else {
1209					if (timelines !== false) {
1210						a[cnt++] = tween;
1211					}
1212					if (nested !== false) {
1213						a = a.concat(tween.getChildren(true, tweens, timelines));
1214						cnt = a.length;
1215					}
1216				}
1217				tween = tween._next;
1218			}
1219			return a;
1220		};
1221
1222		p.getTweensOf = function(target, nested) {
1223			var disabled = this._gc,
1224				a = [],
1225				cnt = 0,
1226				tweens, i;
1227			if (disabled) {
1228				this._enabled(true, true); //getTweensOf() filters out disabled tweens, and we have to mark them as _gc = true when the timeline completes in order to allow clean garbage collection, so temporarily re-enable the timeline here.
1229			}
1230			tweens = TweenLite.getTweensOf(target);
1231			i = tweens.length;
1232			while (--i > -1) {
1233				if (tweens[i].timeline === this || (nested && this._contains(tweens[i]))) {
1234					a[cnt++] = tweens[i];
1235				}
1236			}
1237			if (disabled) {
1238				this._enabled(false, true);
1239			}
1240			return a;
1241		};
1242
1243		p.recent = function() {
1244			return this._recent;
1245		};
1246
1247		p._contains = function(tween) {
1248			var tl = tween.timeline;
1249			while (tl) {
1250				if (tl === this) {
1251					return true;
1252				}
1253				tl = tl.timeline;
1254			}
1255			return false;
1256		};
1257
1258		p.shiftChildren = function(amount, adjustLabels, ignoreBeforeTime) {
1259			ignoreBeforeTime = ignoreBeforeTime || 0;
1260			var tween = this._first,
1261				labels = this._labels,
1262				p;
1263			while (tween) {
1264				if (tween._startTime >= ignoreBeforeTime) {
1265					tween._startTime += amount;
1266				}
1267				tween = tween._next;
1268			}
1269			if (adjustLabels) {
1270				for (p in labels) {
1271					if (labels[p] >= ignoreBeforeTime) {
1272						labels[p] += amount;
1273					}
1274				}
1275			}
1276			return this._uncache(true);
1277		};
1278
1279		p._kill = function(vars, target) {
1280			if (!vars && !target) {
1281				return this._enabled(false, false);
1282			}
1283			var tweens = (!target) ? this.getChildren(true, true, false) : this.getTweensOf(target),
1284				i = tweens.length,
1285				changed = false;
1286			while (--i > -1) {
1287				if (tweens[i]._kill(vars, target)) {
1288					changed = true;
1289				}
1290			}
1291			return changed;
1292		};
1293
1294		p.clear = function(labels) {
1295			var tweens = this.getChildren(false, true, true),
1296				i = tweens.length;
1297			this._time = this._totalTime = 0;
1298			while (--i > -1) {
1299				tweens[i]._enabled(false, false);
1300			}
1301			if (labels !== false) {
1302				this._labels = {};
1303			}
1304			return this._uncache(true);
1305		};
1306
1307		p.invalidate = function() {
1308			var tween = this._first;
1309			while (tween) {
1310				tween.invalidate();
1311				tween = tween._next;
1312			}
1313			return Animation.prototype.invalidate.call(this);;
1314		};
1315
1316		p._enabled = function(enabled, ignoreTimeline) {
1317			if (enabled === this._gc) {
1318				var tween = this._first;
1319				while (tween) {
1320					tween._enabled(enabled, true);
1321					tween = tween._next;
1322				}
1323			}
1324			return SimpleTimeline.prototype._enabled.call(this, enabled, ignoreTimeline);
1325		};
1326
1327		p.totalTime = function(time, suppressEvents, uncapped) {
1328			this._forcingPlayhead = true;
1329			var val = Animation.prototype.totalTime.apply(this, arguments);
1330			this._forcingPlayhead = false;
1331			return val;
1332		};
1333
1334		p.duration = function(value) {
1335			if (!arguments.length) {
1336				if (this._dirty) {
1337					this.totalDuration(); //just triggers recalculation
1338				}
1339				return this._duration;
1340			}
1341			if (this.duration() !== 0 && value !== 0) {
1342				this.timeScale(this._duration / value);
1343			}
1344			return this;
1345		};
1346
1347		p.totalDuration = function(value) {
1348			if (!arguments.length) {
1349				if (this._dirty) {
1350					var max = 0,
1351						tween = this._last,
1352						prevStart = 999999999999,
1353						prev, end;
1354					while (tween) {
1355						prev = tween._prev; //record it here in case the tween changes position in the sequence...
1356						if (tween._dirty) {
1357							tween.totalDuration(); //could change the tween._startTime, so make sure the tween's cache is clean before analyzing it.
1358						}
1359						if (tween._startTime > prevStart && this._sortChildren && !tween._paused && !this._calculatingDuration) { //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence
1360							this._calculatingDuration = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add(), like _parseTimeOrLabel().
1361							this.add(tween, tween._startTime - tween._delay);
1362							this._calculatingDuration = 0;
1363						} else {
1364							prevStart = tween._startTime;
1365						}
1366						if (tween._startTime < 0 && !tween._paused) { //children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found.
1367							max -= tween._startTime;
1368							if (this._timeline.smoothChildTiming) {
1369								this._startTime += tween._startTime / this._timeScale;
1370								this._time -= tween._startTime;
1371								this._totalTime -= tween._startTime;
1372								this._rawPrevTime -= tween._startTime;
1373							}
1374							this.shiftChildren(-tween._startTime, false, -9999999999);
1375							prevStart = 0;
1376						}
1377						end = tween._startTime + (tween._totalDuration / tween._timeScale);
1378						if (end > max) {
1379							max = end;
1380						}
1381						tween = prev;
1382					}
1383					this._duration = this._totalDuration = max;
1384					this._dirty = false;
1385				}
1386				return this._totalDuration;
1387			}
1388			return (value && this.totalDuration()) ? this.timeScale(this._totalDuration / value) : this;
1389		};
1390
1391		p.paused = function(value) {
1392			if (!value) { //if there's a pause directly at the spot from where we're unpausing, skip it.
1393				var tween = this._first,
1394					time = this._time;
1395				while (tween) {
1396					if (tween._startTime === time && tween.data === "isPause") {
1397						tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire.
1398					}
1399					tween = tween._next;
1400				}
1401			}
1402			return Animation.prototype.paused.apply(this, arguments);
1403		};
1404
1405		p.usesFrames = function() {
1406			var tl = this._timeline;
1407			while (tl._timeline) {
1408				tl = tl._timeline;
1409			}
1410			return (tl === Animation._rootFramesTimeline);
1411		};
1412
1413		p.rawTime = function(wrapRepeats) {
1414			return (wrapRepeats && (this._paused || (this._repeat && this.time() > 0 && this.totalProgress() < 1))) ? this._totalTime % (this._duration + this._repeatDelay) : this._paused ? this._totalTime : (this._timeline.rawTime(wrapRepeats) - this._startTime) * this._timeScale;
1415		};
1416
1417		return TimelineLite;
1418
1419	}, true);
1420
1421
1422
1423
1424
1425
1426
1427
1428	
1429	
1430	
1431	
1432	
1433/*
1434 * ----------------------------------------------------------------
1435 * TimelineMax
1436 * ----------------------------------------------------------------
1437 */
1438	_gsScope._gsDefine("TimelineMax", ["TimelineLite","TweenLite","easing.Ease"], function(TimelineLite, TweenLite, Ease) {
1439
1440		var TimelineMax = function(vars) {
1441				TimelineLite.call(this, vars);
1442				this._repeat = this.vars.repeat || 0;
1443				this._repeatDelay = this.vars.repeatDelay || 0;
1444				this._cycle = 0;
1445				this._yoyo = (this.vars.yoyo === true);
1446				this._dirty = true;
1447			},
1448			_tinyNum = 0.0000000001,
1449			TweenLiteInternals = TweenLite._internals,
1450			_lazyTweens = TweenLiteInternals.lazyTweens,
1451			_lazyRender = TweenLiteInternals.lazyRender,
1452			_globals = _gsScope._gsDefine.globals,
1453			_easeNone = new Ease(null, null, 1, 0),
1454			p = TimelineMax.prototype = new TimelineLite();
1455
1456		p.constructor = TimelineMax;
1457		p.kill()._gc = false;
1458		TimelineMax.version = "2.0.2";
1459
1460		p.invalidate = function() {
1461			this._yoyo = (this.vars.yoyo === true);
1462			this._repeat = this.vars.repeat || 0;
1463			this._repeatDelay = this.vars.repeatDelay || 0;
1464			this._uncache(true);
1465			return TimelineLite.prototype.invalidate.call(this);
1466		};
1467
1468		p.addCallback = function(callback, position, params, scope) {
1469			return this.add( TweenLite.delayedCall(0, callback, params, scope), position);
1470		};
1471
1472		p.removeCallback = function(callback, position) {
1473			if (callback) {
1474				if (position == null) {
1475					this._kill(null, callback);
1476				} else {
1477					var a = this.getTweensOf(callback, false),
1478						i = a.length,
1479						time = this._parseTimeOrLabel(position);
1480					while (--i > -1) {
1481						if (a[i]._startTime === time) {
1482							a[i]._enabled(false, false);
1483						}
1484					}
1485				}
1486			}
1487			return this;
1488		};
1489
1490		p.removePause = function(position) {
1491			return this.removeCallback(TimelineLite._internals.pauseCallback, position);
1492		};
1493
1494		p.tweenTo = function(position, vars) {
1495			vars = vars || {};
1496			var copy = {ease:_easeNone, useFrames:this.usesFrames(), immediateRender:false, lazy:false},
1497				Engine = (vars.repeat && _globals.TweenMax) || TweenLite,
1498				duration, p, t;
1499			for (p in vars) {
1500				copy[p] = vars[p];
1501			}
1502			copy.time = this._parseTimeOrLabel(position);
1503			duration = (Math.abs(Number(copy.time) - this._time) / this._timeScale) || 0.001;
1504			t = new Engine(this, duration, copy);
1505			copy.onStart = function() {
1506				t.target.paused(true);
1507				if (t.vars.time !== t.target.time() && duration === t.duration() && !t.isFromTo) { //don't make the duration zero - if it's supposed to be zero, don't worry because it's already initting the tween and will complete immediately, effectively making the duration zero anyway. If we make duration zero, the tween won't run at all.
1508					t.duration( Math.abs( t.vars.time - t.target.time()) / t.target._timeScale ).render(t.time(), true, true); //render() right away to ensure that things look right, especially in the case of .tweenTo(0).
1509				}
1510				if (vars.onStart) { //in case the user had an onStart in the vars - we don't want to overwrite it.
1511					vars.onStart.apply(vars.onStartScope || vars.callbackScope || t, vars.onStartParams || []); //don't use t._callback("onStart") or it'll point to the copy.onStart and we'll get a recursion error.
1512				}
1513			};
1514			return t;
1515		};
1516
1517		p.tweenFromTo = function(fromPosition, toPosition, vars) {
1518			vars = vars || {};
1519			fromPosition = this._parseTimeOrLabel(fromPosition);
1520			vars.startAt = {onComplete:this.seek, onCompleteParams:[fromPosition], callbackScope:this};
1521			vars.immediateRender = (vars.immediateRender !== false);
1522			var t = this.tweenTo(toPosition, vars);
1523			t.isFromTo = 1; //to ensure we don't mess with the duration in the onStart (we've got the start and end values here, so lock it in)
1524			return t.duration((Math.abs( t.vars.time - fromPosition) / this._timeScale) || 0.001);
1525		};
1526
1527		p.render = function(time, suppressEvents, force) {
1528			if (this._gc) {
1529				this._enabled(true, false);
1530			}
1531			var prevTime = this._time,
1532				totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(),
1533				dur = this._duration,
1534				prevTotalTime = this._totalTime,
1535				prevStart = this._startTime,
1536				prevTimeScale = this._timeScale,
1537				prevRawPrevTime = this._rawPrevTime,
1538				prevPaused = this._paused,
1539				prevCycle = this._cycle,
1540				tween, isComplete, next, callback, internalForce, cycleDuration, pauseTween, curTime;
1541			if (prevTime !== this._time) { //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump).
1542				time += this._time - prevTime;
1543			}
1544			if (time >= totalDur - 0.0000001 && time >= 0) { //to work around occasional floating point math artifacts.
1545				if (!this._locked) {
1546					this._totalTime = totalDur;
1547					this._cycle = this._repeat;
1548				}
1549				if (!this._reversed) if (!this._hasPausedChild()) {
1550					isComplete = true;
1551					callback = "onComplete";
1552					internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
1553					if (this._duration === 0) if ((time <= 0 && time >= -0.0000001) || prevRawPrevTime < 0 || prevRawPrevTime === _tinyNum) if (prevRawPrevTime !== time && this._first) {
1554						internalForce = true;
1555						if (prevRawPrevTime > _tinyNum) {
1556							callback = "onReverseComplete";
1557						}
1558					}
1559				}
1560				this._rawPrevTime = (this._duration || !suppressEvents || time || this._rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
1561				if (this._yoyo && (this._cycle & 1) !== 0) {
1562					this._time = time = 0;
1563				} else {
1564					this._time = dur;
1565					time = dur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7. We cannot do less then 0.0001 because the same issue can occur when the duration is extremely large like 999999999999 in 
1565which case adding 0.00000001, for example, causes it to act like nothing was added.
1566				}
1567
1568			} else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0.
1569				if (!this._locked) {
1570					this._totalTime = this._cycle = 0;
1571				}
1572				this._time = 0;
1573				if (prevTime !== 0 || (dur === 0 && prevRawPrevTime !== _tinyNum && (prevRawPrevTime > 0 || (time < 0 && prevRawPrevTime >= 0)) && !this._locked)) { //edge case for checking time < 0 && prevRawPrevTime >= 0: a zero-duration fromTo() tween inside a zero-duration timeline (yeah, very rare)
1574					callback = "onReverseComplete";
1575					isComplete = this._reversed;
1576				}
1577				if (time < 0) {
1578					this._active = false;
1579					if (this._timeline.autoRemoveChildren && this._reversed) {
1580						internalForce = isComplete = true;
1581						callback = "onReverseComplete";
1582					} else if (prevRawPrevTime >= 0 && this._first) { //when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state.
1583						internalForce = true;
1584					}
1585					this._rawPrevTime = time;
1586				} else {
1587					this._rawPrevTime = (dur || !suppressEvents || time || this._rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
1588					if (time === 0 && isComplete) { //if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good).
1589						tween = this._first;
1590						while (tween && tween._startTime === 0) {
1591							if (!tween._duration) {
1592								isComplete = false;
1593							}
1594							tween = tween._next;
1595						}
1596					}
1597					time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
1598					if (!this._initted) {
1599						internalForce = true;
1600					}
1601				}
1602
1603			} else {
1604				if (dur === 0 && prevRawPrevTime < 0) { //without this, zero-duration repeating timelines (like with a simple callback nested at the very beginning and a repeatDelay) wouldn't render the first time through.
1605					internalForce = true;
1606				}
1607				this._time = this._rawPrevTime = time;
1608				if (!this._locked) {
1609					this._totalTime = time;
1610					if (this._repeat !== 0) {
1611						cycleDuration = dur + this._repeatDelay;
1612						this._cycle = (this._totalTime / cycleDuration) >> 0; //originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but it gets reported as 0.79999999!)
1613						if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) {
1614							this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning)
1615						}
1616						this._time = this._totalTime - (this._cycle * cycleDuration);
1617						if (this._yoyo) if ((this._cycle & 1) !== 0) {
1618							this._time = dur - this._time;
1619						}
1620						if (this._time > dur) {
1621							this._time = dur;
1622							time = dur + 0.0001; //to avoid occasional floating point rounding error
1623						} else if (this._time < 0) {
1624							this._time = time = 0;
1625						} else {
1626							time = this._time;
1627						}
1628					}
1629				}
1630
1631				if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
1632					time = this._time;
1633					if (time >= prevTime || (this._repeat && prevCycle !== this._cycle)) {
1634						tween = this._first;
1635						while (tween && tween._startTime <= time && !pauseTween) {
1636							if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
1637								pauseTween = tween;
1638							}
1639							tween = tween._next;
1640						}
1641					} else {
1642						tween = this._last;
1643						while (tween && tween._startTime >= time && !pauseTween) {
1644							if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) {
1645								pauseTween = tween;
1646							}
1647							tween = tween._prev;
1648						}
1649					}
1650					if (pauseTween && pauseTween._startTime < dur) {
1651						this._time = time = pauseTween._startTime;
1652						this._totalTime = time + (this._cycle * (this._totalDuration + this._repeatDelay));
1653					}
1654				}
1655
1656			}
1657
1658			if (this._cycle !== prevCycle) if (!this._locked) {
1659				/*
1660				make sure children at the end/beginning of the timeline are rendered properly. If, for example,
1661				a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which
1662				would get transated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there
1663				could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So
1664				we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must
1665				ensure that zero-duration tweens at the very beginning or end of the TimelineMax work.
1666				*/
1667				var backwards = (this._yoyo && (prevCycle & 1) !== 0),
1668					wrap = (backwards === (this._yoyo && (this._cycle & 1) !== 0)),
1669					recTotalTime = this._totalTime,
1670					recCycle = this._cycle,
1671					recRawPrevTime = this._rawPrevTime,
1672					recTime = this._time;
1673
1674				this._totalTime = prevCycle * dur;
1675				if (this._cycle < prevCycle) {
1676					backwards = !backwards;
1677				} else {
1678					this._totalTime += dur;
1679				}
1680				this._time = prevTime; //temporarily revert _time so that render() renders the children in the correct order. Without this, tweens won't rewind correctly. We could arhictect things in a "cleaner" way by splitting out the rendering queue into a separate method but for performance reasons, we kept it all inside this method.
1681
1682				this._rawPrevTime = (dur === 0) ? prevRawPrevTime - 0.0001 : prevRawPrevTime;
1683				this._cycle = prevCycle;
1684				this._locked = true; //prevents changes to totalTime and skips repeat/yoyo behavior when we recursively call render()
1685				prevTime = (backwards) ? 0 : dur;
1686				this.render(prevTime, suppressEvents, (dur === 0));
1687				if (!suppressEvents) if (!this._gc) {
1688					if (this.vars.onRepeat) {
1689						this._cycle = recCycle; //in case the onRepeat alters the playhead or invalidates(), we shouldn't stay locked or use the previous cycle.
1690						this._locked = false;
1691						this._callback("onRepeat");
1692					}
1693				}
1694				if (prevTime !== this._time) { //in case there's a callback like onComplete in a nested tween/timeline that changes the playhead position, like via seek(), we should just abort.
1695					return;
1696				}
1697				if (wrap) {
1698					this._cycle = prevCycle; //if there's an onRepeat, we reverted this above, so make sure it's set properly again. We also unlocked in that scenario, so reset that too.
1699					this._locked = true;
1700					prevTime = (backwards) ? dur + 0.0001 : -0.0001;
1701					this.render(prevTime, true, false);
1702				}
1703				this._locked = false;
1704				if (this._paused && !prevPaused) { //if the render() triggered callback that paused this timeline, we should abort (very rare, but possible)
1705					return;
1706				}
1707				this._time = recTime;
1708				this._totalTime = recTotalTime;
1709				this._cycle = recCycle;
1710				this._rawPrevTime = recRawPrevTime;
1711			}
1712
1713			if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
1714				if (prevTotalTime !== this._totalTime) if (this._onUpdate) if (!suppressEvents) { //so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate.
1715					this._callback("onUpdate");
1716				}
1717				return;
1718			} else if (!this._initted) {
1719				this._initted = true;
1720			}
1721
1722			if (!this._active) if (!this._paused && this._totalTime !== prevTotalTime && time > 0) {
1723				this._active = true;  //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example.
1724			}
1725
1726			if (prevTotalTime === 0) if (this.vars.onStart) if (this._totalTime !== 0 || !this._totalDuration) if (!suppressEvents) {
1727				this._callback("onStart");
1728			}
1729
1730			curTime = this._time;
1731			if (curTime >= prevTime) {
1732				tween = this._first;
1733				while (tween) {
1734					next = tween._next; //record it here because the value could change after rendering...
1735					if (curTime !== this._time || (this._paused && !prevPaused)) { //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
1736						break;
1737					} else if (tween._active || (tween._startTime <= this._time && !tween._paused && !tween._gc)) {
1738						if (pauseTween === tween) {
1739							this.pause();
1740						}
1741						if (!tween._reversed) {
1742							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
1743						} else {
1744							tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force);
1745						}
1746					}
1747					tween = next;
1748				}
1749			} else {
1750				tween = this._last;
1751				while (tween) {
1752					next = tween._prev; //record it here because the value could change after rendering...
1753					if (curTime !== this._time || (this._paused && !prevPaused)) { //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
1754						break;
1755					} else if (tween._active || (tween._startTime <= prevTime && !tween._paused && !tween._gc)) {
1756						if (pauseTween === tween) {
1757							pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse.
1758							while (pauseTween && pauseTween.endTime() > this._time) {
1759								pauseTween.render( (pauseTween._reversed ? pauseTween.totalDuration() - ((time - pauseTween._startTime) * pauseTween._timeScale) : (time - pauseTween._startTime) * pauseTween._timeScale), suppressEvents, force);
1760								pauseTween = pauseTween._prev;
1761							}
1762							pauseTween = null;
1763							this.pause();
1764						}
1765						if (!tween._reversed) {
1766							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
1767						} else {
1768							tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force);
1769						}
1770					}
1771					tween = next;
1772				}
1773			}
1774
1775			if (this._onUpdate) if (!suppressEvents) {
1776				if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.
1777					_lazyRender();
1778				}
1779				this._callback("onUpdate");
1780			}
1781			if (callback) if (!this._locked) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) { //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate
1782				if (isComplete) {
1783					if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values.
1784						_lazyRender();
1785					}
1786					if (this._timeline.autoRemoveChildren) {
1787						this._enabled(false, false);
1788					}
1789					this._active = false;
1790				}
1791				if (!suppressEvents && this.vars[callback]) {
1792					this._callback(callback);
1793				}
1794			}
1795		};
1796
1797		p.getActive = function(nested, tweens, timelines) {
1798			if (nested == null) {
1799				nested = true;
1800			}
1801			if (tweens == null) {
1802				tweens = true;
1803			}
1804			if (timelines == null) {
1805				timelines = false;
1806			}
1807			var a = [],
1808				all = this.getChildren(nested, tweens, timelines),
1809				cnt = 0,
1810				l = all.length,
1811				i, tween;
1812			for (i = 0; i < l; i++) {
1813				tween = all[i];
1814				if (tween.isActive()) {
1815					a[cnt++] = tween;
1816				}
1817			}
1818			return a;
1819		};
1820
1821
1822		p.getLabelAfter = function(time) {
1823			if (!time) if (time !== 0) { //faster than isNan()
1824				time = this._time;
1825			}
1826			var labels = this.getLabelsArray(),
1827				l = labels.length,
1828				i;
1829			for (i = 0; i < l; i++) {
1830				if (labels[i].time > time) {
1831					return labels[i].name;
1832				}
1833			}
1834			return null;
1835		};
1836
1837		p.getLabelBefore = function(time) {
1838			if (time == null) {
1839				time = this._time;
1840			}
1841			var labels = this.getLabelsArray(),
1842				i = labels.length;
1843			while (--i > -1) {
1844				if (labels[i].time < time) {
1845					return labels[i].name;
1846				}
1847			}
1848			return null;
1849		};
1850
1851		p.getLabelsArray = function() {
1852			var a = [],
1853				cnt = 0,
1854				p;
1855			for (p in this._labels) {
1856				a[cnt++] = {time:this._labels[p], name:p};
1857			}
1858			a.sort(function(a,b) {
1859				return a.time - b.time;
1860			});
1861			return a;
1862		};
1863
1864		p.invalidate = function() {
1865			this._locked = false; //unlock and set cycle in case invalidate() is called from inside an onRepeat
1866			return TimelineLite.prototype.invalidate.call(this);
1867		};
1868
1869
1870//---- GETTERS / SETTERS -------------------------------------------------------------------------------------------------------
1871
1872		p.progress = function(value, suppressEvents) {
1873			return (!arguments.length) ? (this._time / this.duration()) || 0 : this.totalTime( this.duration() * ((this._yoyo && (this._cycle & 1) !== 0) ? 1 - value : value) + (this._cycle * (this._duration + this._repeatDelay)), suppressEvents);
1874		};
1875
1876		p.totalProgress = function(value, suppressEvents) {
1877			return (!arguments.length) ? (this._totalTime / this.totalDuration()) || 0 : this.totalTime( this.totalDuration() * value, suppressEvents);
1878		};
1879
1880		p.totalDuration = function(value) {
1881			if (!arguments.length) {
1882				if (this._dirty) {
1883					TimelineLite.prototype.totalDuration.call(this); //just forces refresh
1884					//Instead of Infinity, we use 999999999999 so that we can accommodate reverses.
1885					this._totalDuration = (this._repeat === -1) ? 999999999999 : this._duration * (this._repeat + 1) + (this._repeatDelay * this._repeat);
1886				}
1887				return this._totalDuration;
1888			}
1889			return (this._repeat === -1 || !value) ? this : this.timeScale( this.totalDuration() / value );
1890		};
1891
1892		p.time = function(value, suppressEvents) {
1893			if (!arguments.length) {
1894				return this._time;
1895			}
1896			if (this._dirty) {
1897				this.totalDuration();
1898			}
1899			if (value > this._duration) {
1900				value = this._duration;
1901			}
1902			if (this._yoyo && (this._cycle & 1) !== 0) {
1903				value = (this._duration - value) + (this._cycle * (this._duration + this._repeatDelay));
1904			} else if (this._repeat !== 0) {
1905				value += this._cycle * (this._duration + this._repeatDelay);
1906			}
1907			return this.totalTime(value, suppressEvents);
1908		};
1909
1910		p.repeat = function(value) {
1911			if (!arguments.length) {
1912				return this._repeat;
1913			}
1914			this._repeat = value;
1915			return this._uncache(true);
1916		};
1917
1918		p.repeatDelay = function(value) {
1919			if (!arguments.length) {
1920				return this._repeatDelay;
1921			}
1922			this._repeatDelay = value;
1923			return this._uncache(true);
1924		};
1925
1926		p.yoyo = function(value) {
1927			if (!arguments.length) {
1928				return this._yoyo;
1929			}
1930			this._yoyo = value;
1931			return this;
1932		};
1933
1934		p.currentLabel = function(value) {
1935			if (!arguments.length) {
1936				return this.getLabelBefore(this._time + 0.00000001);
1937			}
1938			return this.seek(value, true);
1939		};
1940
1941		return TimelineMax;
1942
1943	}, true);
1944	
1945
1946
1947
1948
1949	
1950	
1951	
1952	
1953	
1954
1955	
1956/*
1957 * ----------------------------------------------------------------
1958 * BezierPlugin
1959 * ----------------------------------------------------------------
1960 */
1961	(function() {
1962
1963		var _RAD2DEG = 180 / Math.PI,
1964			_r1 = [],
1965			_r2 = [],
1966			_r3 = [],
1967			_corProps = {},
1968			_globals = _gsScope._gsDefine.globals,
1969			Segment = function(a, b, c, d) {
1970				if (c === d) { //if c and d match, the final autoRotate value could lock at -90 degrees, so differentiate them slightly.
1971					c = d - (d - b) / 1000000;
1972				}
1973				if (a === b) { //if a and b match, the starting autoRotate value could lock at -90 degrees, so differentiate them slightly.
1974					b = a + (c - a) / 1000000;
1975				}
1976				this.a = a;
1977				this.b = b;
1978				this.c = c;
1979				this.d = d;
1980				this.da = d - a;
1981				this.ca = c - a;
1982				this.ba = b - a;
1983			},
1984			_correlate = ",x,y,z,left,top,right,bottom,marginTop,marginLeft,marginRight,marginBottom,paddingLeft,paddingTop,paddingRight,paddingBottom,backgroundPosition,backgroundPosition_y,",
1985			cubicToQuadratic = function(a, b, c, d) {
1986				var q1 = {a:a},
1987					q2 = {},
1988					q3 = {},
1989					q4 = {c:d},
1990					mab = (a + b) / 2,
1991					mbc = (b + c) / 2,
1992					mcd = (c + d) / 2,
1993					mabc = (mab + mbc) / 2,
1994					mbcd = (mbc + mcd) / 2,
1995					m8 = (mbcd - mabc) / 8;
1996				q1.b = mab + (a - mab) / 4;
1997				q2.b = mabc + m8;
1998				q1.c = q2.a = (q1.b + q2.b) / 2;
1999				q2.c = q3.a = (mabc + mbcd) / 2;
2000				q3.b = mbcd - m8;
2001				q4.b = mcd + (d - mcd) / 4;
2002				q3.c = q4.a = (q3.b + q4.b) / 2;
2003				return [q1, q2, q3, q4];
2004			},
2005			_calculateControlPoints = function(a, curviness, quad, basic, correlate) {
2006				var l = a.length - 1,
2007					ii = 0,
2008					cp1 = a[0].a,
2009					i, p1, p2, p3, seg, m1, m2, mm, cp2, qb, r1, r2, tl;
2010				for (i = 0; i < l; i++) {
2011					seg = a[ii];
2012					p1 = seg.a;
2013					p2 = seg.d;
2014					p3 = a[ii+1].d;
2015
2016					if (correlate) {
2017						r1 = _r1[i];
2018						r2 = _r2[i];
2019						tl = ((r2 + r1) * curviness * 0.25) / (basic ? 0.5 : _r3[i] || 0.5);
2020						m1 = p2 - (p2 - p1) * (basic ? curviness * 0.5 : (r1 !== 0 ? tl / r1 : 0));
2021						m2 = p2 + (p3 - p2) * (basic ? curviness * 0.5 : (r2 !== 0 ? tl / r2 : 0));
2022						mm = p2 - (m1 + (((m2 - m1) * ((r1 * 3 / (r1 + r2)) + 0.5) / 4) || 0));
2023					} else {
2024						m1 = p2 - (p2 - p1) * curviness * 0.5;
2025						m2 = p2 + (p3 - p2) * curviness * 0.5;
2026						mm = p2 - (m1 + m2) / 2;
2027					}
2028					m1 += mm;
2029					m2 += mm;
2030
2031					seg.c = cp2 = m1;
2032					if (i !== 0) {
2033						seg.b = cp1;
2034					} else {
2035						seg.b = cp1 = seg.a + (seg.c - seg.a) * 0.6; //instead of placing b on a exactly, we move it inline with c so that if the user specifies an ease like Back.easeIn or Elastic.easeIn which goes BEYOND the beginning, it will do so smoothly.
2036					}
2037
2038					seg.da = p2 - p1;
2039					seg.ca = cp2 - p1;
2040					seg.ba = cp1 - p1;
2041
2042					if (quad) {
2043						qb = cubicToQuadratic(p1, cp1, cp2, p2);
2044						a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]);
2045						ii += 4;
2046					} else {
2047						ii++;
2048					}
2049
2050					cp1 = m2;
2051				}
2052				seg = a[ii];
2053				seg.b = cp1;
2054				seg.c = cp1 + (seg.d - cp1) * 0.4; //instead of placing c on d exactly, we move it inline with b so that if the user specifies an ease like Back.easeOut or Elastic.easeOut which goes BEYOND the end, it will do so smoothly.
2055				seg.da = seg.d - seg.a;
2056				seg.ca = seg.c - seg.a;
2057				seg.ba = cp1 - seg.a;
2058				if (quad) {
2059					qb = cubicToQuadratic(seg.a, cp1, seg.c, seg.d);
2060					a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]);
2061				}
2062			},
2063			_parseAnchors = function(values, p, correlate, prepend) {
2064				var a = [],
2065					l, i, p1, p2, p3, tmp;
2066				if (prepend) {
2067					values = [prepend].concat(values);
2068					i = values.length;
2069					while (--i > -1) {
2070						if (typeof( (tmp = values[i][p]) ) === "string") if (tmp.charAt(1) === "=") {
2071							values[i][p] = prepend[p] + Number(tmp.charAt(0) + tmp.substr(2)); //accommodate relative values. Do it inline instead of breaking it out into a function for speed reasons
2072						}
2073					}
2074				}
2075				l = values.length - 2;
2076				if (l < 0) {
2077					a[0] = new Segment(values[0][p], 0, 0, values[0][p]);
2078					return a;
2079				}
2080				for (i = 0; i < l; i++) {
2081					p1 = values[i][p];
2082					p2 = values[i+1][p];
2083					a[i] = new Segment(p1, 0, 0, p2);
2084					if (correlate) {
2085						p3 = values[i+2][p];
2086						_r1[i] = (_r1[i] || 0) + (p2 - p1) * (p2 - p1);
2087						_r2[i] = (_r2[i] || 0) + (p3 - p2) * (p3 - p2);
2088					}
2089				}
2090				a[i] = new Segment(values[i][p], 0, 0, values[i+1][p]);
2091				return a;
2092			},
2093			bezierThrough = function(values, curviness, quadratic, basic, correlate, prepend) {
2094				var obj = {},
2095					props = [],
2096					first = prepend || values[0],
2097					i, p, a, j, r, l, seamless, last;
2098				correlate = (typeof(correlate) === "string") ? ","+correlate+"," : _correlate;
2099				if (curviness == null) {
2100					curviness = 1;
2101				}
2102				for (p in values[0]) {
2103					props.push(p);
2104				}
2105				//check to see if the last and first values are identical (well, within 0.05). If so, make seamless by appending the second element to the very end of the values array and the 2nd-to-last element to the very beginning (we'll remove those segments later)
2106				if (values.length > 1) {
2107					last = values[values.length - 1];
2108					seamless = true;
2109					i = props.length;
2110					while (--i > -1) {
2111						p = props[i];
2112						if (Math.abs(first[p] - last[p]) > 0.05) { //build in a tolerance of +/-0.05 to accommodate rounding errors.
2113							seamless = false;
2114							break;
2115						}
2116					}
2117					if (seamless) {
2118						values = values.concat(); //duplicate the array to avoid contaminating the original which the user may be reusing for other tweens
2119						if (prepend) {
2120							values.unshift(prepend);
2121						}
2122						values.push(values[1]);
2123						prepend = values[values.length - 3];
2124					}
2125				}
2126				_r1.length = _r2.length = _r3.length = 0;
2127				i = props.length;
2128				while (--i > -1) {
2129					p = props[i];
2130					_corProps[p] = (correlate.indexOf(","+p+",") !== -1);
2131					obj[p] = _parseAnchors(values, p, _corProps[p], prepend);
2132				}
2133				i = _r1.length;
2134				while (--i > -1) {
2135					_r1[i] = Math.sqrt(_r1[i]);
2136					_r2[i] = Math.sqrt(_r2[i]);
2137				}
2138				if (!basic) {
2139					i = props.length;
2140					while (--i > -1) {
2141						if (_corProps[p]) {
2142							a = obj[props[i]];
2143							l = a.length - 1;
2144							for (j = 0; j < l; j++) {
2145								r = (a[j+1].da / _r2[j] + a[j].da / _r1[j]) || 0;
2146								_r3[j] = (_r3[j] || 0) + r * r;
2147							}
2148						}
2149					}
2150					i = _r3.length;
2151					while (--i > -1) {
2152						_r3[i] = Math.sqrt(_r3[i]);
2153					}
2154				}
2155				i = props.length;
2156				j = quadratic ? 4 : 1;
2157				while (--i > -1) {
2158					p = props[i];
2159					a = obj[p];
2160					_calculateControlPoints(a, curviness, quadratic, basic, _corProps[p]); //this method requires that _parseAnchors() and _setSegmentRatios() ran first so that _r1, _r2, and _r3 values are populated for all properties
2161					if (seamless) {
2162						a.splice(0, j);
2163						a.splice(a.length - j, j);
2164					}
2165				}
2166				return obj;
2167			},
2168			_parseBezierData = function(values, type, prepend) {
2169				type = type || "soft";
2170				var obj = {},
2171					inc = (type === "cubic") ? 3 : 2,
2172					soft = (type === "soft"),
2173					props = [],
2174					a, b, c, d, cur, i, j, l, p, cnt, tmp;
2175				if (soft && prepend) {
2176					values = [prepend].concat(values);
2177				}
2178				if (values == null || values.length < inc + 1) { throw "invalid Bezier data"; }
2179				for (p in values[0]) {
2180					props.push(p);
2181				}
2182				i = props.length;
2183				while (--i > -1) {
2184					p = props[i];
2185					obj[p] = cur = [];
2186					cnt = 0;
2187					l = values.length;
2188					for (j = 0; j < l; j++) {
2189						a = (prepend == null) ? values[j][p] : (typeof( (tmp = values[j][p]) ) === "string" && tmp.charAt(1) === "=") ? prepend[p] + Number(tmp.charAt(0) + tmp.substr(2)) : Number(tmp);
2190						if (soft) if (j > 1) if (j < l - 1) {
2191							cur[cnt++] = (a + cur[cnt-2]) / 2;
2192						}
2193						cur[cnt++] = a;
2194					}
2195					l = cnt - inc + 1;
2196					cnt = 0;
2197					for (j = 0; j < l; j += inc) {
2198						a = cur[j];
2199						b = cur[j+1];
2200						c = cur[j+2];
2201						d = (inc === 2) ? 0 : cur[j+3];
2202						cur[cnt++] = tmp = (inc === 3) ? new Segment(a, b, c, d) : new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c);
2203					}
2204					cur.length = cnt;
2205				}
2206				return obj;
2207			},
2208			_addCubicLengths = function(a, steps, resolution) {
2209				var inc = 1 / resolution,
2210					j = a.length,
2211					d, d1, s, da, ca, ba, p, i, inv, bez, index;
2212				while (--j > -1) {
2213					bez = a[j];
2214					s = bez.a;
2215					da = bez.d - s;
2216					ca = bez.c - s;
2217					ba = bez.b - s;
2218					d = d1 = 0;
2219					for (i = 1; i <= resolution; i++) {
2220						p = inc * i;
2221						inv = 1 - p;
2222						d = d1 - (d1 = (p * p * da + 3 * inv * (p * ca + inv * ba)) * p);
2223						index = j * resolution + i - 1;
2224						steps[index] = (steps[index] || 0) + d * d;
2225					}
2226				}
2227			},
2228			_parseLengthData = function(obj, resolution) {
2229				resolution = resolution >> 0 || 6;
2230				var a = [],
2231					lengths = [],
2232					d = 0,
2233					total = 0,
2234					threshold = resolution - 1,
2235					segments = [],
2236					curLS = [], //current length segments array
2237					p, i, l, index;
2238				for (p in obj) {
2239					_addCubicLengths(obj[p], a, resolution);
2240				}
2241				l = a.length;
2242				for (i = 0; i < l; i++) {
2243					d += Math.sqrt(a[i]);
2244					index = i % resolution;
2245					curLS[index] = d;
2246					if (index === threshold) {
2247						total += d;
2248						index = (i / resolution) >> 0;
2249						segments[index] = curLS;
2250						lengths[index] = total;
2251						d = 0;
2252						curLS = [];
2253					}
2254				}
2255				return {length:total, lengths:lengths, segments:segments};
2256			},
2257
2258
2259
2260			BezierPlugin = _gsScope._gsDefine.plugin({
2261					propName: "bezier",
2262					priority: -1,
2263					version: "1.3.8",
2264					API: 2,
2265					global:true,
2266
2267					//gets called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
2268					init: function(target, vars, tween) {
2269						this._target = target;
2270						if (vars instanceof Array) {
2271							vars = {values:vars};
2272						}
2273						this._func = {};
2274						this._mod = {};
2275						this._props = [];
2276						this._timeRes = (vars.timeResolution == null) ? 6 : parseInt(vars.timeResolution, 10);
2277						var values = vars.values || [],
2278							first = {},
2279							second = values[0],
2280							autoRotate = vars.autoRotate || tween.vars.orientToBezier,
2281							p, isFunc, i, j, prepend;
2282
2283						this._autoRotate = autoRotate ? (autoRotate instanceof Array) ? autoRotate : [["x","y","rotation",((autoRotate === true) ? 0 : Number(autoRotate) || 0)]] : null;
2284						for (p in second) {
2285							this._props.push(p);
2286						}
2287
2288						i = this._props.length;
2289						while (--i > -1) {
2290							p = this._props[i];
2291
2292							this._overwriteProps.push(p);
2293							isFunc = this._func[p] = (typeof(target[p]) === "function");
2294							first[p] = (!isFunc) ? parseFloat(target[p]) : target[ ((p.indexOf("set") || typeof(target["get" + p.substr(3)]) !== "function") ? p : "get" + p.substr(3)) ]();
2295							if (!prepend) if (first[p] !== values[0][p]) {
2296								prepend = first;
2297							}
2298						}
2299						this._beziers = (vars.type !== "cubic" && vars.type !== "quadratic" && vars.type !== "soft") ? bezierThrough(values, isNaN(vars.curviness) ? 1 : vars.curviness, false, (vars.type === "thruBasic"), vars.correlate, prepend) : _parseBezierData(values, vars.type, first);
2300						this._segCount = this._beziers[p].length;
2301
2302						if (this._timeRes) {
2303							var ld = _parseLengthData(this._beziers, this._timeRes);
2304							this._length = ld.length;
2305							this._lengths = ld.lengths;
2306							this._segments = ld.segments;
2307							this._l1 = this._li = this._s1 = this._si = 0;
2308							this._l2 = this._lengths[0];
2309							this._curSeg = this._segments[0];
2310							this._s2 = this._curSeg[0];
2311							this._prec = 1 / this._curSeg.length;
2312						}
2313
2314						if ((autoRotate = this._autoRotate)) {
2315							this._initialRotations = [];
2316							if (!(autoRotate[0] instanceof Array)) {
2317								this._autoRotate = autoRotate = [autoRotate];
2318							}
2319							i = autoRotate.length;
2320							while (--i > -1) {
2321								for (j = 0; j < 3; j++) {
2322									p = autoRotate[i][j];
2323									this._func[p] = (typeof(target[p]) === "function") ? target[ ((p.indexOf("set") || typeof(target["get" + p.substr(3)]) !== "function") ? p : "get" + p.substr(3)) ] : false;
2324								}
2325								p = autoRotate[i][2];
2326								this._initialRotations[i] = (this._func[p] ? this._func[p].call(this._target) : this._target[p]) || 0;
2327								this._overwriteProps.push(p);
2328							}
2329						}
2330						this._startRatio = tween.vars.runBackwards ? 1 : 0; //we determine the starting ratio when the tween inits which is always 0 unless the tween has runBackwards:true (indicating it's a from() tween) in which case it's 1.
2331						return true;
2332					},
2333
2334					//called each time the values should be updated, and the ratio gets passed as the only parameter (typically it's a value between 0 and 1, but it can exceed those when using an ease like Elastic.easeOut or Back.easeOut, etc.)
2335					set: function(v) {
2336						var segments = this._segCount,
2337							func = this._func,
2338							target = this._target,
2339							notStart = (v !== this._startRatio),
2340							curIndex, inv, i, p, b, t, val, l, lengths, curSeg;
2341						if (!this._timeRes) {
2342							curIndex = (v < 0) ? 0 : (v >= 1) ? segments - 1 : (segments * v) >> 0;
2343							t = (v - (curIndex * (1 / segments))) * segments;
2344						} else {
2345							lengths = this._lengths;
2346							curSeg = this._curSeg;
2347							v *= this._length;
2348							i = this._li;
2349							//find the appropriate segment (if the currently cached one isn't correct)
2350							if (v > this._l2 && i < segments - 1) {
2351								l = segments - 1;
2352								while (i < l && (this._l2 = lengths[++i]) <= v) {	}
2353								this._l1 = lengths[i-1];
2354								this._li = i;
2355								this._curSeg = curSeg = this._segments[i];
2356								this._s2 = curSeg[(this._s1 = this._si = 0)];
2357							} else if (v < this._l1 && i > 0) {
2358								while (i > 0 && (this._l1 = lengths[--i]) >= v) { }
2359								if (i === 0 && v < this._l1) {
2360									this._l1 = 0;
2361								} else {
2362									i++;
2363								}
2364								this._l2 = lengths[i];
2365								this._li = i;
2366								this._curSeg = curSeg = this._segments[i];
2367								this._s1 = curSeg[(this._si = curSeg.length - 1) - 1] || 0;
2368								this._s2 = curSeg[this._si];
2369							}
2370							curIndex = i;
2371							//now find the appropriate sub-segment (we split it into the number of pieces that was defined by "precision" and measured each one)
2372							v -= this._l1;
2373							i = this._si;
2374							if (v > this._s2 && i < curSeg.length - 1) {
2375								l = curSeg.length - 1;
2376								while (i < l && (this._s2 = curSeg[++i]) <= v) {	}
2377								this._s1 = curSeg[i-1];
2378								this._si = i;
2379							} else if (v < this._s1 && i > 0) {
2380								while (i > 0 && (this._s1 = curSeg[--i]) >= v) {	}
2381								if (i === 0 && v < this._s1) {
2382									this._s1 = 0;
2383								} else {
2384									i++;
2385								}
2386								this._s2 = curSeg[i];
2387								this._si = i;
2388							}
2389							t = ((i + (v - this._s1) / (this._s2 - this._s1)) * this._prec) || 0;
2390						}
2391						inv = 1 - t;
2392
2393						i = this._props.length;
2394						while (--i > -1) {
2395							p = this._props[i];
2396							b = this._beziers[p][curIndex];
2397							val = (t * t * b.da + 3 * inv * (t * b.ca + inv * b.ba)) * t + b.a;
2398							if (this._mod[p]) {
2399								val = this._mod[p](val, target);
2400							}
2401							if (func[p]) {
2402								target[p](val);
2403							} else {
2404								target[p] = val;
2405							}
2406						}
2407
2408						if (this._autoRotate) {
2409							var ar = this._autoRotate,
2410								b2, x1, y1, x2, y2, add, conv;
2411							i = ar.length;
2412							while (--i > -1) {
2413								p = ar[i][2];
2414								add = ar[i][3] || 0;
2415								conv = (ar[i][4] === true) ? 1 : _RAD2DEG;
2416								b = this._beziers[ar[i][0]];
2417								b2 = this._beziers[ar[i][1]];
2418
2419								if (b && b2) { //in case one of the properties got overwritten.
2420									b = b[curIndex];
2421									b2 = b2[curIndex];
2422
2423									x1 = b.a + (b.b - b.a) * t;
2424									x2 = b.b + (b.c - b.b) * t;
2425									x1 += (x2 - x1) * t;
2426									x2 += ((b.c + (b.d - b.c) * t) - x2) * t;
2427
2428									y1 = b2.a + (b2.b - b2.a) * t;
2429									y2 = b2.b + (b2.c - b2.b) * t;
2430									y1 += (y2 - y1) * t;
2431									y2 += ((b2.c + (b2.d - b2.c) * t) - y2) * t;
2432
2433									val = notStart ? Math.atan2(y2 - y1, x2 - x1) * conv + add : this._initialRotations[i];
2434
2435									if (this._mod[p]) {
2436										val = this._mod[p](val, target); //for modProps
2437									}
2438
2439									if (func[p]) {
2440										target[p](val);
2441									} else {
2442										target[p] = val;
2443									}
2444								}
2445							}
2446						}
2447					}
2448			}),
2449			p = BezierPlugin.prototype;
2450
2451
2452		BezierPlugin.bezierThrough = bezierThrough;
2453		BezierPlugin.cubicToQuadratic = cubicToQuadratic;
2454		BezierPlugin._autoCSS = true; //indicates that this plugin can be inserted into the "css" object using the autoCSS feature of TweenLite
2455		BezierPlugin.quadraticToCubic = function(a, b, c) {
2456			return new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c);
2457		};
2458
2459		BezierPlugin._cssRegister = function() {
2460			var CSSPlugin = _globals.CSSPlugin;
2461			if (!CSSPlugin) {
2462				return;
2463			}
2464			var _internals = CSSPlugin._internals,
2465				_parseToProxy = _internals._parseToProxy,
2466				_setPluginRatio = _internals._setPluginRatio,
2467				CSSPropTween = _internals.CSSPropTween;
2468			_internals._registerComplexSpecialProp("bezier", {parser:function(t, e, prop, cssp, pt, plugin) {
2469				if (e instanceof Array) {
2470					e = {values:e};
2471				}
2472				plugin = new BezierPlugin();
2473				var values = e.values,
2474					l = values.length - 1,
2475					pluginValues = [],
2476					v = {},
2477					i, p, data;
2478				if (l < 0) {
2479					return pt;
2480				}
2481				for (i = 0; i <= l; i++) {
2482					data = _parseToProxy(t, values[i], cssp, pt, plugin, (l !== i));
2483					pluginValues[i] = data.end;
2484				}
2485				for (p in e) {
2486					v[p] = e[p]; //duplicate the vars object because we need to alter some things which w
2486ould cause problems if the user plans to reuse the same vars object for another tween.
2487				}
2488				v.values = pluginValues;
2489				pt = new CSSPropTween(t, "bezier", 0, 0, data.pt, 2);
2490				pt.data = data;
2491				pt.plugin = plugin;
2492				pt.setRatio = _setPluginRatio;
2493				if (v.autoRotate === 0) {
2494					v.autoRotate = true;
2495				}
2496				if (v.autoRotate && !(v.autoRotate instanceof Array)) {
2497					i = (v.autoRotate === true) ? 0 : Number(v.autoRotate);
2498					v.autoRotate = (data.end.left != null) ? [["left","top","rotation",i,false]] : (data.end.x != null) ? [["x","y","rotation",i,false]] : false;
2499				}
2500				if (v.autoRotate) {
2501					if (!cssp._transform) {
2502						cssp._enableTransforms(false);
2503					}
2504					data.autoRotate = cssp._target._gsTransform;
2505					data.proxy.rotation = data.autoRotate.rotation || 0;
2506					cssp._overwriteProps.push("rotation");
2507				}
2508				plugin._onInitTween(data.proxy, v, cssp._tween);
2509				return pt;
2510			}});
2511		};
2512
2513		p._mod = function(lookup) {
2514			var op = this._overwriteProps,
2515				i = op.length,
2516				val;
2517			while (--i > -1) {
2518				val = lookup[op[i]];
2519				if (val && typeof(val) === "function") {
2520					this._mod[op[i]] = val;
2521				}
2522			}
2523		};
2524
2525		p._kill = function(lookup) {
2526			var a = this._props,
2527				p, i;
2528			for (p in this._beziers) {
2529				if (p in lookup) {
2530					delete this._beziers[p];
2531					delete this._func[p];
2532					i = a.length;
2533					while (--i > -1) {
2534						if (a[i] === p) {
2535							a.splice(i, 1);
2536						}
2537					}
2538				}
2539			}
2540			a = this._autoRotate;
2541			if (a) {
2542				i = a.length;
2543				while (--i > -1) {
2544					if (lookup[a[i][2]]) {
2545						a.splice(i, 1);
2546					}
2547				}
2548			}
2549			return this._super._kill.call(this, lookup);
2550		};
2551
2552	}());
2553
2554
2555
2556
2557
2558
2559	
2560	
2561	
2562	
2563	
2564	
2565	
2566	
2567/*
2568 * ----------------------------------------------------------------
2569 * CSSPlugin
2570 * ----------------------------------------------------------------
2571 */
2572	_gsScope._gsDefine("plugins.CSSPlugin", ["plugins.TweenPlugin","TweenLite"], function(TweenPlugin, TweenLite) {
2573
2574		/** @constructor **/
2575		var CSSPlugin = function() {
2576				TweenPlugin.call(this, "css");
2577				this._overwriteProps.length = 0;
2578				this.setRatio = CSSPlugin.prototype.setRatio; //speed optimization (avoid prototype lookup on this "hot" method)
2579			},
2580			_globals = _gsScope._gsDefine.globals,
2581			_hasPriority, //turns true whenever a CSSPropTween instance is created that has a priority other than 0. This helps us discern whether or not we should spend the time organizing the linked list or not after a CSSPlugin's _onInitTween() method is called.
2582			_suffixMap, //we set this in _onInitTween() each time as a way to have a persistent variable we can use in other methods like _parse() without having to pass it around as a parameter and we keep _parse() decoupled from a particular CSSPlugin instance
2583			_cs, //computed style (we store this in a shared variable to conserve memory and make minification tighter
2584			_overwriteProps, //alias to the currently instantiating CSSPlugin's _overwriteProps array. We use this closure in order to avoid having to pass a reference around from method to method and aid in minification.
2585			_specialProps = {},
2586			p = CSSPlugin.prototype = new TweenPlugin("css");
2587
2588		p.constructor = CSSPlugin;
2589		CSSPlugin.version = "2.0.2";
2590		CSSPlugin.API = 2;
2591		CSSPlugin.defaultTransformPerspective = 0;
2592		CSSPlugin.defaultSkewType = "compensated";
2593		CSSPlugin.defaultSmoothOrigin = true;
2594		p = "px"; //we'll reuse the "p" variable to keep file size down
2595		CSSPlugin.suffixMap = {top:p, right:p, bottom:p, left:p, width:p, height:p, fontSize:p, padding:p, margin:p, perspective:p, lineHeight:""};
2596
2597
2598		var _numExp = /(?:\-|\.|\b)(\d|\.|e\-)+/g,
2599			_relNumExp = /(?:\d|\-\d|\.\d|\-\.\d|\+=\d|\-=\d|\+=.\d|\-=\.\d)+/g,
2600			_valuesExp = /(?:\+=|\-=|\-|\b)[\d\-\.]+[a-zA-Z0-9]*(?:%|\b)/gi, //finds all the values that begin with numbers or += or -= and then a number. Includes suffixes. We use this to split complex values apart like "1px 5px 20px rgb(255,102,51)"
2601			_NaNExp = /(?![+-]?\d*\.?\d+|[+-]|e[+-]\d+)[^0-9]/g, //also allows scientific notation and doesn't kill the leading -/+ in -= and +=
2602			_suffixExp = /(?:\d|\-|\+|=|#|\.)*/g,
2603			_opacityExp = /opacity *= *([^)]*)/i,
2604			_opacityValExp = /opacity:([^;]*)/i,
2605			_alphaFilterExp = /alpha\(opacity *=.+?\)/i,
2606			_rgbhslExp = /^(rgb|hsl)/,
2607			_capsExp = /([A-Z])/g,
2608			_camelExp = /-([a-z])/gi,
2609			_urlExp = /(^(?:url\(\"|url\())|(?:(\"\))$|\)$)/gi, //for pulling out urls from url(...) or url("...") strings (some browsers wrap urls in quotes, some don't when reporting things like backgroundImage)
2610			_camelFunc = function(s, g) { return g.toUpperCase(); },
2611			_horizExp = /(?:Left|Right|Width)/i,
2612			_ieGetMatrixExp = /(M11|M12|M21|M22)=[\d\-\.e]+/gi,
2613			_ieSetMatrixExp = /progid\:DXImageTransform\.Microsoft\.Matrix\(.+?\)/i,
2614			_commasOutsideParenExp = /,(?=[^\)]*(?:\(|$))/gi, //finds any commas that are not within parenthesis
2615			_complexExp = /[\s,\(]/i, //for testing a string to find if it has a space, comma, or open parenthesis (clues that it's a complex value)
2616			_DEG2RAD = Math.PI / 180,
2617			_RAD2DEG = 180 / Math.PI,
2618			_forcePT = {},
2619			_dummyElement = {style:{}},
2620			_doc = _gsScope.document || {createElement: function() {return _dummyElement;}},
2621			_createElement = function(type, ns) {
2622				return _doc.createElementNS ? _doc.createElementNS(ns || "http://www.w3.org/1999/xhtml", type) : _doc.createElement(type);
2623			},
2624			_tempDiv = _createElement("div"),
2625			_tempImg = _createElement("img"),
2626			_internals = CSSPlugin._internals = {_specialProps:_specialProps}, //provides a hook to a few internal methods that we need to access from inside other plugins
2627			_agent = (_gsScope.navigator || {}).userAgent || "",
2628			_autoRound,
2629			_reqSafariFix, //we won't apply the Safari transform fix until we actually come across a tween that affects a transform property (to maintain best performance).
2630
2631			_isSafari,
2632			_isFirefox, //Firefox has a bug that causes 3D transformed elements to randomly disappear unless a repaint is forced after each update on each element.
2633			_isSafariLT6, //Safari (and Android 4 which uses a flavor of Safari) has a bug that prevents changes to "top" and "left" properties from rendering properly if changed on the same frame as a transform UNLESS we set the element's WebkitBackfaceVisibility to hidden (weird, I know). Doing this for Android 3 and earlier seems to actually cause other problems, though (fun!)
2634			_ieVers,
2635			_supportsOpacity = (function() { //we set _isSafari, _ieVers, _isFirefox, and _supportsOpacity all in one function here to reduce file size slightly, especially in the minified version.
2636				var i = _agent.indexOf("Android"),
2637					a = _createElement("a");
2638				_isSafari = (_agent.indexOf("Safari") !== -1 && _agent.indexOf("Chrome") === -1 && (i === -1 || parseFloat(_agent.substr(i+8, 2)) > 3));
2639				_isSafariLT6 = (_isSafari && (parseFloat(_agent.substr(_agent.indexOf("Version/")+8, 2)) < 6));
2640				_isFirefox = (_agent.indexOf("Firefox") !== -1);
2641				if ((/MSIE ([0-9]{1,}[\.0-9]{0,})/).exec(_agent) || (/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/).exec(_agent)) {
2642					_ieVers = parseFloat( RegExp.$1 );
2643				}
2644				if (!a) {
2645					return false;
2646				}
2647				a.style.cssText = "top:1px;opacity:.55;";
2648				return /^0.55/.test(a.style.opacity);
2649			}()),
2650			_getIEOpacity = function(v) {
2651				return (_opacityExp.test( ((typeof(v) === "string") ? v : (v.currentStyle ? v.currentStyle.filter : v.style.filter) || "") ) ? ( parseFloat( RegExp.$1 ) / 100 ) : 1);
2652			},
2653			_log = function(s) {//for logging messages, but in a way that won't throw errors in old versions of IE.
2654				if (_gsScope.console) {
2655					console.log(s);
2656				}
2657			},
2658			_target, //when initting a CSSPlugin, we set this variable so that we can access it from within many other functions without having to pass it around as params
2659			_index, //when initting a CSSPlugin, we set this variable so that we can access it from within many other functions without having to pass it around as params
2660
2661			_prefixCSS = "", //the non-camelCase vendor prefix like "-o-", "-moz-", "-ms-", or "-webkit-"
2662			_prefix = "", //camelCase vendor prefix like "O", "ms", "Webkit", or "Moz".
2663
2664			// @private feed in a camelCase property name like "transform" and it will check to see if it is valid as-is or if it needs a vendor prefix. It returns the corrected camelCase property name (i.e. "WebkitTransform" or "MozTransform" or "transform" or null if no such property is found, like if the browser is IE8 or before, "transform" won't be found at all)
2665			_checkPropPrefix = function(p, e) {
2666				e = e || _tempDiv;
2667				var s = e.style,
2668					a, i;
2669				if (s[p] !== undefined) {
2670					return p;
2671				}
2672				p = p.charAt(0).toUpperCase() + p.substr(1);
2673				a = ["O","Moz","ms","Ms","Webkit"];
2674				i = 5;
2675				while (--i > -1 && s[a[i]+p] === undefined) { }
2676				if (i >= 0) {
2677					_prefix = (i === 3) ? "ms" : a[i];
2678					_prefixCSS = "-" + _prefix.toLowerCase() + "-";
2679					return _prefix + p;
2680				}
2681				return null;
2682			},
2683
2684			_getComputedStyle = (typeof(window) !== "undefined" ? window : _doc.defaultView || {getComputedStyle:function() {}}).getComputedStyle,
2685
2686			/**
2687			 * @private Returns the css style for a particular property of an element. For example, to get whatever the current "left" css value for an element with an ID of "myElement", you could do:
2688			 * var currentLeft = CSSPlugin.getStyle( document.getElementById("myElement"), "left");
2689			 *
2690			 * @param {!Object} t Target element whose style property you want to query
2691			 * @param {!string} p Property name (like "left" or "top" or "marginTop", etc.)
2692			 * @param {Object=} cs Computed style object. This just provides a way to speed processing if you're going to get several properties on the same element in quick succession - you can reuse the result of the getComputedStyle() call.
2693			 * @param {boolean=} calc If true, the value will not be read directly from the element's "style" property (if it exists there), but instead the getComputedStyle() result will be used. This can be useful when you want to ensure that the browser itself is interpreting the value.
2694			 * @param {string=} dflt Default value that should be returned in the place of null, "none", "auto" or "auto auto".
2695			 * @return {?string} The current property value
2696			 */
2697			_getStyle = CSSPlugin.getStyle = function(t, p, cs, calc, dflt) {
2698				var rv;
2699				if (!_supportsOpacity) if (p === "opacity") { //several versions of IE don't use the standard "opacity" property - they use things like filter:alpha(opacity=50), so we parse that here.
2700					return _getIEOpacity(t);
2701				}
2702				if (!calc && t.style[p]) {
2703					rv = t.style[p];
2704				} else if ((cs = cs || _getComputedStyle(t))) {
2705					rv = cs[p] || cs.getPropertyValue(p) || cs.getPropertyValue(p.replace(_capsExp, "-$1").toLowerCase());
2706				} else if (t.currentStyle) {
2707					rv = t.currentStyle[p];
2708				}
2709				return (dflt != null && (!rv || rv === "none" || rv === "auto" || rv === "auto auto")) ? dflt : rv;
2710			},
2711
2712			/**
2713			 * @private Pass the target element, the property name, the numeric value, and the suffix (like "%", "em", "px", etc.) and it will spit back the equivalent pixel number.
2714			 * @param {!Object} t Target element
2715			 * @param {!string} p Property name (like "left", "top", "marginLeft", etc.)
2716			 * @param {!number} v Value
2717			 * @param {string=} sfx Suffix (like "px" or "%" or "em")
2718			 * @param {boolean=} recurse If true, the call is a recursive one. In some browsers (like IE7/8), occasionally the value isn't accurately reported initially, but if we run the function again it will take effect.
2719			 * @return {number} value in pixels
2720			 */
2721			_convertToPixels = _internals.convertToPixels = function(t, p, v, sfx, recurse) {
2722				if (sfx === "px" || (!sfx && p !== "lineHeight")) { return v; }
2723				if (sfx === "auto" || !v) { return 0; }
2724				var horiz = _horizExp.test(p),
2725					node = t,
2726					style = _tempDiv.style,
2727					neg = (v < 0),
2728					precise = (v === 1),
2729					pix, cache, time;
2730				if (neg) {
2731					v = -v;
2732				}
2733				if (precise) {
2734					v *= 100;
2735				}
2736				if (p === "lineHeight" && !sfx) { //special case of when a simple lineHeight (without a unit) is used. Set it to the value, read back the computed value, and then revert.
2737					cache = _getComputedStyle(t).lineHeight;
2738					t.style.lineHeight = v;
2739					pix = parseFloat(_getComputedStyle(t).lineHeight);
2740					t.style.lineHeight = cache;
2741				} else if (sfx === "%" && p.indexOf("border") !== -1) {
2742					pix = (v / 100) * (horiz ? t.clientWidth : t.clientHeight);
2743				} else {
2744					style.cssText = "border:0 solid red;position:" + _getStyle(t, "position") + ";line-height:0;";
2745					if (sfx === "%" || !node.appendChild || sfx.charAt(0) === "v" || sfx === "rem") {
2746						node = t.parentNode || _doc.body;
2747						if (_getStyle(node, "display").indexOf("flex") !== -1) { //Edge and IE11 have a bug that causes offsetWidth to report as 0 if the container has display:flex and the child is position:relative. Switching to position: absolute solves it.
2748							style.position = "absolute";
2749						}
2750						cache = node._gsCache;
2751						time = TweenLite.ticker.frame;
2752						if (cache && horiz && cache.time === time) { //performance optimization: we record the width of elements along with the ticker frame so that we can quickly get it again on the same tick (seems relatively safe to assume it wouldn't change on the same tick)
2753							return cache.width * v / 100;
2754						}
2755						style[(horiz ? "width" : "height")] = v + sfx;
2756					} else {
2757						style[(horiz ? "borderLeftWidth" : "borderTopWidth")] = v + sfx;
2758					}
2759					node.appendChild(_tempDiv);
2760					pix = parseFloat(_tempDiv[(horiz ? "offsetWidth" : "offsetHeight")]);
2761					node.removeChild(_tempDiv);
2762					if (horiz && sfx === "%" && CSSPlugin.cacheWidths !== false) {
2763						cache = node._gsCache = node._gsCache || {};
2764						cache.time = time;
2765						cache.width = pix / v * 100;
2766					}
2767					if (pix === 0 && !recurse) {
2768						pix = _convertToPixels(t, p, v, sfx, true);
2769					}
2770				}
2771				if (precise) {
2772					pix /= 100;
2773				}
2774				return neg ? -pix : pix;
2775			},
2776			_calculateOffset = _internals.calculateOffset = function(t, p, cs) { //for figuring out "top" or "left" in px when it's "auto". We need to factor in margin with the offsetLeft/offsetTop
2777				if (_getStyle(t, "position", cs) !== "absolute") { return 0; }
2778				var dim = ((p === "left") ? "Left" : "Top"),
2779					v = _getStyle(t, "margin" + dim, cs);
2780				return t["offset" + dim] - (_convertToPixels(t, p, parseFloat(v), v.replace(_suffixExp, "")) || 0);
2781			},
2782
2783			// @private returns at object containing ALL of the style properties in camelCase and their associated values.
2784			_getAllStyles = function(t, cs) {
2785				var s = {},
2786					i, tr, p;
2787				if ((cs = cs || _getComputedStyle(t, null))) {
2788					if ((i = cs.length)) {
2789						while (--i > -1) {
2790							p = cs[i];
2791							if (p.indexOf("-transform") === -1 || _transformPropCSS === p) { //Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here.
2792								s[p.replace(_camelExp, _camelFunc)] = cs.getPropertyValue(p);
2793							}
2794						}
2795					} else { //some browsers behave differently - cs.length is always 0, so we must do a for...in loop.
2796						for (i in cs) {
2797							if (i.indexOf("Transform") === -1 || _transformProp === i) { //Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here.
2798								s[i] = cs[i];
2799							}
2800						}
2801					}
2802				} else if ((cs = t.currentStyle || t.style)) {
2803					for (i in cs) {
2804						if (typeof(i) === "string" && s[i] === undefined) {
2805							s[i.replace(_camelExp, _camelFunc)] = cs[i];
2806						}
2807					}
2808				}
2809				if (!_supportsOpacity) {
2810					s.opacity = _getIEOpacity(t);
2811				}
2812				tr = _getTransform(t, cs, false);
2813				s.rotation = tr.rotation;
2814				s.skewX = tr.skewX;
2815				s.scaleX = tr.scaleX;
2816				s.scaleY = tr.scaleY;
2817				s.x = tr.x;
2818				s.y = tr.y;
2819				if (_supports3D) {
2820					s.z = tr.z;
2821					s.rotationX = tr.rotationX;
2822					s.rotationY = tr.rotationY;
2823					s.scaleZ = tr.scaleZ;
2824				}
2825				if (s.filters) {
2826					delete s.filters;
2827				}
2828				return s;
2829			},
2830
2831			// @private analyzes two style objects (as returned by _getAllStyles()) and only looks for differences between them that contain tweenable values (like a number or color). It returns an object with a "difs" property which refers to an object c
2831ontaining only those isolated properties and values for tweening, and a "firstMPT" property which refers to the first MiniPropTween instance in a linked list that recorded all the starting values of the different properties so that we can revert to them at the end or beginning of the tween - we don't want the cascading to get messed up. The forceLookup parameter is an optional generic object with properties that should be forced into the results - this is necessary for className tweens that are overwriting others because imagine a scenario where a rollover/rollout adds/removes a class and the user swipes the mouse over the target SUPER fast, thus nothing actually changed yet and the subsequent comparison of the properties would indicate they match (especially when px rounding is taken into consideration), thus no tweening is necessary even though it SHOULD tween and remove those properties after the tween (otherwise the inline styles will contaminate things). See the className SpecialProp code for details.
2832			_cssDif = function(t, s1, s2, vars, forceLookup) {
2833				var difs = {},
2834					style = t.style,
2835					val, p, mpt;
2836				for (p in s2) {
2837					if (p !== "cssText") if (p !== "length") if (isNaN(p)) if (s1[p] !== (val = s2[p]) || (forceLookup && forceLookup[p])) if (p.indexOf("Origin") === -1) if (typeof(val) === "number" || typeof(val) === "string") {
2838						difs[p] = (val === "auto" && (p === "left" || p === "top")) ? _calculateOffset(t, p) : ((val === "" || val === "auto" || val === "none") && typeof(s1[p]) === "string" && s1[p].replace(_NaNExp, "") !== "") ? 0 : val; //if the ending value is defaulting ("" or "auto"), we check the starting value and if it can be parsed into a number (a string which could have a suffix too, like 700px), then we swap in 0 for "" or "auto" so that things actually tween.
2839						if (style[p] !== undefined) { //for className tweens, we must remember which properties already existed inline - the ones that didn't should be removed when the tween isn't in progress because they were only introduced to facilitate the transition between classes.
2840							mpt = new MiniPropTween(style, p, style[p], mpt);
2841						}
2842					}
2843				}
2844				if (vars) {
2845					for (p in vars) { //copy properties (except className)
2846						if (p !== "className") {
2847							difs[p] = vars[p];
2848						}
2849					}
2850				}
2851				return {difs:difs, firstMPT:mpt};
2852			},
2853			_dimensions = {width:["Left","Right"], height:["Top","Bottom"]},
2854			_margins = ["marginLeft","marginRight","marginTop","marginBottom"],
2855
2856			/**
2857			 * @private Gets the width or height of an element
2858			 * @param {!Object} t Target element
2859			 * @param {!string} p Property name ("width" or "height")
2860			 * @param {Object=} cs Computed style object (if one exists). Just a speed optimization.
2861			 * @return {number} Dimension (in pixels)
2862			 */
2863			_getDimension = function(t, p, cs) {
2864				if ((t.nodeName + "").toLowerCase() === "svg") { //Chrome no longer supports offsetWidth/offsetHeight on SVG elements.
2865					return (cs || _getComputedStyle(t))[p] || 0;
2866				} else if (t.getCTM && _isSVG(t)) {
2867					return t.getBBox()[p] || 0;
2868				}
2869				var v = parseFloat((p === "width") ? t.offsetWidth : t.offsetHeight),
2870					a = _dimensions[p],
2871					i = a.length;
2872				cs = cs || _getComputedStyle(t, null);
2873				while (--i > -1) {
2874					v -= parseFloat( _getStyle(t, "padding" + a[i], cs, true) ) || 0;
2875					v -= parseFloat( _getStyle(t, "border" + a[i] + "Width", cs, true) ) || 0;
2876				}
2877				return v;
2878			},
2879
2880			// @private Parses position-related complex strings like "top left" or "50px 10px" or "70% 20%", etc. which are used for things like transformOrigin or backgroundPosition. Optionally decorates a supplied object (recObj) with the following properties: "ox" (offsetX), "oy" (offsetY), "oxp" (if true, "ox" is a percentage not a pixel value), and "oxy" (if true, "oy" is a percentage not a pixel value)
2881			_parsePosition = function(v, recObj) {
2882				if (v === "contain" || v === "auto" || v === "auto auto") { //note: Firefox uses "auto auto" as default whereas Chrome uses "auto".
2883					return v + " ";
2884				}
2885				if (v == null || v === "") {
2886					v = "0 0";
2887				}
2888				var a = v.split(" "),
2889					x = (v.indexOf("left") !== -1) ? "0%" : (v.indexOf("right") !== -1) ? "100%" : a[0],
2890					y = (v.indexOf("top") !== -1) ? "0%" : (v.indexOf("bottom") !== -1) ? "100%" : a[1],
2891					i;
2892				if (a.length > 3 && !recObj) { //multiple positions
2893					a = v.split(", ").join(",").split(",");
2894					v = [];
2895					for (i = 0; i < a.length; i++) {
2896						v.push(_parsePosition(a[i]));
2897					}
2898					return v.join(",");
2899				}
2900				if (y == null) {
2901					y = (x === "center") ? "50%" : "0";
2902				} else if (y === "center") {
2903					y = "50%";
2904				}
2905				if (x === "center" || (isNaN(parseFloat(x)) && (x + "").indexOf("=") === -1)) { //remember, the user could flip-flop the values and say "bottom center" or "center bottom", etc. "center" is ambiguous because it c
2905ould be used to describe horizontal or vertical, hence the isNaN(). If there's an "=" sign in the value, it's relative.
2906					x = "50%";
2907				}
2908				v = x + " " + y + ((a.length > 2) ? " " + a[2] : "");
2909				if (recObj) {
2910					recObj.oxp = (x.indexOf("%") !== -1);
2911					recObj.oyp = (y.indexOf("%") !== -1);
2912					recObj.oxr = (x.charAt(1) === "=");
2913					recObj.oyr = (y.charAt(1) === "=");
2914					recObj.ox = parseFloat(x.replace(_NaNExp, ""));
2915					recObj.oy = parseFloat(y.replace(_NaNExp, ""));
2916					recObj.v = v;
2917				}
2918				return recObj || v;
2919			},
2920
2921			/**
2922			 * @private Takes an ending value (typically a string, but can be a number) and a starting value and returns the change between the two, looking for relative value indicators like += and -= and it also ignores suffixes (but make sure the ending value starts with a number or +=/-= and that the starting value is a NUMBER!)
2923			 * @param {(number|string)} e End value which is typically a string, but could be a number
2924			 * @param {(number|string)} b Beginning value which is typically a string but could be a number
2925			 * @return {number} Amount of change between the beginning and ending values (relative values that have a "+=" or "-=" are recognized)
2926			 */
2927			_parseChange = function(e, b) {
2928				if (typeof(e) === "function") {
2929					e = e(_index, _target);
2930				}
2931				return (typeof(e) === "string" && e.charAt(1) === "=") ? parseInt(e.charAt(0) + "1", 10) * parseFloat(e.substr(2)) : (parseFloat(e) - parseFloat(b)) || 0;
2932			},
2933
2934			/**
2935			 * @private Takes a value and a default number, checks if the value is relative, null, or numeric and spits back a normalized number accordingly. Primarily used in the _parseTransform() function.
2936			 * @param {Object} v Value to be parsed
2937			 * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter)
2938			 * @return {number} Parsed value
2939			 */
2940			_parseVal = function(v, d) {
2941				if (typeof(v) === "function") {
2942					v = v(_index, _target);
2943				}
2944				var isRelative = (typeof(v) === "string" && v.charAt(1) === "=");
2945				if (typeof(v) === "string" && v.charAt(v.length - 2) === "v") { //convert vw and vh into px-equivalents.
2946					v = (isRelative ? v.substr(0, 2) : 0) + (window["inner" + ((v.substr(-2) === "vh") ? "Height" : "Width")] * (parseFloat(isRelative ? v.substr(2) : v) / 100));
2947				}
2948				return (v == null) ? d : isRelative ? parseInt(v.charAt(0) + "1", 10) * parseFloat(v.substr(2)) + d : parseFloat(v) || 0;
2949			},
2950
2951			/**
2952			 * @private Translates strings like "40deg" or "40" or 40rad" or "+=40deg" or "270_short" or "-90_cw" or "+=45_ccw" to a numeric radian angle. Of course a starting/default value must be fed in too so that relative values can be calculated properly.
2953			 * @param {Object} v Value to be parsed
2954			 * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter)
2955			 * @param {string=} p property name for directionalEnd (optional - only used when the parsed value is directional ("_short", "_cw", or "_ccw" suffix). We need a way to store the uncompensated value so that at the end of the tween, we set it to exactly what was requested with no directional compensation). Property name would be "rotation", "rotationX", or "rotationY"
2956			 * @param {Object=} directionalEnd An object that will store the raw end values for directional angles ("_short", "_cw", or "_ccw" suffix). We need a way to store the uncompensated value so that at the end of the tween, we set it to exactly what was requested with no directional compensation.
2957			 * @return {number} parsed angle in radians
2958			 */
2959			_parseAngle = function(v, d, p, directionalEnd) {
2960				var min = 0.000001,
2961					cap, split, dif, result, isRelative;
2962				if (typeof(v) === "function") {
2963					v = v(_index, _target);
2964				}
2965				if (v == null) {
2966					result = d;
2967				} else if (typeof(v) === "number") {
2968					result = v;
2969				} else {
2970					cap = 360;
2971					split = v.split("_");
2972					isRelative = (v.charAt(1) === "=");
2973					dif = (isRelative ? parseInt(v.charAt(0) + "1", 10) * parseFloat(split[0].substr(2)) : parseFloat(split[0])
2973) * ((v.indexOf("rad") === -1) ? 1 : _RAD2DEG) - (isRelative ? 0 : d);
2974					if (split.length) {
2975						if (directionalEnd) {
2976							directionalEnd[p] = d + dif;
2977						}
2978						if (v.indexOf("short") !== -1) {
2979							dif = dif % cap;
2980							if (dif !== dif % (cap / 2)) {
2981								dif = (dif < 0) ? dif + cap : dif - cap;
2982							}
2983						}
2984						if (v.indexOf("_cw") !== -1 && dif < 0) {
2985							dif = ((dif + cap * 9999999999) % cap) - ((dif / cap) | 0) * cap;
2986						} else if (v.indexOf("ccw") !== -1 && dif > 0) {
2987							dif = ((dif - cap * 9999999999) % cap) - ((dif / cap) | 0) * cap;
2988						}
2989					}
2990					result = d + dif;
2991				}
2992				if (result < min && result > -min) {
2993					result = 0;
2994				}
2995				return result;
2996			},
2997
2998			_colorLookup = {aqua:[0,255,255],
2999				lime:[0,255,0],
3000				silver:[192,192,192],
3001				black:[0,0,0],
3002				maroon:[128,0,0],
3003				teal:[0,128,128],
3004				blue:[0,0,255],
3005				navy:[0,0,128],
3006				white:[255,255,255],
3007				fuchsia:[255,0,255],
3008				olive:[128,128,0],
3009				yellow:[255,255,0],
3010				orange:[255,165,0],
3011				gray:[128,128,128],
3012				purple:[128,0,128],
3013				green:[0,128,0],
3014				red:[255,0,0],
3015				pink:[255,192,203],
3016				cyan:[0,255,255],
3017				transparent:[255,255,255,0]},
3018
3019			_hue = function(h, m1, m2) {
3020				h = (h < 0) ? h + 1 : (h > 1) ? h - 1 : h;
3021				return ((((h * 6 < 1) ? m1 + (m2 - m1) * h * 6 : (h < 0.5) ? m2 : (h * 3 < 2) ? m1 + (m2 - m1) * (2 / 3 - h) * 6 : m1) * 255) + 0.5) | 0;
3022			},
3023
3024			/**
3025			 * @private Parses a color (like #9F0, #FF9900, rgb(255,51,153) or hsl(108, 50%, 10%)) into an array with 3 elements for red, green, and blue or if toHSL parameter is true, it will populate the array with hue, saturation, and lightness values. If a relative value is found in an hsl() or hsla() string, it will preserve those relative prefixes and all the values in the array will be strings instead of numbers (in all other cases it will be populated with numbers).
3026			 * @param {(string|number)} v The value the should be parsed which could be a string like #9F0 or rgb(255,102,51) or rgba(255,0,0,0.5) or it could be a number like 0xFF00CC or even a named color like red, blue, purple, etc.
3027			 * @param {(boolean)} toHSL If true, an hsl() or hsla() value will be returned instead of rgb() or rgba()
3028			 * @return {Array.<number>} An array containing red, green, and blue (and optionally alpha) in that order, or if the toHSL parameter was true, the array will contain hue, saturation and lightness (and optionally alpha) in that order. Always numbers unless there's a relative prefix found in an hsl() or hsla() string and toHSL is true.
3029			 */
3030			_parseColor = CSSPlugin.parseColor = function(v, toHSL) {
3031				var a, r, g, b, h, s, l, max, min, d, wasHSL;
3032				if (!v) {
3033					a = _colorLookup.black;
3034				} else if (typeof(v) === "number") {
3035					a = [v >> 16, (v >> 8) & 255, v & 255];
3036				} else {
3037					if (v.charAt(v.length - 1) === ",") { //sometimes a trailing comma is included and we should chop it off (typically from a comma-delimited list of values like a textShadow:"2px 2px 2px blue, 5px 5px 5px rgb(255,0,0)" - in this example "blue," has a trailing comma. We could strip it out inside parseComplex() but we'd need to do it to the beginning and ending values plus it wouldn't provide protection from other potential scenarios like if the user passes in a similar value.
3038						v = v.substr(0, v.length - 1);
3039					}
3040					if (_colorLookup[v]) {
3041						a = _colorLookup[v];
3042					} else if (v.charAt(0) === "#") {
3043						if (v.length === 4) { //for shorthand like #9F0
3044							r = v.charAt(1);
3045							g = v.charAt(2);
3046							b = v.charAt(3);
3047							v = "#" + r + r + g + g + b + b;
3048						}
3049						v = parseInt(v.substr(1), 16);
3050						a = [v >> 16, (v >> 8) & 255, v & 255];
3051					} else if (v.substr(0, 3) === "hsl") {
3052						a = wasHSL = v.match(_numExp);
3053						if (!toHSL) {
3054							h = (Number(a[0]) % 360) / 360;
3055							s = Number(a[1]) / 100;
3056							l = Number(a[2]) / 100;
3057							g = (l <= 0.5) ? l * (s + 1) : l + s - l * s;
3058							r = l * 2 - g;
3059							if (a.length > 3) {
3060								a[3] = Number(a[3]);
3061							}
3062							a[0] = _hue(h + 1 / 3, r, g);
3063							a[1] = _hue(h, r, g);
3064							a[2] = _hue(h - 1 / 3, r, g);
3065						} else if (v.indexOf("=") !== -1) { //if relative values are found, just return the raw strings with the relative prefixes in place.
3066							return v.match(_relNumExp);
3067						}
3068					} else {
3069						a = v.match(_numExp) || _colorLookup.transparent;
3070					}
3071					a[0] = Number(a[0]);
3072					a[1] = Number(a[1]);
3073					a[2] = Number(a[2]);
3074					if (a.length > 3) {
3075						a[3] = Number(a[3]);
3076					}
3077				}
3078				if (toHSL && !wasHSL) {
3079					r = a[0] / 255;
3080					g = a[1] / 255;
3081					b = a[2] / 255;
3082					max = Math.max(r, g, b);
3083					min = Math.min(r, g, b);
3084					l = (max + min) / 2;
3085					if (max === min) {
3086						h = s = 0;
3087					} else {
3088						d = max - min;
3089						s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
3090						h = (max === r) ? (g - b) / d + (g < b ? 6 : 0) : (max === g) ? (b - r) / d + 2 : (r - g) / d + 4;
3091						h *= 60;
3092					}
3093					a[0] = (h + 0.5) | 0;
3094					a[1] = (s * 100 + 0.5) | 0;
3095					a[2] = (l * 100 + 0.5) | 0;
3096				}
3097				return a;
3098			},
3099			_formatColors = function(s, toHSL) {
3100				var colors = s.match(_colorExp) || [],
3101					charIndex = 0,
3102					parsed = "",
3103					i, color, temp;
3104				if (!colors.length) {
3105					return s;
3106				}
3107				for (i = 0; i < colors.length; i++) {
3108					color = colors[i];
3109					temp = s.substr(charIndex, s.indexOf(color, charIndex)-charIndex);
3110					charIndex += temp.length + color.length;
3111					color = _parseColor(color, toHSL);
3112					if (color.length === 3) {
3113						color.push(1);
3114					}
3115					parsed += temp + (toHSL ? "hsla(" + color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : "rgba(" + color.join(",")) + ")";
3116				}
3117				return parsed + s.substr(charIndex);
3118			},
3119			_colorExp = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3}){1,2}\\b"; //we'll dynamically build this Regular Expression to conserve file size. After building it, it will be able to find rgb(), rgba(), # (hexadecimal), and named color values like red, blue, purple, etc.
3120
3121		for (p in _colorLookup) {
3122			_colorExp += "|" + p + "\\b";
3123		}
3124		_colorExp = new RegExp(_colorExp+")", "gi");
3125
3126		CSSPlugin.colorStringFilter = function(a) {
3127			var combined = a[0] + " " + a[1],
3128				toHSL;
3129			if (_colorExp.test(combined)) {
3130				toHSL = (combined.indexOf("hsl(") !== -1 || combined.indexOf("hsla(") !== -1);
3131				a[0] = _formatColors(a[0], toHSL);
3132				a[1] = _formatColors(a[1], toHSL);
3133			}
3134			_colorExp.lastIndex = 0;
3135		};
3136
3137		if (!TweenLite.defaultStringFilter) {
3138			TweenLite.defaultStringFilter = CSSPlugin.colorStringFilter;
3139		}
3140
3141		/**
3142		 * @private Returns a formatter function that handles taking a string (or number in some cases) and returning a consistently formatted one in terms of delimiters, quantity of values, etc. For example, we may get boxShadow values defined as "0px red" or "0px 0px 10px rgb(255,0,0)" or "0px 0px 20px 20px #F00" and we need to ensure that what we get back is described with 4 numbers and a color. This allows us to feed it into the _parseComplex() method and split the values up appropriately. The neat thing about this _getFormatter() function is that the dflt defines a pattern as well as a default, so for example, _getFormatter("0px 0px 0px 0px #777", true) not only sets the default as 0px for all distances and #777 for the color, but also sets the pattern such that 4 numbers and a color will always get returned.
3143		 * @param {!string} dflt The default value and pattern to follow. So "0px 0px 0px 0px #777" will ensure that 4 numbers and a color will always get returned.
3144		 * @param {boolean=} clr If true, the values should be searched for color-related data. For example, boxShadow values typically contain a color whereas borderRadius don't.
3145		 * @param {boolean=} collapsible If true, the value is a top/left/right/bottom style one that acts like margin or padding, where if only one value is received, it's used for all 4; if 2 are received, the first is duplicated for 3rd (bottom) and the 2nd is duplicated for the 4th spot (left), etc.
3146		 * @return {Function} formatter function
3147		 */
3148		var _getFormatter = function(dflt, clr, collapsible, multi) {
3149				if (dflt == null) {
3150					return function(v) {return v;};
3151				}
3152				var dColor = clr ? (dflt.match(_colorExp) || [""])[0] : "",
3153					dVals = dflt.split(dColor).join("").match(_valuesExp) || [],
3154					pfx = dflt.substr(0, dflt.indexOf(dVals[0])),
3155					sfx = (dflt.charAt(dflt.length - 1) === ")") ? ")" : "",
3156					delim = (dflt.indexOf(" ") !== -1) ? " " : ",",
3157					numVals = dVals.length,
3158					dSfx = (numVals > 0) ? dVals[0].replace(_numExp, "") : "",
3159					formatter;
3160				if (!numVals) {
3161					return function(v) {return v;};
3162				}
3163				if (clr) {
3164					formatter = function(v) {
3165						var color, vals, i, a;
3166						if (typeof(v) === "number") {
3167							v += dSfx;
3168						} else if (multi && _commasOutsideParenExp.test(v)) {
3169							a = v.replace(_commasOutsideParenExp, "|").split("|");
3170							for (i = 0; i < a.length; i++) {
3171								a[i] = formatter(a[i]);
3172							}
3173							return a.join(",");
3174						}
3175						color = (v.match(_colorExp) || [dColor])[0];
3176						vals = v.split(color).join("").match(_valuesExp) || [];
3177						i = vals.length;
3178						if (numVals > i--) {
3179							while (++i < numVals) {
3180								vals[i] = collapsible ? vals[(((i - 1) / 2) | 0)] : dVals[i];
3181							}
3182						}
3183						return pfx + vals.join(delim) + delim + color + sfx + (v.indexOf("inset") !== -1 ? " inset" : "");
3184					};
3185					return formatter;
3186
3187				}
3188				formatter = function(v) {
3189					var vals, a, i;
3190					if (typeof(v) === "number") {
3191						v += dSfx;
3192					} else if (multi && _commasOutsideParenExp.test(v)) {
3193						a = v.replace(_commasOutsideParenExp, "|").split("|");
3194						for (i = 0; i < a.length; i++) {
3195							a[i] = formatter(a[i]);
3196						}
3197						return a.join(",");
3198					}
3199					vals = v.match(_valuesExp) || [];
3200					i = vals.length;
3201					if (numVals > i--) {
3202						while (++i < numVals) {
3203							vals[i] = collapsible ? vals[(((i - 1) / 2) | 0)] : dVals[i];
3204						}
3205					}
3206					return pfx + vals.join(delim) + sfx;
3207				};
3208				return formatter;
3209			},
3210
3211			/**
3212			 * @private returns a formatter function that's used for edge-related values like marginTop, marginLeft, paddingBottom, paddingRight, etc. Just pass a comma-delimited list of property names related to the edges.
3213			 * @param {!string} props a comma-delimited list of property names in order from top to left, like "marginTop,marginRight,marginBottom,marginLeft"
3214			 * @return {Function} a formatter function
3215			 */
3216			_getEdgeParser = function(props) {
3217				props = props.split(",");
3218				return function(t, e, p, cssp, pt, plugin, vars) {
3219					var a = (e + "").split(" "),
3220						i;
3221					vars = {};
3222					for (i = 0; i < 4; i++) {
3223						vars[props[i]] = a[i] = a[i] || a[(((i - 1) / 2) >> 0)];
3224					}
3225					return cssp.parse(t, vars, pt, plugin);
3226				};
3227			},
3228
3229			// @private used when other plugins must tween values first, like BezierPlugin or ThrowPropsPlugin, etc. That plugin's setRatio() gets called first so that the values are updated, and then we loop through the MiniPropTweens which handle copying the values into their appropriate slots so that they can then be applied correctly in the main CSSPlugin setRatio() method. Remember, we typically create a proxy object that has a bunch of uniquely-named properties that we feed to the sub-plugin and it does its magic normally, and then we must interpret those values and apply them to the css because often numbers must get combined/concatenated, suffixes added, etc. to work with css, like boxShadow could have 4 values plus a color.
3230			_setPluginRatio = _internals._setPluginRatio = function(v) {
3231				this.plugin.setRatio(v);
3232				var d = this.data,
3233					proxy = d.proxy,
3234					mpt = d.firstMPT,
3235					min = 0.000001,
3236					val, pt, i, str, p;
3237				while (mpt) {
3238					val = proxy[mpt.v];
3239					if (mpt.r) {
3240						val = mpt.r(val);
3241					} else if (val < min && val > -min) {
3242						val = 0;
3243					}
3244					mpt.t[mpt.p] = val;
3245					mpt = mpt._next;
3246				}
3247				if (d.autoRotate) {
3248					d.autoRotate.rotation = d.mod ? d.mod.call(this._tween, proxy.rotation, this.t, this._tween) : proxy.rotation; //special case for ModifyPlugin to hook into an auto-rotating bezier
3249				}
3250				//at the end, we must set the CSSPropTween's "e" (end) value dynamically here because that's what is used in the final setRatio() method. Same for "b" at the beginning.
3251				if (v === 1 || v === 0) {
3252					mpt = d.firstMPT;
3253					p = (v === 1) ? "e" : "b";
3254					while (mpt) {
3255						pt = mpt.t;
3256						if (!pt.type) {
3257							pt[p] = pt.s + pt.xs0;
3258						} else if (pt.type === 1) {
3259							str = pt.xs0 + pt.s + pt.xs1;
3260							for (i = 1; i < pt.l; i++) {
3261								str += pt["xn"+i] + pt["xs"+(i+1)];
3262							}
3263							pt[p] = str;
3264						}
3265						mpt = mpt._next;
3266					}
3267				}
3268			},
3269
3270			/**
3271			 * @private @constructor Used by a few SpecialProps to hold important values for proxies. For example, _parseToProxy() creates a MiniPropTween instance for each property that must get tweened on the proxy, and we record the original property name as well as the unique one we create for the proxy, plus whether or not the value needs to be rounded plus the original value.
3272			 * @param {!Object} t target object whose property we're tweening (often a CSSPropTween)
3273			 * @param {!string} p property name
3274			 * @param {(number|string|object)} v value
3275			 * @param {MiniPropTween=} next next MiniPropTween in the linked list
3276			 * @param {boolean=} r if true, the tweened value should be rounded to the nearest integer
3277			 */
3278			MiniPropTween = function(t, p, v, next, r) {
3279				this.t = t;
3280				this.p = p;
3281				this.v = v;
3282				this.r = r;
3283				if (next) {
3284					next._prev = this;
3285					this._next = next;
3286				}
3287			},
3288
3289			/**
3290			 * @private Most other plugins (like BezierPlugin and ThrowPropsPlugin and others) can only tween numeric values, but CSSPlugin must accommodate special values that have a bunch of extra data (like a suffix or strings between numeric values, etc.). For example, boxShadow has values like "10px 10px 20px 30px rgb(255,0,0)" which would utterly confuse other plugins. This method allows us to split that data apart and grab only the numeric data and attach it to uniquely-named properties of a generic proxy object ({}) so that we can feed that to virtually any plugin to have the numbers tweened. However, we must also keep track of which properties from the proxy go with which CSSPropTween values and instances. So we create a linked list of MiniPropTweens. Each one records a target (the original CSSPropTween), property (like "s" or "xn1" or "xn2") that we're tweening and the unique property name that was used for the proxy (like "boxShadow_xn1" and "boxShadow_xn2") and whether or not they need to be rounded. That way, in the _setPluginRatio() method we can simply copy the values over from the proxy to the CSSPropTween instance(s). Then, when the main CSSPlugin setRatio() method runs and applies the CSSPropTween values accordingly, they're updated nicely. So the external plugin tweens the numbers, _setPluginRatio() copies them over, and setRatio() acts normally, applying css-specific values to the element.
3291			 * This method returns an object that has the following properties:
3292			 *  - proxy: a generic object containing the starting values for all the properties that will be tweened by the external plugin.  This is what we feed to the external _onInitTween() as the target
3293			 *  - end: a generic object containing the ending values for all the properties that will be tweened by the external plugin. This is what we feed to the external plugin's _onInitTween() as the destination values
3294			 *  - firstMPT: the first MiniPropTween in the linked list
3295			 *  - pt: the first CSSPropTween in the linked list that was created when parsing. If shallow is true, this linked list will NOT attach to the one passed into the _parseToProxy() as the "pt" (4th) parameter.
3296			 * @param {!Object} t target object to be tweened
3297			 * @param {!(Object|string)} vars the object containing the information about the tweening values (typically the end/destination values) that should be parsed
3298			 * @param {!CSSPlugin} cssp The CSSPlugin instance
3299			 * @param {CSSPropTween=} pt the next CSSPropTween in the linked list
3300			 * @param {TweenPlugin=} plugin the external TweenPlugin instance that will be handling tweening the numeric values
3301			 * @param {boolean=} shallow if true, the resulting linked list from the parse will NOT be attached to the CSSPropTween that was passed in as the "pt" (4th) parameter.
3302			 * @return An object containing the following properties: proxy, end, firstMPT, and pt (see above for descriptions)
3303			 */
3304			_parseToProxy = _internals._parseToProxy = function(t, vars, cssp, pt, plugin, shallow) {
3305				var bpt = pt,
3306					start = {},
3307					end = {},
3308					transform = cssp._transform,
3309					oldForce = _forcePT,
3310					i, p, xp, mpt, firstPT;
3311				cssp._transform = null;
3312				_forcePT = vars;
3313				pt = firstPT = cssp.parse(t, vars, pt, plugin);
3314				_forcePT = oldForce;
3315				//break off from the linked list so the new ones are isolated.
3316				if (shallow) {
3317					cssp._transform = transform;
3318					if (bpt) {
3319						bpt._prev = null;
3320						if (bpt._prev) {
3321							bpt._prev._next = null;
3322						}
3323					}
3324				}
3325				while (pt && pt !== bpt) {
3326					if (pt.type <= 1) {
3327						p = pt.p;
3328						end[p] = pt.s + pt.c;
3329						start[p] = pt.s;
3330						if (!shallow) {
3331							mpt = new MiniPropTween(pt, "s", p, mpt, pt.r);
3332							pt.c = 0;
3333						}
3334						if (pt.type === 1) {
3335							i = pt.l;
3336							while (--i > 0) {
3337								xp = "xn" + i;
3338								p = pt.p + "_" + xp;
3339								end[p] = pt.data[xp];
3340								start[p] = pt[xp];
3341								if (!shallow) {
3342									mpt = new MiniPropTween(pt, xp, p, mpt, pt.rxp[xp]);
3343								}
3344							}
3345						}
3346					}
3347					pt = pt._next;
3348				}
3349				return {proxy:start, end:end, firstMPT:mpt, pt:firstPT};
3350			},
3351
3352
3353
3354			/**
3355			 * @constructor Each property that is tweened has at least one CSSPropTween associated with it. These instances store important information like the target, property, starting value, amount of change, etc. They can also optionally have a number of "extra" strings and numeric values named xs1, xn1, xs2, xn2, xs3, xn3, etc. where "s" indicates string and "n" indicates number. These can be pieced together in a complex-value tween (type:1) that has alternating types of data like a string, number, string, number, etc. For example, boxShadow could be "5px 5px 8px rgb(102, 102, 51)". In that value, there are 6 numbers that may need to tween and then pieced back together into a string again with spaces, suffixes, etc. xs0 is special in that it stores the suffix for standard (type:0) tweens, -OR- the first string (prefix) in a complex-value (type:1) CSSPropTween -OR- it can be the non-tweening value in a type:-1 CSSPropTween. We do this to conserve memory.
3356			 * CSSPropTweens have the following optional properties as well (not defined through the constructor):
3357			 *  - l: Length in terms of the number of extra properties that the CSSPropTween has (default: 0). For example, for a boxShadow we may need to tween 5 numbers in which case l would be 5; Keep in mind that the start/end values for the first number that's tweened are always stored in the s and c properties to conserve memory. All additional values thereafter are stored in xn1, xn2, etc.
3358			 *  - xfirst: The first instance of any sub-CSSPropTweens that are tweening properties of this instance. For example, we may split up a boxShadow tween so that there's a main CSSPropTween of type:1 that has various xs* and xn* values associated with the h-shadow, v-shadow, blur, color, etc. Then we spawn a CSSPropTween for each of those that has a higher priority and runs BEFORE the main CSSPropTween so that the values are all set by the time it needs to re-assemble them. The xfirst gives us an easy way to identify the first one in that chain which typically ends at the main one (because they're all prepende to the linked list)
3359			 *  - plugin: The TweenPlugin instance that will handle the tweening of any complex values. For example, sometimes we don't want to use normal subt
3359weens (like xfirst refers to) to tween the values - we might want ThrowPropsPlugin or BezierPlugin some other plugin to do the actual tweening, so we create a plugin instance and store a reference here. We need this reference so that if we get a request to round values or disable a tween, we can pass along that request.
3360			 *  - data: Arbitrary data that needs to be stored with the CSSPropTween. Typically if we're going to have a plugin handle the tweening of a complex-value tween, we create a generic object that stores the END values that we're tweening to and the CSSPropTween's xs1, xs2, etc. have the starting values. We store that object as data. That way, we can simply pass that object to the plugin and use the CSSPropTween as the target.
3361			 *  - setRatio: Only used for type:2 tweens that require custom functionality. In this case, we call the CSSPropTween's setRatio() method and pass the ratio each time the tween updates. This isn't quite as efficient as doing things directly in the CSSPlugin's setRatio() method, but it's very convenient and flexible.
3362			 * @param {!Object} t Target object whose property will be tweened. Often a DOM element, but not always. It could be anything.
3363			 * @param {string} p Property to tween (name). For example, to tween element.width, p would be "width".
3364			 * @param {number} s Starting numeric value
3365			 * @param {number} c Change in numeric value over the course of the entire tween. For example, if element.width starts at 5 and should end at 100, c would be 95.
3366			 * @param {CSSPropTween=} next The next CSSPropTween in the linked list. If one is defined, we will define its _prev as the new instance, and the new instance's _next will be pointed at it.
3367			 * @param {number=} type The type of CSSPropTween where -1 = a non-tweening value, 0 = a standard simple tween, 1 = a complex value (like one that has multiple numbers in a comma- or space-delimited string like border:"1px solid red"), and 2 = one that uses a custom setRatio function that does all of the work of applying the values on each update.
3368			 * @param {string=} n Name of the property that should be used for overwriting purposes which is typically the same as p but not always. For example, we may need to create a subtween for the 2nd part of a "clip:rect(...)" tween in which case "p" might be xs1 but "n" is still "clip"
3369			 * @param {boolean=} r If true, the value(s) should be rounded
3370			 * @param {number=} pr Priority in the linked list order. Higher priority CSSPropTweens will be updated before lower priority ones. The default priority is 0.
3371			 * @param {string=} b Beginning value. We store this to ensure that it is EXACTLY what it was when the tween began without any risk of interpretation issues.
3372			 * @param {string=} e Ending value. We store this to ensure that it is EXACTLY what the user defined at the end of the tween without any risk of interpretation issues.
3373			 */
3374			CSSPropTween = _internals.CSSPropTween = function(t, p, s, c, next, type, n, r, pr, b, e) {
3375				this.t = t; //target
3376				this.p = p; //property
3377				this.s = s; //starting value
3378				this.c = c; //change value
3379				this.n = n || p; //name that this CSSPropTween should be associated to (usually the same as p, but not always - n is what overwriting looks at)
3380				if (!(t instanceof CSSPropTween)) {
3381					_overwriteProps.push(this.n);
3382				}
3383				this.r = !r ? r : (typeof(r) === "function") ? r : Math.round; //round (boolean)
3384				this.type = type || 0; //0 = normal tween, -1 = non-tweening (in which case xs0 will be applied to the target's property, like tp.t[tp.p] = tp.xs0), 1 = complex-value SpecialProp, 2 = custom setRatio() that does all the work
3385				if (pr) {
3386					this.pr = pr;
3387					_hasPriority = true;
3388				}
3389				this.b = (b === undefined) ? s : b;
3390				this.e = (e === undefined) ? s + c : e;
3391				if (next) {
3392					this._next = next;
3393					next._prev = this;
3394				}
3395			},
3396
3397			_addNonTweeningNumericPT = function(target, prop, start, end, next, overwriteProp) { //cleans up some code redundancies and helps minification. Just a fast way to add a NUMERIC non-tweening CSSPropTween
3398				var pt = new CSSPropTween(target, prop, start, end - start, next, -1, overwriteProp);
3399				pt.b = start;
3400				pt.e = pt.xs0 = end;
3401				return pt;
3402			},
3403
3404			/**
3405			 * Takes a target, the beginning value and ending value (as strings) and parses them into a CSSPropTween (possibly with child CSSPropTweens) that accommodates multiple numbers, colors, comma-delimited values, etc. For example:
3406			 * sp.parseComplex(element, "boxShadow", "5px 10px 20px rgb(255,102,51)", "0px 0px 0px red", true, "0px 0px 0px rgb(0,0,0,0)", pt);
3407			 * It will walk through the beginning and ending values (which should be in the same format with the same number and type of values) and figure out which parts are numbers, what strings separate the numeric/tweenable values, and then create the CSSPropTweens accordingly. If a plugin is defined, no child CSSPropTweens will be created. Instead, the ending values will be stored in the "data" property of the returned CSSPropTween like: {s:-5, xn1:-10, xn2:-20, xn3:255, xn4:0, xn5:0} so that it can be fed to any other plugin and it'll be plain numeric tweens but the recomposition of the complex value will be handled inside CSSPlugin's setRatio().
3408			 * If a setRatio is defined, the type of the CSSPropTween will be set to 2 and recomposition of the values will be the responsibility of that method.
3409			 *
3410			 * @param {!Object} t Target whose property will be tweened
3411			 * @param {!string} p Property that will be tweened (its name, like "left" or "backgroundColor" or "boxShadow")
3412			 * @param {string} b Beginning value
3413			 * @param {string} e Ending value
3414			 * @param {boolean} clrs If true, the value could contain a color value like "rgb(255,0,0)" or "#F00" or "red". The default is false, so no colors will be recognized (a performance optimization)
3415			 * @param {(string|number|Object)} dflt The default beginning value that should be used if no valid beginning value is defined or if the number of values inside the complex beginning and ending values don't match
3416			 * @param {?CSSPropTween} pt CSSPropTween instance that is the current head of the linked list (we'll prepend to this).
3417			 * @param {number=} pr Priority in the linked list order. Higher priority properties will be updated before lower priority ones. The default priority is 0.
3418			 * @param {TweenPlugin=} plugin If a plugin should handle the tweening of extra properties, pass the plugin instance here. If one is defined, then NO subtweens will be created for any extra properties (the properties will be created - just not additional CSSPropTween instances to tween them) because the plugin is expected to do so. However, the end values WILL be populated in the "data" property, like {s:100, xn1:50, xn2:300}
3419			 * @param {function(number)=} setRatio If values should be set in a custom function instead of being pieced together in a type:1 (complex-value) CSSPropTween, define that custom function here.
3420			 * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parseComplex() call.
3421			 */
3422			_parseComplex = CSSPlugin.parseComplex = function(t, p, b, e, clrs, dflt, pt, pr, plugin, setRatio) {
3423				//DEBUG: _log("parseComplex: "+p+", b: "+b+", e: "+e);
3424				b = b || dflt || "";
3425				if (typeof(e) === "function") {
3426					e = e(_index, _target);
3427				}
3428				pt = new CSSPropTween(t, p, 0, 0, pt, (setRatio ? 2 : 1), null, false, pr, b, e);
3429				e += ""; //ensures it's a string
3430				if (clrs && _colorExp.test(e + b)) { //if colors are found, normalize the formatting to rgba() or hsla().
3431					e = [b, e];
3432					CSSPlugin.colorStringFilter(e);
3433					b = e[0];
3434					e = e[1];
3435				}
3436				var ba = b.split(", ").join(",").split(" "), //beginning array
3437					ea = e.split(", ").join(",").split(" "), //ending array
3438					l = ba.length,
3439					autoRound = (_autoRound !== false),
3440					i, xi, ni, bv, ev, bnums, enums, bn, hasAlpha, temp, cv, str, useHSL;
3441				if (e.indexOf(",") !== -1 || b.indexOf(",") !== -1) {
3442					if ((e + b).indexOf("rgb") !== -1 || (e + b).indexOf("hsl") !== -1) { //keep rgb(), rgba(), hsl(), and hsla() values together! (remember, we're splitting on spaces)
3443						ba = ba.join(" ").replace(_commasOutsideParenExp, ", ").split(" ");
3444						ea = ea.join(" ").replace(_commasOutsideParenExp, ", ").split(" ");
3445					} else {
3446						ba = ba.join(" ").split(",").join(", ").split(" ");
3447						ea = ea.join(" ").split(",").join(", ").split(" ");
3448					}
3449					l = ba.length;
3450				}
3451				if (l !== ea.length) {
3452					//DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")");
3453					ba = (dflt || "").split(" ");
3454					l = ba.length;
3455				}
3456				pt.plugin = plugin;
3457				pt.setRatio = setRatio;
3458				_colorExp.lastIndex = 0;
3459				for (i = 0; i < l; i++) {
3460					bv = ba[i];
3461					ev = ea[i] + "";
3462					bn = parseFloat(bv);
3463					//if the value begins with a number (most common). It's fine if it has a suffix like px
3464					if (bn || bn === 0) {
3465						pt.appendXtra("", bn, _parseChange(ev, bn), ev.replace(_relNumExp, ""), (autoRound && ev.indexOf("px") !== -1) ? Math.round : false, true);
3466
3467					//if the value is a color
3468					} else if (clrs && _colorExp.test(bv)) {
3469						str = ev.indexOf(")") + 1;
3470						str = ")" + (str ? ev.substr(str) : ""); //if there's a comma or ) at the end, retain it.
3471						useHSL = (ev.indexOf("hsl") !== -1 && _supportsOpacity);
3472						temp = ev; //original string value so we can look for any prefix later.
3473						bv = _parseColor(bv, useHSL);
3474						ev = _parseColor(ev, useHSL);
3475						hasAlpha = (bv.length + ev.length > 6);
3476						if (hasAlpha && !_supportsOpacity && ev[3] === 0) { //older versions of IE don't support rgba(), so if the destination alpha is 0, just use "transparent" for the end color
3477							pt["xs" + pt.l] += pt.l ? " transparent" : "transparent";
3478							pt.e = pt.e.split(ea[i]).join("transparent");
3479						} else {
3480							if (!_supportsOpacity) { //old versions of IE don't support rgba().
3481								hasAlpha = false;
3482							}
3483							if (useHSL) {
3484								pt.appendXtra(temp.substr(0, temp.indexOf("hsl")) + (hasAlpha ? "hsla(" : "hsl("), bv[0], _parseChange(ev[0], bv[0]), ",", false, true)
3485									.appendXtra("", bv[1], _parseChange(ev[1], bv[1]), "%,", false)
3486									.appendXtra("", bv[2], _parseChange(ev[2], bv[2]), (hasAlpha ? "%," : "%" + str), false);
3487							} else {
3488								pt.appendXtra(temp.substr(0, temp.indexOf("rgb")) + (hasAlpha ? "rgba(" : "rgb("), bv[0], ev[0] - bv[0], ",", Math.round, true)
3489									.appendXtra("", bv[1], ev[1] - bv[1], ",", Math.round)
3490									.appendXtra("", bv[2], ev[2] - bv[2], (hasAlpha ? "," : str), Math.round);
3491							}
3492
3493							if (hasAlpha) {
3494								bv = (bv.length < 4) ? 1 : bv[3];
3495								pt.appendXtra("", bv, ((ev.length < 4) ? 1 : ev[3]) - bv, str, false);
3496							}
3497						}
3498						_colorExp.lastIndex = 0; //otherwise the test() on the RegExp could move the lastIndex and taint future results.
3499
3500					} else {
3501						bnums = bv.match(_numExp); //gets each group of numbers in the beginning value string and drops them into an array
3502
3503						//if no number is found, treat it as a non-tweening value and just append the string to the current xs.
3504						if (!bnums) {
3505							pt["xs" + pt.l] += (pt.l || pt["xs" + pt.l]) ? " " + ev : ev;
3506
3507						//loop through all the numbers that are found and construct the extra values on the pt.
3508						} else {
3509							enums = ev.match(_relNumExp); //get each group of numbers in the end value string and drop them into an array. We allow relative values too, like +=50 or -=.5
3510							if (!enums || enums.length !== bnums.length) {
3511								//DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")");
3512								return pt;
3513							}
3514							ni = 0;
3515							for (xi = 0; xi < bnums.length; xi++) {
3516								cv = bnums[xi];
3517								temp = bv.indexOf(cv, ni);
3518								pt.appendXtra(bv.substr(ni, temp - ni), Number(cv), _parseChange(enums[xi], cv), "", (autoRound && bv.substr(temp + cv.length, 2) === "px") ? Math.round : false, (xi === 0));
3519								ni = temp + cv.length;
3520							}
3521							pt["xs" + pt.l] += bv.substr(ni);
3522						}
3523					}
3524				}
3525				//if there are relative values ("+=" or "-=" prefix), we need to adjust the ending value to eliminate the prefixes and combine the values properly.
3526				if (e.indexOf("=") !== -1) if (pt.data) {
3527					str = pt.xs0 + pt.data.s;
3528					for (i = 1; i < pt.l; i++) {
3529						str += pt["xs" + i] + pt.data["xn" + i];
3530					}
3531					pt.e = str + pt["xs" + i];
3532				}
3533				if (!pt.l) {
3534					pt.type = -1;
3535					pt.xs0 = pt.e;
3536				}
3537				return pt.xfirst || pt;
3538			},
3539			i = 9;
3540
3541
3542		p = CSSPropTween.prototype;
3543		p.l = p.pr = 0; //length (number of extra properties like xn1, xn2, xn3, etc.
3544		while (--i > 0) {
3545			p["xn" + i] = 0;
3546			p["xs" + i] = "";
3547		}
3548		p.xs0 = "";
3549		p._next = p._prev = p.xfirst = p.data = p.plugin = p.setRatio = p.rxp = null;
3550
3551
3552		/**
3553		 * Appends and extra tweening value to a CSSPropTween and automatically manages any prefix and suffix strings. The first extra value is stored in the s and c of the main CSSPropTween instance, but thereafter any extras are stored in the xn1, xn2, xn3, etc. The prefixes and suffixes are stored in the xs0, xs1, xs2, etc. properties. For example, if I walk through a clip value like "rect(10px, 5px, 0px, 20px)", the values would be stored like this:
3554		 * xs0:"rect(", s:10, xs1:"px, ", xn1:5, xs2:"px, ", xn2:0, xs3:"px, ", xn3:20, xn4:"px)"
3555		 * And they'd all get joined together when the CSSPlugin renders (in the setRatio() method).
3556		 * @param {string=} pfx Prefix (if any)
3557		 * @param {!number} s Starting value
3558		 * @param {!number} c Change in numeric value over the course of the entire tween. For example, if the start is 5 and the end is 100, the change would be 95.
3559		 * @param {string=} sfx Suffix (if any)
3560		 * @param {boolean=} r Round (if true).
3561		 * @param {boolean=} pad If true, this extra value should be separated by the previous one by a space. If there is no previous extra and pad is true, it will automatically drop the space.
3562		 * @return {CSSPropTween} returns itself so that multiple methods can be chained together.
3563		 */
3564		p.appendXtra = function(pfx, s, c, sfx, r, pad) {
3565			var pt = this,
3566				l = pt.l;
3567			pt["xs" + l] += (pad && (l || pt["xs" + l])) ? " " + pfx : pfx || "";
3568			if (!c) if (l !== 0 && !pt.plugin) { //typically we'll combine non-changing values right into the xs to optimize performance, but we don't combine them when there's a plugin that will be tweening the values because it may depend on the values being split apart, like for a bezier, if a value doesn't change between the first and second iteration but then it does on the 3rd, we'll run into trouble because there's no xn slot for that value!
3569				pt["xs" + l] += s + (sfx || "");
3570				return pt;
3571			}
3572			pt.l++;
3573			pt.type = pt.setRatio ? 2 : 1;
3574			pt["xs" + pt.l] = sfx || "";
3575			if (l > 0) {
3576				pt.data["xn" + l] = s + c;
3577				pt.rxp["xn" + l] = r; //round extra property (we need to tap into this in the _parseToProxy() method)
3578				pt["xn" + l] = s;
3579				if (!pt.plugin) {
3580					pt.xfirst = new CSSPropTween(pt, "xn" + l, s, c, pt.xfirst || pt, 0, pt.n, r, pt.pr);
3581					pt.xfirst.xs0 = 0; //just to ensure that the property stays numeric which helps modern browsers speed up processing. Remember, in the setRatio() method, we do pt.t[pt.p] = val + pt.xs0 so if pt.xs0 is "" (the default), it'll cast the end value as a string. When a property is a number sometimes and a string sometimes, it prevents the compiler from locking in the data type, slowing things down slightly.
3582				}
3583				return pt;
3584			}
3585			pt.data = {s:s + c};
3586			pt.rxp = {};
3587			pt.s = s;
3588			pt.c = c;
3589			pt.r = r;
3590			return pt;
3591		};
3592
3593		/**
3594		 * @constructor A SpecialProp is basically a css property that needs to be treated in a non-standard way, like if it may contain a complex value like boxShadow:"5px 10px 15px rgb(255, 102, 51)" or if it is associated with another plugin like ThrowPropsPlugin or BezierPlugin. Every SpecialProp is associated with a particular property name like "boxShadow" or "throwProps" or "bezier" and it will intercept those values in the vars object that's passed to the CSSPlugin and handle them accordingly.
3595		 * @param {!string} p Property name (like "boxShadow" or "throwProps")
3596		 * @param {Object=}
3596 options An object containing any of the following configuration options:
3597		 *                      - defaultValue: the default value
3598		 *                      - parser: A function that should be called when the associated property name is found in the vars. This function should return a CSSPropTween instance and it should ensure that it is properly inserted into the linked list. It will receive 4 paramters: 1) The target, 2) The value defined in the vars, 3) The CSSPlugin instance (whose _firstPT should be used for the linked list), and 4) A computed style object if one was calculated (this is a speed optimization that allows retrieval of starting values quicker)
3599		 *                      - formatter: a function that formats any value received for this special property (for example, boxShadow could take "5px 5px red" and format it to "5px 5px 0px 0px red" so that both the beginning and ending values have a common order and quantity of values.)
3600		 *                      - prefix: if true, we'll determine whether or not this property requires a vendor prefix (like Webkit or Moz or ms or O)
3601		 *                      - color: set this to true if the value for this SpecialProp may contain color-related values like rgb(), rgba(), etc.
3602		 *                      - priority: priority in the linked list order. Higher priority SpecialProps will be updated before lower priority ones. The default priority is 0.
3603		 *                      - multi: if true, the formatter should accommodate a comma-delimited list of values, like boxShadow could have multiple boxShadows listed out.
3604		 *                      - collapsible: if true, the formatter should treat the value like it's a top/right/bottom/left value that could be collapsed, like "5px" would apply to all, "5px, 10px" would use 5px for top/bottom and 10px for right/left, etc.
3605		 *                      - keyword: a special keyword that can [optionally] be found inside the value (like "inset" for boxShadow). This allows us to validate beginning/ending values to make sure they match (if the keyword is found in one, it'll be added to the other for consistency by default).
3606		 */
3607		var SpecialProp = function(p, options) {
3608				options = options || {};
3609				this.p = options.prefix ? _checkPropPrefix(p) || p : p;
3610				_specialProps[p] = _specialProps[this.p] = this;
3611				this.format = options.formatter || _getFormatter(options.defaultValue, options.color, options.collapsible, options.multi);
3612				if (options.parser) {
3613					this.parse = options.parser;
3614				}
3615				this.clrs = options.color;
3616				this.multi = options.multi;
3617				this.keyword = options.keyword;
3618				this.dflt = options.defaultValue;
3619				this.pr = options.priority || 0;
3620			},
3621
3622			//shortcut for creating a new SpecialProp that can accept multiple properties as a comma-delimited list (helps minification). dflt can be an array for multiple values (we don't do a comma-delimited list because the default value may contain commas, like rect(0px,0px,0px,0px)). We attach this method to the SpecialProp class/object instead of using a private _createSpecialProp() method so that we can tap into it externally if necessary, like from another plugin.
3623			_registerComplexSpecialProp = _internals._registerComplexSpecialProp = function(p, options, defaults) {
3624				if (typeof(options) !== "object") {
3625					options = {parser:defaults}; //to make backwards compatible with older versions of BezierPlugin and ThrowPropsPlugin
3626				}
3627				var a = p.split(","),
3628					d = options.defaultValue,
3629					i, temp;
3630				defaults = defaults || [d];
3631				for (i = 0; i < a.length; i++) {
3632					options.prefix = (i === 0 && options.prefix);
3633					options.defaultValue = defaults[i] || d;
3634					temp = new SpecialProp(a[i], options);
3635				}
3636			},
3637
3638			//creates a placeholder special prop for a plugin so that the property gets caught the first time a tween of it is attempted, and at that time it makes the plugin register itself, thus taking over for all future tweens of that property. This allows us to not mandate that things load in a particular order and it also allows us to log() an error that informs the user when they attempt to tween an external plugin-related property without loading its .js file.
3639			_registerPluginProp = _internals._registerPluginProp = function(p) {
3640				if (!_specialProps[p]) {
3641					var pluginName = p.charAt(0).toUpperCase() + p.substr(1) + "Plugin";
3642					_registerComplexSpecialProp(p, {parser:function(t, e, p, cssp, pt, plugin, vars) {
3643						var pluginClass = _globals.com.greensock.plugins[pluginName];
3644						if (!pluginClass) {
3645							_log("Error: " + pluginName + " js file not loaded.");
3646							return pt;
3647						}
3648						pluginClass._cssRegister();
3649						return _specialProps[p].parse(t, e, p, cssp, pt, plugin, vars);
3650					}});
3651				}
3652			};
3653
3654
3655		p = SpecialProp.prototype;
3656
3657		/**
3658		 * Alias for _parseComplex() that automatically plugs in certain values for this SpecialProp, like its property name, whether or not colors should be sensed, the default value, and priority. It also looks for any keyword that the SpecialProp defines (like "inset" for boxSh
3658adow) and ensures that the beginning and ending values have the same number of values for SpecialProps where multi is true (like boxShadow and textShadow can have a comma-delimited list)
3659		 * @param {!Object} t target element
3660		 * @param {(string|number|object)} b beginning value
3661		 * @param {(string|number|object)} e ending (destination) value
3662		 * @param {CSSPropTween=} pt next CSSPropTween in the linked list
3663		 * @param {TweenPlugin=} plugin If another plugin will be tweening the complex value, that TweenPlugin instance goes here.
3664		 * @param {function=} setRatio If a custom setRatio() method should be used to handle this complex value, that goes here.
3665		 * @return {CSSPropTween=} First CSSPropTween in the linked list
3666		 */
3667		p.parseComplex = function(t, b, e, pt, plugin, setRatio) {
3668			var kwd = this.keyword,
3669				i, ba, ea, l, bi, ei;
3670			//if this SpecialProp's value can contain a comma-delimited list of values (like boxShadow or textShadow), we must parse them in a special way, and look for a keyword (like "inset" for boxShadow) and ensure that the beginning and ending BOTH have it if the end defines it as such. We also must ensure that there are an equal number of values specified (we can't tween 1 boxShadow to 3 for example)
3671			if (this.multi) if (_commasOutsideParenExp.test(e) || _commasOutsideParenExp.test(b)) {
3672				ba = b.replace(_commasOutsideParenExp, "|").split("|");
3673				ea = e.replace(_commasOutsideParenExp, "|").split("|");
3674			} else if (kwd) {
3675				ba = [b];
3676				ea = [e];
3677			}
3678			if (ea) {
3679				l = (ea.length > ba.length) ? ea.length : ba.length;
3680				for (i = 0; i < l; i++) {
3681					b = ba[i] = ba[i] || this.dflt;
3682					e = ea[i] = ea[i] || this.dflt;
3683					if (kwd) {
3684						bi = b.indexOf(kwd);
3685						ei = e.indexOf(kwd);
3686						if (bi !== ei) {
3687							if (ei === -1) { //if the keyword isn't in the end value, remove it from the beginning one.
3688								ba[i] = ba[i].split(kwd).join("");
3689							} else if (bi === -1) { //if the keyword isn't in the beginning, add it.
3690								ba[i] += " " + kwd;
3691							}
3692						}
3693					}
3694				}
3695				b = ba.join(", ");
3696				e = ea.join(", ");
3697			}
3698			return _parseComplex(t, this.p, b, e, this.clrs, this.dflt, pt, this.pr, plugin, setRatio);
3699		};
3700
3701		/**
3702		 * Accepts a target and end value and spits back a CSSPropTween that has been inserted into the CSSPlugin's linked list and conforms with all the conventions we use internally, like type:-1, 0, 1, or 2, setting up any extra property tweens, priority, etc. For example, if we have a boxShadow SpecialProp and call:
3703		 * this._firstPT = sp.parse(element, "5px 10px 20px rgb(2550,102,51)", "boxShadow", this);
3704		 * It should figure out the starting value of the element's boxShadow, compare it to the provided end value and create all the necessary CSSPropTweens of the appropriate types to tween the boxShadow. The CSSPropTween that gets spit back should already be inserted into the linked list (the 4th parameter is the current head, so prepend to that).
3705		 * @param {!Object} t Target object whose property is being tweened
3706		 * @param {Object} e End value as provided in the vars object (typically a string, but not always - like a throwProps would be an object).
3707		 * @param {!string} p Property name
3708		 * @param {!CSSPlugin} cssp The CSSPlugin instance that should be associated with this tween.
3709		 * @param {?CSSPropTween} pt The CSSPropTween that is the current head of the linked list (we'll prepend to it)
3710		 * @param {TweenPlugin=} plugin If a plugin will be used to tween the parsed value, this is the plugin instance.
3711		 * @param {Object=} vars Original vars object that contains the data for parsing.
3712		 * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parse() call.
3713		 */
3714		p.parse = function(t, e, p, cssp, pt, plugin, vars) {
3715			return this.parseComplex(t.style, this.format(_getStyle(t, this.p, _cs, false, this.dflt)), this.format(e), pt, plugin);
3716		};
3717
3718		/**
3719		 * Registers a special property that should be intercepted from any "css" objects defined in tweens. This allows you to handle them however you want without CSSPlugin doing it for you. The 2nd parameter should be a function that accepts 3 parameters:
3720		 *  1) Target object whose property should be tweened (typically a DOM element)
3721		 *  2) The end/destination value (could be a string, number, object, or whatever you want)
3722		 *  3) The tween instance (you probably don't need to worry about this, but it can be useful for looking up information like the duration)
3723		 *
3724		 * Then, your function should return a function which will be called each time the tween gets rendered, passing a numeric "ratio" parameter to your function that indicates the change factor (usually between 0 and 1). For example:
3725		 *
3726		 * CSSPlugin.registerSpecialProp("myCustomProp", function(target, value, tween) {
3727		 *      var start = target.style.width;
3728		 *      return function(ratio) {
3729		 *              target.style.width = (start + value * ratio) + "px";
3730		 *              console.log("set width to " + target.style.width);
3731		 *          }
3732		 * }, 0);
3733		 *
3734		 * Then, when I do this tween, it will trigger my special property:
3735		 *
3736		 * TweenLite.to(element, 1, {css:{myCustomProp:100}});
3737		 *
3738		 * In the example, of course, we're just changing the width, but you can do anything you want.
3739		 *
3740		 * @param {!string} name Property name (or comma-delimited list of property names) that should be intercepted and handled by your function. For example, if I define "myCustomProp", then it would handle that portion of the following tween: TweenLite.to(element, 1, {css:{myCustomProp:100}})
3741		 * @param {!function(Object, Object, Object, string):function(number)} onInitTween The function that will be called when a tween of this special property is performed. The function will receive 4 parameters: 1) Target object that should be tweened, 2) Value that was passed to the tween, 3) The tween instance itself (rarely used), and 4) The property name that's being tweened. Your function should return a function that should be called on every update of the tween. That function will receive a single parameter that is a "change factor" value (typically between 0 and 1) indicating the amount of change as a ratio. You can use this to determine how to set the values appropriately in your function.
3742		 * @param {number=} priority Priority that helps the engine determine the order in which to set the properties (default: 0). Higher priority properties will be updated before lower priority ones.
3743		 */
3744		CSSPlugin.registerSpecialProp = function(name, onInitTween, priority) {
3745			_registerComplexSpecialProp(name, {parser:function(t, e, p, cssp, pt, plugin, vars) {
3746				var rv = new CSSPropTween(t, p, 0, 0, pt, 2, p, false, priority);
3747				rv.plugin = plugin;
3748				rv.setRatio = onInitTween(t, e, cssp._tween, p);
3749				return rv;
3750			}, priority:priority});
3751		};
3752
3753
3754
3755
3756
3757
3758		//transform-related methods and properties
3759		CSSPlugin.useSVGTransformAttr = true; //Safari and Firefox both have some rendering bugs when applying CSS transforms to SVG elements, so default to using the "transform" attribute instead (users can override this).
3760		var _transformProps = ("scaleX,scaleY,scaleZ,x,y,z,skewX,skewY,rotation,rotationX,rotationY,perspective,xPercent,yPercent").split(","),
3761			_transformProp = _checkPropPrefix("transform"), //the Javascript (camelCase) transform property, like msTransform, WebkitTransform, MozTransform, or OTransform.
3762			_transformPropCSS = _prefixCSS + "transform",
3763			_transformOriginProp = _checkPropPrefix("transformOrigin"),
3764			_supports3D = (_checkPropPrefix("perspective") !== null),
3765			Transform = _internals.Transform = function() {
3766				this.perspective = parseFloat(CSSPlugin.defaultTransformPerspective) || 0;
3767				this.force3D = (CSSPlugin.defaultForce3D === false || !_supports3D) ? false : CSSPlugin.defaultForce3D || "auto";
3768			},
3769			_SVGElement = _gsScope.SVGElement,
3770			_useSVGTransformAttr,
3771			//Some browsers (like Firefox and IE) don't honor transform-origin properly in SVG elements, so we need to manually adjust the matrix accordingly. We feature detect here rather than always doing the conversion for certain browsers because they may fix the problem at some point in the future.
3772
3773			_createSVG = function(type, container, attributes) {
3774				var element = _doc.createElementNS("http://www.w3.org/2000/svg", type),
3775					reg = /([a-z])([A-Z])/g,
3776					p;
3777				for (p in attributes) {
3778					element.setAttributeNS(null, p.replace(reg, "$1-$2").toLowerCase(), attributes[p]);
3779				}
3780				container.appendChild(element);
3781				return element;
3782			},
3783			_docElement = _doc.documentElement || {},
3784			_forceSVGTransformAttr = (function() {
3785				//IE and Android stock don't support CSS transforms on SVG elements, so we must write them to the "transform" attribute. We populate this variable in the _parseTransform() method, and only if/when we come across an SVG element
3786				var force = _ieVers || (/Android/i.test(_agent) && !_gsScope.chrome),
3787					svg, rect, width;
3788				if (_doc.createElementNS && !force) { //IE8 and earlier doesn't support SVG anyway
3789					svg = _createSVG("svg", _docElement);
3790					rect = _createSVG("rect", svg, {width:100, height:50, x:100});
3791					width = rect.getBoundingClientRect().width;
3792					rect.style[_transformOriginProp] = "50% 50%";
3793					rect.style[_transformProp] = "scaleX(0.5)";
3794					force = (width === rect.getBoundingClientRect().width && !(_is
3794Firefox && _supports3D)); //note: Firefox fails the test even though it does support CSS transforms in 3D. Since we can't push 3D stuff into the transform attribute, we force Firefox to pass the test here (as long as it does truly support 3D).
3795					_docElement.removeChild(svg);
3796				}
3797				return force;
3798			})(),
3799			_parseSVGOrigin = function(e, local, decoratee, absolute, smoothOrigin, skipRecord) {
3800				var tm = e._gsTransform,
3801					m = _getMatrix(e, true),
3802					v, x, y, xOrigin, yOrigin, a, b, c, d, tx, ty, determinant, xOriginOld, yOriginOld;
3803				if (tm) {
3804					xOriginOld = tm.xOrigin; //record the original values before we alter them.
3805					yOriginOld = tm.yOrigin;
3806				}
3807				if (!absolute || (v = absolute.split(" ")).length < 2) {
3808					b = e.getBBox();
3809					if (b.x === 0 && b.y === 0 && b.width + b.height === 0) { //some browsers (like Firefox) misreport the bounds if the element has zero width and height (it just assumes it's at x:0, y:0), thus we need to manually grab the position in that case.
3810						b = {x: parseFloat(e.hasAttribute("x") ? e.getAttribute("x") : e.hasAttribute("cx") ? e.getAttribute("cx") : 0) || 0, y: parseFloat(e.hasAttribute("y") ? e.getAttribute("y") : e.hasAttribute("cy") ? e.getAttribute("cy") : 0) || 0, width:0, height:0};
3811					}
3812					local = _parsePosition(local).split(" ");
3813					v = [(local[0].indexOf("%") !== -1 ? parseFloat(local[0]) / 100 * b.width : parseFloat(local[0])) + b.x,
3814						 (local[1].indexOf("%") !== -1 ? parseFloat(local[1]) / 100 * b.height : parseFloat(local[1])) + b.y];
3815				}
3816				decoratee.xOrigin = xOrigin = parseFloat(v[0]);
3817				decoratee.yOrigin = yOrigin = parseFloat(v[1]);
3818				if (absolute && m !== _identity2DMatrix) { //if svgOrigin is being set, we must invert the matrix and determine where the absolute point is, factoring in the current transforms. Otherwise, the svgOrigin would be based on the element's non-transformed position on the canvas.
3819					a = m[0];
3820					b = m[1];
3821					c = m[2];
3822					d = m[3];
3823					tx = m[4];
3824					ty = m[5];
3825					determinant = (a * d - b * c);
3826					if (determinant) { //if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero.
3827						x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + ((c * ty - d * tx) / determinant);
3828						y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - ((a * ty - b * tx) / determinant);
3829						xOrigin = decoratee.xOrigin = v[0] = x;
3830						yOrigin = decoratee.yOrigin = v[1] = y;
3831					}
3832				}
3833				if (tm) { //avoid jump when transformOrigin is changed - adjust the x/y values accordingly
3834					if (skipRecord) {
3835						decoratee.xOffset = tm.xOffset;
3836						decoratee.yOffset = tm.yOffset;
3837						tm = decoratee;
3838					}
3839					if (smoothOrigin || (smoothOrigin !== false && CSSPlugin.defaultSmoothOrigin !== false)) {
3840						x = xOrigin - xOriginOld;
3841						y = yOrigin - yOriginOld;
3842						//originally, we simply adjusted the x and y values, but that would cause problems if, for example, you created a rotational tween part-way through an x/y tween. Managing the offset in a separate variable gives us ultimate flexibility.
3843						//tm.x -= x - (x * m[0] + y * m[2]);
3844						//tm.y -= y - (x * m[1] + y * m[3]);
3845						tm.xOffset += (x * m[0] + y * m[2]) - x;
3846						tm.yOffset += (x * m[1] + y * m[3]) - y;
3847					} else {
3848						tm.xOffset = tm.yOffset = 0;
3849					}
3850				}
3851				if (!skipRecord) {
3852					e.setAttribute("data-svg-origin", v.join(" "));
3853				}
3854			},
3855			_getBBoxHack = function(swapIfPossible) { //works around issues in some browsers (like Firefox) that don't correctly report getBBox() on SVG elements inside a <defs> element and/or <mask>. We try creating an SVG, adding it to the documentElement and toss the element in there so that it's definitely part of the rendering tree, then grab the bbox and if it works, we actually swap out the original getBBox() method for our own that does these extra steps whenever getBBox is needed. This helps ensure that performance is optimal (only do all these extra steps when absolutely necessary...most elements don't need it).
3856				var svg = _createElement("svg", (this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns")) || "http://www.w3.org/2000/svg"),
3857					oldParent = this.parentNode,
3858					oldSibling = this.nextSibling,
3859					oldCSS = this.style.cssText,
3860					bbox;
3861				_docElement.appendChild(svg);
3862				svg.appendChild(this);
3863				this.style.display = "block";
3864				if (swapIfPossible) {
3865					try {
3866						bbox = this.getBBox();
3867						this._originalGetBBox = this.getBBox;
3868						this.getBBox = _getBBoxHack;
3869					} catch (e) { }
3870				} else if (this._originalGetBBox) {
3871					bbox = this._originalGetBBox();
3872				}
3873				if (oldSibling) {
3874					oldParent.insertBefore(this, oldSibling);
3875				} else {
3876					oldParent.appendChild(this);
3877				}
3878				_docElement.removeChild(svg);
3879				this.style.cssText = oldCSS;
3880				return bbox;
3881			},
3882			_getBBox = function(e) {
3883				try {
3884					return e.getBBox(); //Firefox throws errors if you try calling getBBox() on an SVG element that's not rendered (like in a <symbol> or <defs>). https://bugzilla.mozilla.org/show_bug.cgi?id=612118
3885				} catch (error) {
3886					return _getBBoxHack.call(e, true);
3887				}
3888			},
3889			_isSVG = function(e) { //reports if the element is an SVG on which getBBox() actually works
3890				return !!(_SVGElement && e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e));
3891			},
3892			_identity2DMatrix = [1,0,0,1,0,0],
3893			_getMatrix = function(e, force2D) {
3894				var tm = e._gsTransform || new Transform(),
3895					rnd = 100000,
3896					style = e.style,
3897					isDefault, s, m, n, dec, none;
3898				if (_transformProp) {
3899					s = _getStyle(e, _transformPropCSS, null, true);
3900				} else if (e.currentStyle) {
3901					//for older versions of IE, we need to interpret the filter portion that is in the format: progid:DXImageTransform.Microsoft.Matrix(M11=6.123233995736766e-17, M12=-1, M21=1, M22=6.123233995736766e-17, sizingMethod='auto expand') Notice that we need to swap b and c compared to a normal matrix.
3902					s = e.currentStyle.filter.match(_ieGetMatrixExp);
3903					s = (s && s.length === 4) ? [s[0].substr(4), Number(s[2].substr(4)), Number(s[1].substr(4)), s[3].substr(4), (tm.x || 0), (tm.y || 0)].join(",") : "";
3904				}
3905				isDefault = (!s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)");
3906				if (_transformProp && ((none = (!_getComputedStyle(e) || _getComputedStyle(e).display === "none")) || !e.parentNode)) { //note: Firefox returns null for getComputedStyle() if the element is in an iframe that has display:none. https://bugzilla.mozilla.org/show_bug.cgi?id=548397
3907					if (none) { //browsers don't report transforms accurately unless the element is in the DOM and has a display value that's not "none". Firefox and Microsoft browsers have a partial bug where they'll report transforms even if display:none BUT not any percentage-based values like translate(-50%, 8px) will be reported as if it's translate(0, 8px).
3908						n = style.display;
3909						style.display = "block";
3910					}
3911					if (!e.parentNode) {
3912						dec = 1; //flag
3913						_docElement.appendChild(e);
3914					}
3915					s = _getStyle(e, _transformPropCSS, null, true);
3916					isDefault = (!s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)");
3917					if (n) {
3918						style.display = n;
3919					} else if (none) {
3920						_removeProp(style, "display");
3921					}
3922					if (dec) {
3923						_docElement.removeChild(e);
3924					}
3925				}
3926				if (tm.svg || (e.getCTM && _isSVG(e))) {
3927					if (isDefault && (style[_transformProp] + "").indexOf("matrix") !== -1) { //some browsers (like Chrome 40) don't correctly report transforms that are applied inline on an SVG element (they don't get included in the computed style), so we double-check here and accept matrix values
3928						s = style[_transformProp];
3929						isDefault = 0;
3930					}
3931					m = e.getAttribute("transform");
3932					if (isDefault && m) {
3933						m = e.transform.baseVal.consolidate().matrix; //ensures that even complex values like "translate(50,60) rotate(135,0,0)" are parsed because it mashes it into a matrix.
3934						s = "matrix(" + m.a + "," + m.b + "," + m.c + "," + m.d + "," + m.e + "," + m.f + ")";
3935						isDefault = 0;
3936					}
3937				}
3938				if (isDefault) {
3939					return _identity2DMatrix;
3940				}
3941				//split the matrix values out into an array (m for matrix)
3942				m = (s || "").match(_numExp) || [];
3943				i = m.length;
3944				while (--i > -1) {
3945					n = Number(m[i]);
3946					m[i] = (dec = n - (n |= 0)) ? ((dec * rnd + (dec < 0 ? -0.5 : 0.5)) | 0) / rnd + n : n; //convert strings to Numbers and round to 5 decimal places to avoid issues with tiny numbers. Roughly 20x faster than Number.toFixed(). We also must make sure to round before dividing so that values like 0.9999999999 become 1 to avoid glitches in browser rendering and interpretation of flipped/rotated 3D matrices. And don't just multiply the number by rnd, floor it, and then divide by rnd because the bitwise operations max out at a 32-bit signed integer, thus it could get clipped at a relatively low value (like 22,000.00000 for example).
3947				}
3948				return (force2D && m.length > 6) ? [m[0], m[1], m[4], m[5], m[12], m[13]] : m;
3949			},
3950
3951			/**
3952			 * Parses the transform values for an element, returning an object with x, y, z, scaleX, scaleY, scaleZ, rotation, rotationX, rotationY, skewX, and skewY properties. Note: by default (for performance reasons), all skewing is combined into skewX and rotation but skewY still has a place in the transform object so that we can record how much of the skew is attributed to skewX vs skewY. Remember, a skewY of 10 looks the same as a rotation of 10 and skewX of -10.
3953			 * @param {!Object} t target element
3954			 * @param {Object=} cs computed style object (optional)
3955			 * @param {boolean=} rec if true, the transform values will be recorded to the target element's _gsTransform object, like target._gsTransform = {x:0, y:0, z:0, scaleX:1...}
3956			 * @param {boolean=} parse if true, we'll ignore any _gsTransform values that already exist on the element, and force a reparsing of the css (calculated style)
3957			 * @return {object}
3957 object containing all of the transform properties/values like {x:0, y:0, z:0, scaleX:1...}
3958			 */
3959			_getTransform = _internals.getTransform = function(t, cs, rec, parse) {
3960				if (t._gsTransform && rec && !parse) {
3961					return t._gsTransform; //if the element already has a _gsTransform, use that. Note: some browsers don't accurately return the calculated style for the transform (particularly for SVG), so it's almost always safest to just use the values we've already applied rather than re-parsing things.
3962				}
3963				var tm = rec ? t._gsTransform || new Transform() : new Transform(),
3964					invX = (tm.scaleX < 0), //in order to interpret things properly, we need to know if the user applied a negative scaleX previously so that we can adjust the rotation and skewX accordingly. Otherwise, if we always interpret a flipped matrix as affecting scaleY and the user only wants to tween the scaleX on multiple sequential tweens, it would keep the negative scaleY without that being the user's intent.
3965					min = 0.00002,
3966					rnd = 100000,
3967					zOrigin = _supports3D ? parseFloat(_getStyle(t, _transformOriginProp, cs, false, "0 0 0").split(" ")[2]) || tm.zOrigin  || 0 : 0,
3968					defaultTransformPerspective = parseFloat(CSSPlugin.defaultTransformPerspective) || 0,
3969					m, i, scaleX, scaleY, rotation, skewX;
3970
3971				tm.svg = !!(t.getCTM && _isSVG(t));
3972				if (tm.svg) {
3973					_parseSVGOrigin(t, _getStyle(t, _transformOriginProp, cs, false, "50% 50%") + "", tm, t.getAttribute("data-svg-origin"));
3974					_useSVGTransformAttr = CSSPlugin.useSVGTransformAttr || _forceSVGTransformAttr;
3975				}
3976				m = _getMatrix(t);
3977				if (m !== _identity2DMatrix) {
3978
3979					if (m.length === 16) {
3980						//we'll only look at these position-related 6 variables first because if x/y/z all match, it's relatively safe to assume we don't need to re-parse everything which risks losing important rotational information (like rotationX:180 plus rotationY:180 would look the same as rotation:180 - there's no way to know for sure which direction was taken based solely on the matrix3d() values)
3981						var a11 = m[0], a21 = m[1], a31 = m[2], a41 = m[3],
3982							a12 = m[4], a22 = m[5], a32 = m[6], a42 = m[7],
3983							a13 = m[8], a23 = m[9], a33 = m[10],
3984							a14 = m[12], a24 = m[13], a34 = m[14],
3985							a43 = m[11],
3986							angle = Math.atan2(a32, a33),
3987							t1, t2, t3, t4, cos, sin;
3988						//we manually compensate for non-zero z component of transformOrigin to work around bugs in Safari
3989						if (tm.zOrigin) {
3990							a34 = -tm.zOrigin;
3991							a14 = a13*a34-m[12];
3992							a24 = a23*a34-m[13];
3993							a34 = a33*a34+tm.zOrigin-m[14];
3994						}
3995						//note for possible future consolidation: rotationX: Math.atan2(a32, a33), rotationY: Math.atan2(-a31, Math.sqrt(a33 * a33 + a32 * a32)), rotation: Math.atan2(a21, a11), skew: Math.atan2(a12, a22). However, it doesn't seem to be quite as reliable as the full-on backwards rotation procedure.
3996						tm.rotationX = angle * _RAD2DEG;
3997						//rotationX
3998						if (angle) {
3999							cos = Math.cos(-angle);
4000							sin = Math.sin(-angle);
4001							t1 = a12*cos+a13*sin;
4002							t2 = a22*cos+a23*sin;
4003							t3 = a32*cos+a33*sin;
4004							a13 = a12*-sin+a13*cos;
4005							a23 = a22*-sin+a23*cos;
4006							a33 = a32*-sin+a33*cos;
4007							a43 = a42*-sin+a43*cos;
4008							a12 = t1;
4009							a22 = t2;
4010							a32 = t3;
4011						}
4012						//rotationY
4013						angle = Math.atan2(-a31, a33);
4014						tm.rotationY = angle * _RAD2DEG;
4015						if (angle) {
4016							cos = Math.cos(-angle);
4017							sin = Math.sin(-angle);
4018							t1 = a11*cos-a13*sin;
4019							t2 = a21*cos-a23*sin;
4020							t3 = a31*cos-a33*sin;
4021							a23 = a21*sin+a23*cos;
4022							a33 = a31*sin+a33*cos;
4023							a43 = a41*sin+a43*cos;
4024							a11 = t1;
4025							a21 = t2;
4026							a31 = t3;
4027						}
4028						//rotationZ
4029						angle = Math.atan2(a21, a11);
4030						tm.rotation = angle * _RAD2DEG;
4031						if (angle) {
4032							cos = Math.cos(angle);
4033							sin = Math.sin(angle);
4034							t1 = a11*cos+a21*sin;
4035							t2 = a12*cos+a22*sin;
4036							t3 = a13*cos+a23*sin;
4037							a21 = a21*cos-a11*sin;
4038							a22 = a22*cos-a12*sin;
4039							a23 = a23*cos-a13*sin;
4040							a11 = t1;
4041							a12 = t2;
4042							a13 = t3;
4043						}
4044
4045						if (tm.rotationX && Math.abs(tm.rotationX) + Math.abs(tm.rotation) > 359.9) { //when rotationY is set, it will often be parsed as 180 degrees different than it should be, and rotationX and rotation both being 180 (it looks the same), so we adjust for that here.
4046							tm.rotationX = tm.rotation = 0;
4047							tm.rotationY = 180 - tm.rotationY;
4048						}
4049
4050						//skewX
4051						angle = Math.atan2(a12, a22);
4052
4053						//scales
4054						tm.scaleX = ((Math.sqrt(a11 * a11 + a21 * a21 + a31 * a31) * rnd + 0.5) | 0) / rnd;
4055						tm.scaleY = ((Math.sqrt(a22 * a22 + a32 * a32) * rnd + 0.5) | 0) / rnd;
4056						tm.scaleZ = ((Math.sqrt(a13 * a13 + a23 * a23 + a33 * a33) * rnd + 0.5) | 0) / rnd;
4057						a11 /= tm.scaleX;
4058						a12 /= tm.scaleY;
4059						a21 /= tm.scaleX;
4060						a22 /= tm.scaleY;
4061						if (Math.abs(angle) > min) {
4062							tm.skewX = angle * _RAD2DEG;
4063							a12 = 0;
4063 //unskews
4064							if (tm.skewType !== "simple") {
4065								tm.scaleY *= 1 / Math.cos(angle); //by default, we compensate the scale based on the skew so that the element maintains a similar proportion when skewed, so we have to alter the scaleY here accordingly to match the default (non-adjusted) skewing that CSS does (stretching more and more as it skews).
4066							}
4067
4068						} else {
4069							tm.skewX = 0;
4070						}
4071
4072						/* //for testing purposes
4073						var transform = "matrix3d(",
4074							comma = ",",
4075							zero = "0";
4076						a13 /= tm.scaleZ;
4077						a23 /= tm.scaleZ;
4078						a31 /= tm.scaleX;
4079						a32 /= tm.scaleY;
4080						a33 /= tm.scaleZ;
4081						transform += ((a11 < min && a11 > -min) ? zero : a11) + comma + ((a21 < min && a21 > -min) ? zero : a21) + comma + ((a31 < min && a31 > -min) ? zero : a31);
4082						transform += comma + ((a41 < min && a41 > -min) ? zero : a41) + comma + ((a12 < min && a12 > -min) ? zero : a12) + comma + ((a22 < min && a22 > -min) ? zero : a22);
4083						transform += comma + ((a32 < min && a32 > -min) ? zero : a32) + comma + ((a42 < min && a42 > -min) ? zero : a42) + comma + ((a13 < min && a13 > -min) ? zero : a13);
4084						transform += comma + ((a23 < min && a23 > -min) ? zero : a23) + comma + ((a33 < min && a33 > -min) ? zero : a33) + comma + ((a43 < min && a43 > -min) ? zero : a43) + comma;
4085						transform += a14 + comma + a24 + comma + a34 + comma + (tm.perspective ? (1 + (-a34 / tm.perspective)) : 1) + ")";
4086						console.log(transform);
4087						document.querySelector(".test").style[_transformProp] = transform;
4088						*/
4089
4090						tm.perspective = a43 ? 1 / ((a43 < 0) ? -a43 : a43) : 0;
4091						tm.x = a14;
4092						tm.y = a24;
4093						tm.z = a34;
4094						if (tm.svg) {
4095							tm.x -= tm.xOrigin - (tm.xOrigin * a11 - tm.yOrigin * a12);
4096							tm.y -= tm.yOrigin - (tm.yOrigin * a21 - tm.xOrigin * a22);
4097						}
4098
4099					} else if ((!_supports3D || parse || !m.length || tm.x !== m[4] || tm.y !== m[5] || (!tm.rotationX && !tm.rotationY))) { //sometimes a 6-element matrix is returned even when we performed 3D transforms, like if rotationX and rotationY are 180. In cases like this, we still need to honor the 3D transforms. If we just rely on the 2D info, it could affect how the data is interpreted, like scaleY might get set to -1 or rotation could get offset by 180 degrees. For example, do a TweenLite.to(element, 1, {css:{rotationX:180, rotationY:180}}) and then later, TweenLite.to(element, 1, {css:{rotationX:0}}) and without this conditional logic in place, it'd jump to a state of being unrotated when the 2nd tween starts. Then again, we need to honor the fact that the user COULD alter the transforms outside of CSSPlugin, like by manually applying new css, so we try to sense that by looking at x and y because if those changed, we know the changes were made outside CSSPlugin and we force a reinterpretation of the matrix values. Also, in Webkit browsers, if the element's "display" is "none", its calculated style value will always return empty, so if we've already recorded the values in the _gsTransform object, we'll just rely on those.
4100						var k = (m.length >= 6),
4101							a = k ? m[0] : 1,
4102							b = m[1] || 0,
4103							c = m[2] || 0,
4104							d = k ? m[3] : 1;
4105						tm.x = m[4] || 0;
4106						tm.y = m[5] || 0;
4107						scaleX = Math.sqrt(a * a + b * b);
4108						scaleY = Math.sqrt(d * d + c * c);
4109						rotation = (a || b) ? Math.atan2(b, a) * _RAD2DEG : tm.rotation || 0; //note: if scaleX is 0, we cannot accurately measure rotation. Same for skewX with a scaleY of 0. Therefore, we default to the previously recorded value (or zero if that doesn't exist).
4110						skewX = (c || d) ? Math.atan2(c, d) * _RAD2DEG + rotation : tm.skewX || 0;
4111						tm.scaleX = scaleX;
4112						tm.scaleY = scaleY;
4113						tm.rotation = rotation;
4114						tm.skewX = skewX;
4115						if (_supports3D) {
4116							tm.rotationX = tm.rotationY = tm.z = 0;
4117							tm.perspective = defaultTransformPerspective;
4118							tm.scaleZ = 1;
4119						}
4120						if (tm.svg) {
4121							tm.x -= tm.xOrigin - (tm.xOrigin * a + tm.yOrigin * c);
4122							tm.y -= tm.yOrigin - (tm.xOrigin * b + tm.yOrigin * d);
4123						}
4124					}
4125					if (Math.abs(tm.skewX) > 90 && Math.abs(tm.skewX) < 270) {
4126						if (invX) {
4127							tm.scaleX *= -1;
4128							tm.skewX += (tm.rotation <= 0) ? 180 : -180;
4129							tm.rotation += (tm.rotation <= 0) ? 180 : -180;
4130						} else {
4131							tm.scaleY *= -1;
4132							tm.skewX += (tm.skewX <= 0) ? 180 : -180;
4133						}
4134					}
4135					tm.zOrigin = zOrigin;
4136					//some browsers have a hard time with very small values like 2.4492935982947064e-16 (notice the "e-" towards the end) and would render the object slightly off. So we round to 0 in these cases. The conditional logic here is faster than calling Math.abs(). Also, browsers tend to render a SLIGHTLY rotated object in a fuzzy way, so we need to snap to exactly 0 when appropriate.
4137					for (i in tm) {
4138						if (tm[i] < min) if (tm[i] > -min) {
4139							tm[i] = 0;
4140						}
4141					}
4142				}
4143				//DEBUG: _log("parsed rotation of " + t.getAttribute("id")+": "+(tm.rotationX)+", "+(tm.rotationY)+", "+(tm.rotation)+", scale: "+tm.scaleX+", "+tm.scaleY+", "+tm.scaleZ+", position: "+tm.x+", "+tm.y+", "+tm.z+", perspective: "+tm.perspective+ ", origin: "+ tm.xOrigin+ ","+ tm.yOrigin);
4144				if (rec) {
4145					t._gsTransform = tm; //record to the object's _gsTransform which we use so that tweens can control individual properties independently (we need all the properties to accurately recompose the matrix in the setRatio() method)
4146					if (tm.svg) { //if we're supposed to apply transforms to the SVG element's "transform" attribute, make sure there aren't any CSS transforms applied or they'll override the attribute ones. Also clear the transform attribute if we're using CSS, just to be clean.
4147						if (_useSVGTransformAttr && t.style[_transformProp]) {
4148							TweenLite.delayedCall(0.001, function(){ //if we apply this right away (before anything has rendered), we risk there being no transforms for a brief moment and it also interferes with adjusting the transformOrigin in a tween with immediateRender:true (it'd try reading the matrix and it wouldn't have the appropriate data in place because we just removed it).
4149								_removeProp(t.style, _transformProp);
4150							});
4151						} else if (!_useSVGTransformAttr && t.getAttribute("transform")) {
4152							TweenLite.delayedCall(0.001, function(){
4153								t.removeAttribute("transform");
4154							});
4155						}
4156					}
4157				}
4158				return tm;
4159			},
4160
4161			//for setting 2D transforms in IE6, IE7, and IE8 (must use a "filter" to emulate the behavior of modern day browser transforms)
4162			_setIETransformRatio = function(v) {
4163				var t = this.data, //refers to the element's _gsTransform object
4164					ang = -t.rotation * _DEG2RAD,
4165					skew = ang + t.skewX * _DEG2RAD,
4166					rnd = 100000,
4167					a = ((Math.cos(ang) * t.scaleX * rnd) | 0) / rnd,
4168					b = ((Math.sin(ang) * t.scaleX * rnd) | 0) / rnd,
4169					c = ((Math.sin(skew) * -t.scaleY * rnd) | 0) / rnd,
4170					d = ((Math.cos(skew) * t.scaleY * rnd) | 0) / rnd,
4171					style = this.t.style,
4172					cs = this.t.currentStyle,
4173					filters, val;
4174				if (!cs) {
4175					return;
4176				}
4177				val = b; //just for swapping the variables an inverting them (reused "val" to avoid creating another variable in memory). IE's filter matrix uses a non-standard matrix configuration (angle goes the opposite way, and b and c are reversed and inverted)
4178				b = -c;
4179				c = -val;
4180				filters = cs.filter;
4181				style.filter = ""; //remove filters so that we can accurately measure offsetWidth/offsetHeight
4182				var w = this.t.offsetWidth,
4183					h = this.t.offsetHeight,
4184					clip = (cs.position !== "absolute"),
4185					m = "progid:DXImageTransform.Microsoft.Matrix(M11=" + a + ", M12=" + b + ", M21=" + c + ", M22=" + d,
4186					ox = t.x + (w * t.xPercent / 100),
4187					oy = t.y + (h * t.yPercent / 100),
4188					dx, dy;
4189
4190				//if transformOrigin is being used, adjust the offset x and y
4191				if (t.ox != null) {
4192					dx = ((t.oxp) ? w * t.ox * 0.01 : t.ox) - w / 2;
4193					dy = ((t.oyp) ? h * t.oy * 0.01 : t.oy) - h / 2;
4194					ox += dx - (dx * a + dy * b);
4195					oy += dy - (dx * c + dy * d);
4196				}
4197
4198				if (!clip) {
4199					m += ", sizingMethod='auto expand')";
4200				} else {
4201					dx = (w / 2);
4202					dy = (h / 2);
4203					//translate to ensure that transformations occur around the correct origin (default is center).
4204					m += ", Dx=" + (dx - (dx * a + dy * b) + ox) + ", Dy=" + (dy - (dx * c + dy * d) + oy) + ")";
4205				}
4206				if (filters.indexOf("DXImageTransform.Microsoft.Matrix(") !== -1) {
4207					style.filter = filters.replace(_ieSetMatrixExp, m);
4208				} else {
4209					style.filter = m + " " + filters;
4209 //we must always put the transform/matrix FIRST (before alpha(opacity=xx)) to avoid an IE bug that slices part of the object when rotation is applied with alpha.
4210				}
4211
4212				//at the end or beginning of the tween, if the matrix is normal (1, 0, 0, 1) and opacity is 100 (or doesn't exist), remove the filter to improve browser performance.
4213				if (v === 0 || v === 1) if (a === 1) if (b === 0) if (c === 0) if (d === 1) if (!clip || m.indexOf("Dx=0, Dy=0") !== -1) if (!_opacityExp.test(filters) || parseFloat(RegExp.$1) === 100) if (filters.indexOf("gradient(" && filters.indexOf("Alpha")) === -1) {
4214					style.removeAttribute("filter");
4215				}
4216
4217				//we must set the margins AFTER applying the filter in order to avoid some bugs in IE8 that could (in rare scenarios) cause them to be ignored intermittently (vibration).
4218				if (!clip) {
4219					var mult = (_ieVers < 8) ? 1 : -1, //in Internet Explorer 7 and before, the box model is broken, causing the browser to treat the width/height of the actual rotated filtered image as the width/height of the box itself, but Microsoft corrected that in IE8. We must use a negative offset in IE8 on the right/bottom
4220						marg, prop, dif;
4221					dx = t.ieOffsetX || 0;
4222					dy = t.ieOffsetY || 0;
4223					t.ieOffsetX = Math.round((w - ((a < 0 ? -a : a) * w + (b < 0 ? -b : b) * h)) / 2 + ox);
4224					t.ieOffsetY = Math.round((h - ((d < 0 ? -d : d) * h + (c < 0 ? -c : c) * w)) / 2 + oy);
4225					for (i = 0; i < 4; i++) {
4226						prop = _margins[i];
4227						marg = cs[prop];
4228						//we need to get the current margin in case it is being tweened separately (we want to respect that tween's changes)
4229						val = (marg.indexOf("px") !== -1) ? parseFloat(marg) : _convertToPixels(this.t, prop, parseFloat(marg), marg.replace(_suffixExp, "")) || 0;
4230						if (val !== t[prop]) {
4231							dif = (i < 2) ? -t.ieOffsetX : -t.ieOffsetY; //if another tween is controlling a margin, we cannot only apply the difference in the ieOffsets, so we essentially zero-out the dx and dy here in that case. We record the margin(s) later so that we can keep comparing them, making this code very flexible.
4232						} else {
4233							dif = (i < 2) ? dx - t.ieOffsetX : dy - t.ieOffsetY;
4234						}
4235						style[prop] = (t[prop] = Math.round( val - dif * ((i === 0 || i === 2) ? 1 : mult) )) + "px";
4236					}
4237				}
4238			},
4239
4240			/* translates a super small decimal to a string WITHOUT scientific notation
4241			_safeDecimal = function(n) {
4242				var s = (n < 0 ? -n : n) + "",
4243					a = s.split("e-");
4244				return (n < 0 ? "-0." : "0.") + new Array(parseInt(a[1], 10) || 0).join("0") + a[0].split(".").join("");
4245			},
4246			*/
4247
4248			_setTransformRatio = _internals.set3DTransformRatio = _internals.setTransformRatio = function(v) {
4249				var t = this.data, //refers to the element's _gsTransform object
4250					style = this.t.style,
4251					angle = t.rotation,
4252					rotationX = t.rotationX,
4253					rotationY = t.rotationY,
4254					sx = t.scaleX,
4255					sy = t.scaleY,
4256					sz = t.scaleZ,
4257					x = t.x,
4258					y = t.y,
4259					z = t.z,
4260					isSVG = t.svg,
4261					perspective = t.perspective,
4262					force3D = t.force3D,
4263					skewY = t.skewY,
4264					skewX = t.skewX,
4265					t1,	a11, a12, a13, a21, a22, a23, a31, a32, a33, a41, a42, a43,
4266					zOrigin, min, cos, sin, t2, transform, comma, zero, skew, rnd;
4267				if (skewY) { //for performance reasons, we combine all skewing into the skewX and rotation values. Remember, a skewY of 10 degrees looks the same as a rotation of 10 degrees plus a skewX of 10 degrees.
4268					skewX += skewY;
4269					angle += skewY;
4270				}
4271
4272				//check to see if we should render as 2D (and SVGs must use 2D when _useSVGTransformAttr is true)
4273				if (((((v === 1 || v === 0) && force3D === "auto" && (this.tween._totalTime === this.tween._totalDuration || !this.tween._totalTime)) || !force3D) && !z && !perspective && !rotationY && !rotationX && sz === 1) || (_useSVGTransformAttr && isSVG) || !_supports3D) { //on the final render (which could be 0 for a from tween), if there are no 3D aspects, render in 2D to free up memory and improve performance especially on mobile devices. Check the tween's totalTime/totalDuration too in order to make sure it doesn't happen between repeats if it's a repeating tween.
4274
4275					//2D
4276					if (angle || skewX || isSVG) {
4277						angle *= _DEG2RAD;
4278						skew = skewX * _DEG2RAD;
4279						rnd = 100000;
4280						a11 = Math.cos(angle) * sx;
4281						a21 = Math.sin(angle) * sx;
4282						a12 = Math.sin(angle - skew) * -sy;
4283						a22 = Math.cos(angle - skew) * sy;
4284						if (skew && t.skewType === "simple") { //by default, we compensate skewing on the other axis to make it look more natural, but you can set the skewType to "simple" to use the uncompensated skewing that CSS does
4285							t1 = Math.tan(skew - skewY * _DEG2RAD);
4286							t1 = Math.sqrt(1 + t1 * t1);
4287							a12 *= t1;
4288							a22 *= t1;
4289							if (skewY) {
4290								t1 = Math.tan(skewY * _DEG2RAD);
4291								t1 = Math.sqrt(1 + t1 * t1);
4292								a11 *= t1;
4293								a21 *= t1;
4294							}
4295						}
4296						if (isSVG) {
4297							x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset;
4298							y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset;
4299							if (_useSVGTransformAttr && (t.xPercent || t.yPercent)) { //The SVG spec doesn't support percentage-based translation in the "transform" attribute, so we merge it into the matrix to simulate it.
4300								min = this.t.getBBox();
4301								x += t.xPercent * 0.01 * min.width;
4302								y += t.yPercent * 0.01 * min.height;
4303							}
4304							min = 0.000001;
4305							if (x < min) if (x > -min) {
4306								x = 0;
4307							}
4308							if (y < min) if (y > -min) {
4309								y = 0;
4310							}
4311						}
4312						transform = (((a11 * rnd) | 0) / rnd) + "," + (((a21 * rnd) | 0) / rnd) + "," + (((a12 * rnd) | 0) / rnd) + "," + (((a22 * rnd) | 0) / rnd) + "," + x + "," + y + ")";
4313						if (isSVG && _useSVGTransformAttr) {
4314							this.t.setAttribute("transform", "matrix(" + transform);
4315						} else {
4316							//some browsers have a hard time with very small values like 2.4492935982947064e-16 (notice the "e-" towards the end) and would render the object slightly off. So we round to 5 decimal places.
4317							style[_transformProp] = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + transform;
4318						}
4319					} else {
4320						style[_transformProp] = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + sx + ",0,0," + sy + "," + x + "," + y + ")";
4321					}
4322					return;
4323
4324				}
4325				if (_isFirefox) { //Firefox has a bug (at least in v25) that causes it to render the transparent part of 32-bit PNG images as black when displayed inside an iframe and the 3D scale is very small and doesn't change sufficiently enough between renders (like if you use a Power4.easeInOut to scale from 0 to 1 where the beginning values only change a tiny amount to begin the tween before accelerating). In this case, we force the scale to be 0.00002 instead which is visually the same but works around the Firefox issue.
4326					min = 0.0001;
4327					if (sx < min && sx > -min) {
4328						sx = sz = 0.00002;
4329					}
4330					if (sy < min && sy > -min) {
4331						sy = sz = 0.00002;
4332					}
4333					if (perspective && !t.z && !t.rotationX && !t.rotationY) { //Firefox has a bug that causes elements to have an odd super-thin, broken/dotted black border on elements that have a perspective set but aren't utilizing 3D space (no rotationX, rotationY, or z).
4334						perspective = 0;
4335					}
4336				}
4337				if (angle || skewX) {
4338					angle *= _DEG2RAD;
4339					cos = a11 = Math.cos(angle);
4340					sin = a21 = Math.sin(angle);
4341					if (skewX) {
4342						angle -= skewX * _DEG2RAD;
4343						cos = Math.cos(angle);
4344						sin = Math.sin(angle);
4345						if (t.skewType === "simple") { //by default, we compensate skewing on the other axis to make it look more natural, but you can set the skewType to "simple" to use the uncompensated skewing that CSS does
4346							t1 = Math.tan((skewX - skewY) * _DEG2RAD);
4347							t1 = Math.sqrt(1 + t1 * t1);
4348							cos *= t1;
4349							sin *= t1;
4350							if (t.skewY) {
4351								t1 = Math.tan(skewY * _DEG2RAD);
4352								t1 = Math.sqrt(1 + t1 * t1);
4353								a11 *= t1;
4354								a21 *= t1;
4355							}
4356						}
4357					}
4358					a12 = -sin;
4359					a22 = cos;
4360
4361				} else if (!rotationY && !rotationX && sz === 1 && !perspective && !isSVG) { //if we're only translating and/or 2D scaling, this is faster...
4362					style[_transformProp] = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) translate3d(" : "translate3d(") + x + "px," + y + "px," + z +"px)" + ((sx !== 1 || sy !== 1) ? " scale(" + sx + "," + sy + ")" : "");
4363					return;
4364				} else {
4365					a11 = a22 = 1;
4366					a12 = a21 = 0;
4367				}
4368				// KEY  INDEX   AFFECTS a[row][column]
4369				// a11  0       rotation, rotationY, scaleX
4370				// a21  1       rotation, rotationY, scaleX
4371				// a31  2       rotationY, scaleX
4372				// a41  3       rotationY, scaleX
4373				// a12  4       rotation, skewX, rotationX, scaleY
4374				// a22  5       rotation, skewX, rotationX, scaleY
4375				// a32  6       rotationX, scaleY
4376				// a42  7       rotationX, scaleY
4377				// a13  8       rotationY, rotationX, scaleZ
4378				// a23  9       rotationY, rotationX, scaleZ
4379				// a33  10      rotationY, rotationX, scaleZ
4380				// a43  11      rotationY, rotationX, perspective, scaleZ
4381				// a14  12      x, zOrigin, svgOrigin
4382				// a24  13      y, zOrigin, svgOrigin
4383				// a34  14      z, zOrigin
4384				// a44  15
4385				// rotation: Math.atan2(a21, a11)
4386				// rotationY: Math.atan2(a13, a33) (or Math.atan2(a13, a11))
4387				// rotationX: Math.atan2(a32, a33)
4388				a33 = 1;
4389				a13 = a23 = a31 = a32 = a41 = a42 = 0;
4390				a43 = (perspective) ? -1 / perspective : 0;
4391				zOrigin = t.zOrigin;
4392				min = 0.000001; //threshold below which browsers use scientific notation which won't work.
4393				comma = ",";
4394				zero = "0";
4395				angle = rotationY * _DEG2RAD;
4396				if (angle) {
4397					cos = Math.cos(angle);
4398					sin = Math.sin(angle);
4399					a31 = -sin;
4400					a41 = a43*-sin;
4401					a13 = a11*sin;
4402					a23 = a21*sin;
4403					a33 = cos;
4404					a43 *= cos;
4405					a11 *= cos;
4406					a21 *= cos;
4407				}
4408				angle = rotationX * _DEG2RAD;
4409				if (angle) {
4410					cos = Math.cos(angle);
4411					sin = Math.sin(angle);
4412					t1 = a12*cos+a13*sin;
4413					t2 = a22*cos+a23*sin;
4414					a32 = a33*sin;
4415					a42 = a43*sin;
4416					a13 = a12*-sin+a13*cos;
4417					a23 = a22*-sin+a23*cos;
4418					a33 = a33*cos;
4419					a43 = a43*cos;
4420					a12 = t1;
4421					a22 = t2;
4422				}
4423				if (sz !== 1) {
4424					a13*=sz;
4425					a23*=sz;
4426					a33*=sz;
4427					a43*=sz;
4428				}
4429				if (sy !== 1) {
4430					a12*=sy;
4431					a22*=sy;
4432					a32*=sy;
4433					a42*=sy;
4434				}
4435				if (sx !== 1) {
4436					a11*=sx;
4437					a21*=sx;
4438					a31*=sx;
4439					a41*=sx;
4440				}
4441
4442				if (zOrigin || isSVG) {
4443					if (zOrigin) {
4444						x += a13*-zOrigin;
4445						y += a23*-zOrigin;
4446						z += a33*-zOrigin+zOrigin;
4447					}
4448					if (isSVG) { //due to bugs in some browsers, we need to manage the transform-origin of SVG manually
4449						x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset;
4450						y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset;
4451					}
4452					if (x < min && x > -min) {
4453						x = zero;
4454					}
4455					if (y < min && y > -min) {
4456						y = zero;
4457					}
4458					if (z < min && z > -min) {
4459						z = 0; //don't use string because we calculate perspective later and need the number.
4460					}
4461				}
4462
4463				//optimized way of concatenating all the values into a string. If we do it all in one shot, it's slower because of the way browsers have to create temp strings and the way it affects memory. If we do it piece-by-piece with +=, it's a bit slower too. We found that doing it in these sized chunks works best overall:
4464				transform = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix3d(" : "matrix3d(");
4465				transform += ((a11 < min && a11 > -min) ? zero : a11) + comma + ((a21 < min && a21 > -min) ? zero : a21) + comma + ((a31 < min && a31 > -min) ? zero : a31);
4466				transform += comma + ((a41 < min && a41 > -min) ? zero : a41) + comma + ((a12 < min && a12 > -min) ? zero : a12) + comma + ((a22 < min && a22 > -min) ? zero : a22);
4467				if (rotationX || rotationY || sz !== 1) { //performance optimization (often there's no rotationX or rotationY, so we can skip these calculations)
4468					transform += comma + ((a32 < min && a32 > -min) ? zero : a32) + comma + ((a42 < min && a42 > -min) ? zero : a42) + comma + ((a13 < min && a13 > -min) ? zero : a13);
4469					transform += comma + ((a23 < min && a23 > -min) ? zero : a23) + comma + ((a33 < min && a33 > -min) ? zero : a33) + comma + ((a43 < min && a43 > -min) ? zero : a43) + comma;
4470				} else {
4471					transform += ",0,0,0,0,1,0,";
4472				}
4473				transform += x + comma + y + comma + z + comma + (perspective ? (1 + (-z / perspective)) : 1) + ")";
4474
4475				style[_transformProp] = transform;
4476			};
4477
4478		p = Transform.prototype;
4479		p.x = p.y = p.z = p.skewX = p.skewY = p.rotation = p.rotationX = p.rotationY = p.zOrigin = p.xPercent = p.yPercent = p.xOffset = p.yOffset = 0;
4480		p.scaleX = p.scaleY = p.scaleZ = 1;
4481
4482		_registerComplexSpecialProp("transform,scale,scaleX,scaleY,scaleZ,x,y,z,rotation,rotationX,rotationY,rotationZ,skewX,skewY,shortRotation,shortRotationX,shortRotationY,shortRotationZ,transformOrigin,svgOrigin,transformPerspective,directionalRotation,parseTransform,force3D,skewType,xPercent,yPercent,smoothOrigin", {parser:function(t, e, parsingProp, cssp, pt, plugin, vars) {
4483			if (cssp._lastParsedTransform === vars) { return pt; } //only need to parse the transform once, and only if the browser supports it.
4484			cssp._lastParsedTransform = vars;
4485			var scaleFunc = (vars.scale && typeof(vars.scale) === "function") ? vars.scale : 0, //if there's a function-based "scale" value, swap in the resulting numeric value temporarily. Otherwise, if it's called for both scaleX and scaleY independently, they may not match (like if the function uses Math.random()).
4486				swapFunc;
4487			if (typeof(vars[parsingProp]) === "function") { //whatever property triggers the initial parsing might be a function-based value in which case it already got called in parse(), thus we don't want to call it again in here. The most efficient way to avoid this is to temporarily swap the value directly into the vars object, and then after we do all our parsing in this function, we'll swap it back again.
4488				swapFunc = vars[parsingProp];
4489				vars[parsingProp] = e;
4490			}
4491			if (scaleFunc) {
4492				vars.scale = scaleFunc(_index, t);
4493			}
4494			var originalGSTransform = t._gsTransform,
4495				style = t.style,
4496				min = 0.000001,
4497				i = _transformProps.length,
4498				v = vars,
4499				endRotations = {},
4500				transformOriginString = "transformOrigin",
4501				m1 = _getTransform(t, _cs, true, v.parseTransform),
4502				orig = v.transform && ((typeof(v.transform) === "function") ? v.transform(_index, _target) : v.transform),
4503				m2, copy, has3D, hasChange, dr, x, y, matrix, p;
4504			m1.skewType = v.skewType || m1.skewType || CSSPlugin.defaultSkewType;
4505			cssp._transform = m1;
4506			if ("rotationZ" in v) {
4507				v.rotation = v.rotationZ;
4508			}
4509			if (orig && typeof(orig) === "string" && _transformProp) { //for values like transform:"rotate(60deg) scale(0.5, 0.8)"
4510				copy = _tempDiv.style; //don't use the original target because it might be SVG in which case some browsers don't report computed style correctly.
4511				copy[_transformProp] = orig;
4512				copy.display = "block"; //if display is "none", the browser often refuses to report the transform properties correctly.
4513				copy.position = "absolute";
4514				if (orig.indexOf("%") !== -1) { //%-based translations will fail unless we set the width/height to match the original target...
4515					copy.width = _getStyle(t, "width");
4516					copy.height = _getStyle(t, "height");
4517				}
4518				_doc.body.appendChild(_tempDiv);
4519				m2 = _getTransform(_tempDiv, null, false);
4520				if (m1.skewType === "simple") { //the default _getTransform() reports the skewX/scaleY as if skewType is "compensated", thus we need to adjust that here if skewType is "simple".
4521					m2.scaleY *= Math.cos(m2.skewX * _DEG2RAD);
4522				}
4523				if (m1.svg) { //if it's an SVG element, x/y part of the matrix will be affected by whatever we use as the origin and the offsets, so compensate here...
4524					x = m1.xOrigin;
4525					y = m1.yOrigin;
4526					m2.x -= m1.xOffset;
4527					m2.y -= m1.yOffset;
4528					if (v.transformOrigin || v.svgOrigin) { //if this tween is altering the origin, we must factor that in here. The actual work of recording the transformOrigin values and setting up the PropTween is done later (still inside this function) so we cannot leave the changes intact here - we only want to update the x/y accordingly.
4529						orig = {};
4530						_parseSVGOrigin(t, _parsePosition(v.transformOrigin), orig, v.svgOrigin, v.smoothOrigin, true);
4531						x = orig.xOrigin;
4532						y = orig.yOrigin;
4533						m2.x -= orig.xOffset - m1.xOffset;
4534						m2.y -= orig.yOffset - m1.yOffset;
4535					}
4536					if (x || y) {
4537						matrix = _getMatrix(_tempDiv, true);
4538						m2.x -= x - (x * matrix[0] + y * matrix[2]);
4539						m2.y -= y - (x * matrix[1] + y * matrix[3]);
4540					}
4541				}
4542				_doc.body.removeChild(_tempDiv);
4543				if (!m2.perspective) {
4544					m2.perspective = m1.perspective; //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case.
4545				}
4546				if (v.xPercent != null) {
4547					m2.xPercent = _parseVal(v.xPercent, m1.xPercent);
4548				}
4549				if (v.yPercent != null) {
4550					m2.yPercent = _parseVal(v.yPercent, m1.yPercent);
4551				}
4552			} else if (typeof(v) === "object") { //for values like scaleX, scaleY, rotation, x, y, skewX, and skewY or transform:{...} (object)
4553				m2 = {scaleX:_parseVal((v.scaleX != null) ? v.scaleX : v.scale, m1.scaleX),
4554					scaleY:_parseVal((v.scaleY != null) ? v.scaleY : v.scale, m1.scaleY),
4555					scaleZ:_parseVal(v.scaleZ, m1.scaleZ),
4556					x:_parseVal(v.x, m1.x),
4557					y:_parseVal(v.y, m1.y),
4558					z:_parseVal(v.z, m1.z),
4559					xPercent:_parseVal(v.xPercent, m1.xPercent),
4560					yPercent:_parseVal(v.yPercent, m1.yPercent),
4561					perspective:_parseVal(v.transformPerspective, m1.perspective)};
4562				dr = v.directionalRotation;
4563				if (dr != null) {
4564					if (typeof(dr) === "object") {
4565						for (copy in dr) {
4566							v[copy] = dr[copy];
4567						}
4568					} else {
4569						v.rotation = dr;
4570					}
4571				}
4572				if (typeof(v.x) === "string" && v.x.indexOf("%") !== -1) {
4573					m2.x = 0;
4574					m2.xPercent = _parseVal(v.x, m1.xPercent);
4575				}
4576				if (typeof(v.y) === "string" && v.y.indexOf("%") !== -1) {
4577					m2.y = 0;
4578					m2.yPercent = _parseVal(v.y, m1.yPercent);
4579				}
4580
4581				m2.rotation = _parseAngle(("rotation" in v) ? v.rotation : ("shortRotation" in v) ? v.shortRotation + "_short" : m1.rotation, m1.rotation, "rotation", endRotations);
4582				if (_supports3D) {
4583					m2.rotationX = _parseAngle(("rotationX" in v) ? v.rotationX : ("shortRotationX" in v) ? v.shortRotationX + "_short" : m1.rotationX || 0, m1.rotationX, "rotationX", endRotations);
4584					m2.rotationY = _parseAngle(("rotationY" in v) ? v.rotationY : ("shortRotationY" in v) ? v.shortRotationY + "_short" : m1.rotationY || 0, m1.rotationY, "rotationY", endRotations);
4585				}
4586				m2.skewX = _parseAngle(v.skewX, m1.skewX);
4587				m2.skewY = _parseAngle(v.skewY, m1.skewY);
4588			}
4589			if (_supports3D && v.force3D != null) {
4590				m1.force3D = v.force3D;
4591				hasChange = true;
4592			}
4593
4594			has3D = (m1.force3D || m1.z || m1.rotationX || m1.rotationY || m2.z || m2.rotationX || m2.rotationY || m2.perspective);
4595			if (!has3D && v.scale != null) {
4596				m2.scaleZ = 1; //no need to tween scaleZ.
4597			}
4598
4599			while (--i > -1) {
4600				p = _transformProps[i];
4601				orig = m2[p] - m1[p];
4602				if (orig > min || orig < -min || v[p] != null || _forcePT[p] != null) {
4603					hasChange = true;
4604					pt = new CSSPropTween(m1, p, m1[p], orig, pt);
4605					if (p in endRotations) {
4606						pt.e = endRotations[p]; //directional rotations typically have compensated values during the tween, but we need to make sure they end at exactly what the user requested
4607					}
4608					pt.xs0 = 0; //ensures the value stays numeric in setRatio()
4609					pt.plugin = plugin;
4610					cssp._overwriteProps.push(pt.n);
4611				}
4612			}
4613
4614			orig = v.transformOrigin;
4615			if (m1.svg && (orig || v.svgOrigin)) {
4616				x = m1.xOffset; //when we change the origin, in order to prevent things from jumping we adjust the x/y so we must record those here so that we can create PropTweens for them and flip them at the same time as the origin
4617				y = m1.yOffset;
4618				_parseSVGOrigin(t, _parsePosition(orig), m2, v.svgOrigin, v.smoothOrigin);
4619				pt = _addNonTweeningNumericPT(m1, "xOrigin", (originalGSTransform ? m1 : m2).xOrigin, m2.xOrigin, pt, transformOriginString); //note: if there wasn't a transformOrigin defined yet, just start with the destination one; it's wasteful otherwise, and it causes problems with fromTo() tweens. For example, TweenLite.to("#wheel", 3, {rotation:180, transformOrigin:"50% 50%", delay:1}); TweenLite.fromTo("#wheel", 3, {scale:0.5, transformOrigin:"50% 50%"}, {scale:1, delay:2}); would cause a jump when the from values revert at the beginning of the 2nd tween.
4620				pt = _addNonTweeningNumericPT(m1, "yOrigin", (originalGSTransform ? m1 : m2).yOrigin, m2.yOrigin, pt, transformOriginString);
4621				if (x !== m1.xOffset || y !== m1.yOffset) {
4622					pt = _addNonTweeningNumericPT(m1, "xOffset", (originalGSTransform ? x : m1.xOffset), m1.xOffset, pt, transformOriginString);
4623					pt = _addNonTweeningNumericPT(m1, "yOffset", (originalGSTransform ? y : m1.yOffset), m1.yOffset, pt, transformOriginString);
4624				}
4625				orig = "0px 0px"; //certain browsers (like firefox) completely botch transform-origin, so we must remove it to prevent it from contaminating transforms. We manage it ourselves with xOrigin and yOrigin
4626			}
4627			if (orig || (_supports3D && has3D && m1.zOrigin)) { //if anything 3D is happening and there's a transformOrigin with a z component that's non-zero, we must ensure that the transformOrigin's z-component is set to 0 so that we can manually do those calculations to get around Safari bugs. Even if the user didn't specifically define a "transformOrigin" in this particular tween (maybe they did it via css directly).
4628				if (_transformProp) {
4629					hasChange = true;
4630					p = _transformOriginProp;
4631					orig = (orig || _getStyle(t, p, _cs, false, "50% 50%")) + ""; //cast as string to avoid errors
4632					pt = new CSSPropTween(style, p, 0, 0, pt, -1, transformOriginString);
4633					pt.b = style[p];
4634					pt.plugin = plugin;
4635					if (_supports3D) {
4636						copy = m1.zOrigin;
4637						orig = orig.split(" ");
4638						m1.zOrigin = ((orig.length > 2 && !(copy !== 0 && orig[2] === "0px")) ? parseFloat(orig[2]) : copy) || 0; //Safari doesn't handle the z part of transformOrigin correctly, so we'll manually handle it in the _set3DTransformRatio() method.
4639						pt.xs0 = pt.e = orig[0] + " " + (orig[1] || "50%") + " 0px"; //we must define a z value of 0px specifically otherwise iOS 5 Safari will stick with the old one (if one was defined)!
4640						pt = new CSSPropTween(m1, "zOrigin", 0, 0, pt, -1, pt.n); //we must create a CSSPropTween for the _gsTransform.zOrigin so that it gets reset properly at the beginning if the tween runs backward (as opposed to just setting m1.zOrigin here)
4641						pt.b = copy;
4642						pt.xs0 = pt.e = m1.zOrigin;
4643					} else {
4644						pt.xs0 = pt.e = orig;
4645					}
4646
4647					//for older versions of IE (6-8), we need to manually calculate things inside the setRatio() function. We record origin x and y (ox and oy) and whether or not the values are percentages (oxp and oyp).
4648				} else {
4649					_parsePosition(orig + "", m1);
4650				}
4651			}
4652			if (hasChange) {
4653				cssp._transformType = (!(m1.svg && _useSVGTransformAttr) && (has3D || this._transformType === 3)) ? 3 : 2; //quicker than calling cssp._enableTransforms();
4654			}
4655			if (swapFunc) {
4656				vars[parsingProp] = swapFunc;
4657			}
4658			if (scaleFunc) {
4659				vars.scale = scaleFunc;
4660			}
4661			return pt;
4662		}, prefix:true});
4663
4664		_registerComplexSpecialProp("boxShadow", {defaultValue:"0px 0px 0px 0px #999", prefix:true, color:true, multi:true, keyword:"inset"});
4665
4666		_registerComplexSpecialProp("borderRadius", {defaultValue:"0px", parser:function(t, e, p, cssp, pt, plugin) {
4667			e = this.format(e);
4668			var props = ["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"],
4669				style = t.style,
4670				ea1, i, es2, bs2, bs, es, bn, en, w, h, esfx, bsfx, rel, hn, vn, em;
4671			w = parseFloat(t.offsetWidth);
4672			h = parseFloat(t.offsetHeight);
4673			ea1 = e.split(" ");
4674			for (i = 0; i < props.length; i++) { //if we're dealing with percentages, we must convert things separately for the horizontal and vertical axis!
4675				if (this.p.indexOf("border")) { //older browsers used a prefix
4676					props[i] = _checkPropPrefix(props[i]);
4677				}
4678				bs = bs2 = _getStyle(t, props[i], _cs, false, "0px");
4679				if (bs.indexOf(" ") !== -1) {
4680					bs2 = bs.split(" ");
4681					bs = bs2[0];
4682					bs2 = bs2[1];
4683				}
4684				es = es2 = ea1[i];
4685				bn = parseFloat(bs);
4686				bsfx = bs.substr((bn + "").length);
4687				rel = (es.charAt(1) === "=");
4688				if (rel) {
4689					en = parseInt(es.charAt(0)+"1", 10);
4690					es = es.substr(2);
4691					en *= parseFloat(es);
4692					esfx = es.substr((en + "").length - (en < 0 ? 1 : 0)) || "";
4693				} else {
4694					en = parseFloat(es);
4695					esfx = es.substr((en + "").length);
4696				}
4697				if (esfx === "") {
4698					esfx = _suffixMap[p] || bsfx;
4699				}
4700				if (esfx !== bsfx) {
4701					hn = _convertToPixels(t, "borderLeft", bn, bsfx); //horizontal number (we use a bogus "borderLeft" property just because the _convertToPixels() method searches for the keywords "Left", "Right", "Top", and "Bottom" to determine of it's a horizontal or vertical property, and we need "border" in the name so that it knows it should measure relative to the element itself, not its parent.
4702					vn = _convertToPixels(t, "borderTop", bn, bsfx); //vertical number
4703					if (esfx === "%") {
4704						bs = (hn / w * 100) + "%";
4705						bs2 = (vn / h * 100) + "%";
4706					} else if (esfx === "em") {
4707						em = _convertToPixels(t, "borderLeft", 1, "em");
4708						bs = (hn / em) + "em";
4709						bs2 = (vn / em) + "em";
4710					} else {
4711						bs = hn + "px";
4712						bs2 = vn + "px";
4713					}
4714					if (rel) {
4715						es = (parseFloat(bs) + en) + esfx;
4716						es2 = (parseFloat(bs2) + en) + esfx;
4717					}
4718				}
4719				pt = _parseComplex(style, props[i], bs + " " + bs2, es + " " + es2, false, "0px", pt);
4720			}
4721			return pt;
4722		}, prefix:true, formatter:_getFormatter("0px 0px 0px 0px", false, true)});
4723		_registerComplexSpecialProp("borderBottomLeftRadius,borderBottomRightRadius,borderTopLeftRadius,borderTopRightRadius", {defaultValue:"0px", parser:function(t, e, p, cssp, pt, plugin) {
4724			return _parseComplex(t.style, p, this.format(_getStyle(t, p, _cs, false, "0px 0px")), this.format(e), false, "0px", pt);
4725		}, prefix:true, formatter:_getFormatter("0px 0px", false, true)});
4726		_registerComplexSpecialProp("backgroundPosition", {defaultValue:"0 0", parser:function(t, e, p, cssp, pt, plugin) {
4727			var bp = "background-position",
4728				cs = (_cs || _getComputedStyle(t, null)),
4729				bs = this.format( ((cs) ? _ieVers ? cs.getPropertyValue(bp + "-x") + " " + cs.getPropertyValue(bp + "-y") : cs.getPropertyValue(bp) : t.currentStyle.backgroundPositionX + " " + t.currentStyle.backgroundPositionY) || "0 0"), //Internet Explorer doesn't report background-position correctly - we must query background-position-x and background-position-y and combine them (even in IE10). Before IE9, we must do the same with the currentStyle object and use camelCase
4730				es = this.format(e),
4731				ba, ea, i, pct, overlap, src;
4732			if ((bs.indexOf("%") !== -1) !== (es.indexOf("%") !== -1) && es.split(",").length < 2) {
4733				src = _getStyle(t, "backgroundImage").replace(_urlExp, "");
4734				if (src && src !== "none") {
4735					ba = bs.split(" ");
4736					ea = es.split(" ");
4737					_tempImg.setAttribute("src", src); //set the temp IMG's src to the background-image so that we can measure its width/height
4738					i = 2;
4739					while (--i > -1) {
4740						bs = ba[i];
4741						pct = (bs.indexOf("%") !== -1);
4742						if (pct !== (ea[i].indexOf("%") !== -1)) {
4743							overlap = (i === 0) ? t.offsetWidth - _tempImg.width : t.offsetHeight - _tempImg.height;
4744							ba[i] = pct ? (parseFloat(bs) / 100 * overlap) + "px" : (parseFloat(bs) / overlap * 100) + "%";
4745						}
4746					}
4747					bs = ba.join(" ");
4748				}
4749			}
4750			return this.parseComplex(t.style, bs, es, pt, plugin);
4751		}, formatter:_parsePosition});
4752		_registerComplexSpecialProp("backgroundSize", {defaultValue:"0 0", formatter:function(v) {
4753			v += ""; //ensure it's a string
4754			return (v.substr(0,2) === "co") ? v : _parsePosition(v.indexOf(" ") === -1 ? v + " " + v : v); //if set to something like "100% 100%", Safari typically reports the computed style as just "100%" (no 2nd value), but we should ensure that there are two values, so copy the first one. Otherwise, it'd be interpreted as "100% 0" (wrong). Also remember that it could be "cover" or "contain" which we can't tween but should be able to set.
4755		}});
4756		_registerComplexSpecialProp("perspective", {defaultValue:"0px", prefix:true});
4757		_registerComplexSpecialProp("perspectiveOrigin", {defaultValue:"50% 50%", prefix:true});
4758		_registerComplexSpecialProp("transformStyle", {prefix:true});
4759		_registerComplexSpecialProp("backfaceVisibility", {prefix:true});
4760		_registerComplexSpecialProp("userSelect", {prefix:true});
4761		_registerComplexSpecialProp("margin", {parser:_getEdgeParser("marginTop,marginRight,marginBottom,marginLeft")});
4762		_registerComplexSpecialProp("padding", {parser:_getEdgeParser("paddingTop,paddingRight,paddingBottom,paddingLeft")});
4763		_registerComplexSpecialProp("clip", {defaultValue:"rect(0px,0px,0px,0px)", parser:function(t, e, p, cssp, pt, plugin){
4764			var b, cs, delim;
4765			if (_ieVers < 9) { //IE8 and earlier don't report a "clip" value in the currentStyle - instead, the values are split apart into clipTop, clipRight, clipBottom, and clipLeft. Also, in IE7 and earlier, the values inside rect() are space-delimited, not comma-delimited.
4766				cs = t.currentStyle;
4767				delim = _ieVers < 8 ? " " : ",";
4768				b = "rect(" + cs.clipTop + delim + cs.clipRight + delim + cs.clipBottom + delim + cs.clipLeft + ")";
4769				e = this.format(e).split(",").join(delim);
4770			} else {
4771				b = this.format(_getStyle(t, this.p, _cs, false, this.dflt));
4772				e = this.format(e);
4773			}
4774			return this.parseComplex(t.style, b, e, pt, plugin);
4775		}});
4776		_registerComplexSpecialProp("textShadow", {defaultValue:"0px 0px 0px #999", color:true, multi:true});
4777		_registerComplexSpecialProp("autoRound,strictUnits", {parser:function(t, e, p, cssp, pt) {return pt;}}); //just so that we can ignore these properties (not tween them)
4778		_registerComplexSpecialProp("border", {defaultValue:"0px solid #000", parser:function(t, e, p, cssp, pt, plugin) {
4779			var bw = _getStyle(t, "borderTopWidth", _cs, false, "0px"),
4780				end = this.format(e).split(" "),
4781				esfx = end[0].replace(_suffixExp, "");
4782			if (esfx !== "px") { //if we're animating to a non-px value, we need to convert the beginning width to that unit.
4783				bw = (parseFloat(bw) / _convertToPixels(t, "borderTopWidth", 1, esfx)) + esfx;
4784			}
4785			return this.parseComplex(t.style, this.format(bw + " " + _getStyle(t, "borderTopStyle", _cs, false, "solid") + " " + _getStyle(t, "borderTopColor", _cs, false, "#000")), end.join(" "), pt, plugin);
4786			}, color:true, formatter:function(v) {
4787				var a = v.split(" ");
4788				return a[0] + " " + (a[1] || "solid") + " " + (v.match(_colorExp) || ["#000"])[0];
4789			}});
4790		_registerComplexSpecialProp("borderWidth", {parser:_getEdgeParser("borderTopWidth,borderRightWidth,borderBottomWidth,borderLeftWidth")}); //Firefox doesn't pick up on borderWidth set in style sheets (only inline).
4791		_registerComplexSpecialProp("float,cssFloat,styleFloat", {parser:function(t, e, p, cssp, pt, plugin) {
4792			var s = t.style,
4793				prop = ("cssFloat" in s) ? "cssFloat" : "styleFloat";
4794			return new CSSPropTween(s, prop, 0, 0, pt, -1, p, false, 0, s[prop], e);
4795		}});
4796
4797		//opacity-related
4798		var _setIEOpacityRatio = function(v) {
4799				var t = this.t, //refers to the element's style property
4800					filters = t.filter || _getStyle(this.data, "filter") || "",
4801					val = (this.s + this.c * v) | 0,
4802					skip;
4803				if (val === 100) { //for older versions of IE that need to use a filter to apply opacity, we should remove the filter if opacity hits 1 in order to improve performance, but make sure there isn't a transform (matrix) or gradient in the filters.
4804					if (filters.indexOf("atrix(") === -1 && filters.indexOf("radient(") === -1 && filters.indexOf("oader(") === -1) {
4805						t.removeAttribute("filter");
4806						skip = (!_getStyle(this.data, "filter")); //if a class is applied that has an alpha filter, it will take effect (we don't want that), so re-apply our alpha filter in that case. We must first remove it and then check.
4807					} else {
4808						t.filter = filters.replace(_alphaFilterExp, "");
4809						skip = true;
4810					}
4811				}
4812				if (!skip) {
4813					if (this.xn1) {
4814						t.filter = filters = filters || ("alpha(opacity=" + val + ")"); //works around bug in IE7/8 that prevents changes to "visibility" from being applied properly if the filter is changed to a different alpha on the same frame.
4815					}
4816					if (filters.indexOf("pacity") === -1) { //only used if browser doesn't support the standard opacity style property (IE 7 and 8). We omit the "O" to avoid case-sensitivity issues
4817						if (val !== 0 || !this.xn1) { //bugs in IE7/8 won't render the filter properly if opacity is ADDED on the same frame/render as "visibility" changes (this.xn1 is 1 if this tween is an "autoAlpha" tween)
4818							t.filter = filters + " alpha(opacity=" + val + ")"; //we round the value because otherwise, bugs in IE7/8 can prevent "visibility" changes from being applied properly.
4819						}
4820					} else {
4821						t.filter = filters.replace(_opacityExp, "opacity=" + val);
4822					}
4823				}
4824			};
4825		_registerComplexSpecialProp("opacity,alpha,autoAlpha", {defaultValue:"1", parser:function(t, e, p, cssp, pt, plugin) {
4826			var b = parseFloat(_getStyle(t, "opacity", _cs, false, "1")),
4827				style = t.style,
4828				isAutoAlpha = (p === "autoAlpha");
4829			if (typeof(e) === "string" && e.charAt(1) === "=") {
4830				e = ((e.charAt(0) === "-") ? -1 : 1) * parseFloat(e.substr(2)) + b;
4831			}
4832			if (isAutoAlpha && b === 1 && _getStyle(t, "visibility", _cs) === "hidden" && e !== 0) { //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience)
4833				b = 0;
4834			}
4835			if (_supportsOpacity) {
4836				pt = new CSSPropTween(style, "opacity", b, e - b, pt);
4837			} else {
4838				pt = new CSSPropTween(style, "opacity", b * 100, (e - b) * 100, pt);
4839				pt.xn1 = isAutoAlpha ? 1 : 0; //we need to record whether or not this is an autoAlpha so that in the setRatio(), we know to duplicate the setting of the alpha in order to work around a bug in IE7 and IE8 that prevents changes to "visibility" from taking effect if the filter is changed to a different alpha(opacity) at the same time. Setting it to the SAME value first, then the new value works around the IE7/8 bug.
4840				style.zoom = 1; //helps correct an IE issue.
4841				pt.type = 2;
4842				pt.b = "alpha(opacity=" + pt.s + ")";
4843				pt.e = "alpha(opacity=" + (pt.s + pt.c) + ")";
4844				pt.data = t;
4845				pt.plugin = plugin;
4846				pt.setRatio = _setIEOpacityRatio;
4847			}
4848			if (isAutoAlpha) { //we have to create the "visibility" PropTween after the opacity one in the linked list so that they run in the order that works properly in IE8 and earlier
4849				pt = new CSSPropTween(style, "visibility", 0, 0, pt, -1, null, false, 0, ((b !== 0) ? "inherit" : "hidden"), ((e === 0) ? "hidden" : "inherit"));
4850				pt.xs0 = "inherit";
4851				cssp._overwriteProps.push(pt.n);
4852				cssp._overwriteProps.push(p);
4853			}
4854			return pt;
4855		}});
4856
4857
4858		var _removeProp = function(s, p) {
4859				if (p) {
4860					if (s.removeProperty) {
4861						if (p.substr(0,2) === "ms" || p.substr(0,6) === "webkit") { //Microsoft and some Webkit browsers don't conform to the standard of capitalizing the first prefix character, so we adjust so that when we prefix the caps with a dash, it's correct (otherwise it'd be "ms-transform" instead of "-ms-transform" for IE9, for example)
4862							p = "-" + p;
4863						}
4864						s.removeProperty(p.replace(_capsExp, "-$1").toLowerCase());
4865					} else { //note: old versions of IE use "removeAttribute()" instead of "removeProperty()"
4866						s.removeAttribute(p);
4867					}
4868				}
4869			},
4870			_setClassNameRatio = function(v) {
4871				this.t._gsClassPT = this;
4872				if (v === 1 || v === 0) {
4873					this.t.setAttribute("class", (v === 0) ? this.b : this.e);
4874					var mpt = this.data, //first MiniPropTween
4875						s = this.t.style;
4876					while (mpt) {
4877						if (!mpt.v) {
4878							_removeProp(s, mpt.p);
4879						} else {
4880							s[mpt.p] = mpt.v;
4881						}
4882						mpt = mpt._next;
4883					}
4884					if (v === 1 && this.t._gsClassPT === this) {
4885						this.t._gsClassPT = null;
4886					}
4887				} else if (this.t.getAttribute("class") !== this.e) {
4888					this.t.setAttribute("class", this.e);
4889				}
4890			};
4891		_registerComplexSpecialProp("className", {parser:function(t, e, p, cssp, pt, plugin, vars) {
4892			var b = t.getAttribute("class") || "", //don't use t.className because it doesn't work consistently on SVG elements; getAttribute("class") and setAttribute("class", value") is more reliable.
4893				cssText = t.style.cssText,
4894				difData, bs, cnpt, cnptLookup, mpt;
4895			pt = cssp._classNamePT = new CSSPropTween(t, p, 0, 0, pt, 2);
4896			pt.setRatio = _setClassNameRatio;
4897			pt.pr = -11;
4898			_hasPriority = true;
4899			pt.b = b;
4900			bs = _getAllStyles(t, _cs);
4901			//if there's a className tween already operating on the target, force it to its end so that the necessary inline styles are removed and the class name is applied before we determine the end state (we don't want inline styles interfer
4901ing that were there just for class-specific values)
4902			cnpt = t._gsClassPT;
4903			if (cnpt) {
4904				cnptLookup = {};
4905				mpt = cnpt.data; //first MiniPropTween which stores the inline styles - we need to force these so that the inline styles don't contaminate things. Otherwise, there's a small chance that a tween could start and the inline values match the destination values and they never get cleaned.
4906				while (mpt) {
4907					cnptLookup[mpt.p] = 1;
4908					mpt = mpt._next;
4909				}
4910				cnpt.setRatio(1);
4911			}
4912			t._gsClassPT = pt;
4913			pt.e = (e.charAt(1) !== "=") ? e : b.replace(new RegExp("(?:\\s|^)" + e.substr(2) + "(?![\\w-])"), "") + ((e.charAt(0) === "+") ? " " + e.substr(2) : "");
4914			t.setAttribute("class", pt.e);
4915			difData = _cssDif(t, bs, _getAllStyles(t), vars, cnptLookup);
4916			t.setAttribute("class", b);
4917			pt.data = difData.firstMPT;
4918			t.style.cssText = cssText; //we recorded cssText before we swapped classes and ran _getAllStyles() because in cases when a className tween is overwritten, we remove all the related tweening properties from that class change (otherwise class-specific stuff can't override properties we've directly set on the target's style object due to specificity).
4919			pt = pt.xfirst = cssp.parse(t, difData.difs, pt, plugin); //we record the CSSPropTween as the xfirst so that we can handle overwriting propertly (if "className" gets overwritten, we must kill all the properties associated with the className part of the tween, so we can loop through from xfirst to the pt itself)
4920			return pt;
4921		}});
4922
4923
4924		var _setClearPropsRatio = function(v) {
4925			if (v === 1 || v === 0) if (this.data._totalTime === this.data._totalDuration && this.data.data !== "isFromStart") { //this.data refers to the tween. Only clear at the END of the tween (remember, from() tweens make the ratio go from 1 to 0, so we can't just check that and if the tween is the zero-duration one that's created internally to render the starting values in a from() tween, ignore that because otherwise, for example, from(...{height:100, clearProps:"height", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in).
4926				var s = this.t.style,
4927					transformParse = _specialProps.transform.parse,
4928					a, p, i, clearTransform, transform;
4929				if (this.e === "all") {
4930					s.cssText = "";
4931					clearTransform = true;
4932				} else {
4933					a = this.e.split(" ").join("").split(",");
4934					i = a.length;
4935					while (--i > -1) {
4936						p = a[i];
4937						if (_specialProps[p]) {
4938							if (_specialProps[p].parse === transformParse) {
4939								clearTransform = true;
4940							} else {
4941								p = (p === "transformOrigin") ? _transformOriginProp : _specialProps[p].p; //ensures that special properties use the proper browser-specific property name, like "scaleX" might be "-webkit-transform" or "boxShadow" might be "-moz-box-shadow"
4942							}
4943						}
4944						_removeProp(s, p);
4945					}
4946				}
4947				if (clearTransform) {
4948					_removeProp(s, _transformProp);
4949					transform = this.t._gsTransform;
4950					if (transform) {
4951						if (transform.svg) {
4952							this.t.removeAttribute("data-svg-origin");
4953							this.t.removeAttribute("transform");
4954						}
4955						delete this.t._gsTransform;
4956					}
4957				}
4958
4959			}
4960		};
4961		_registerComplexSpecialProp("clearProps", {parser:function(t, e, p, cssp, pt) {
4962			pt = new CSSPropTween(t, p, 0, 0, pt, 2);
4963			pt.setRatio = _setClearPropsRatio;
4964			pt.e = e;
4965			pt.pr = -10;
4966			pt.data = cssp._tween;
4967			_hasPriority = true;
4968			return pt;
4969		}});
4970
4971		p = "bezier,throwProps,physicsProps,physics2D".split(",");
4972		i = p.length;
4973		while (i--) {
4974			_registerPluginProp(p[i]);
4975		}
4976
4977
4978
4979
4980
4981
4982
4983
4984		p = CSSPlugin.prototype;
4985		p._firstPT = p._lastParsedTransform = p._transform = null;
4986
4987		//gets called when the tween renders for the first time. This kicks everything off, recording start/end values, etc.
4988		p._onInitTween = function(target, vars, tween, index) {
4989			if (!target.nodeType) { //css is only for dom elements
4990				return false;
4991			}
4992			this._target = _target = target;
4993			this._tween = tween;
4994			this._vars = vars;
4995			_index = index;
4996			_autoRound = vars.autoRound;
4997			_hasPriority = false;
4998			_suffixMap = vars.suffixMap || CSSPlugin.suffixMap;
4999			_cs = _getComputedStyle(target, "");
5000			_overwriteProps = this._overwriteProps;
5001			var style = target.style,
5002				v, pt, pt2, first, last, next, zIndex, tpt, threeD;
5003			if (_reqSafariFix) if (style.zIndex === "") {
5004				v = _getStyle(target, "zIndex", _cs);
5005				if (v === "auto" || v === "") {
5006					//corrects a bug in [non-Android] Safari that prevents it from repainting elements in their new positions if they don't have a zIndex set. We also can't just apply this inside _parseTransform() because anything that's moved in any way (like using "left" or "top" instead of transforms like "x" and "y") can be affected, so it is best to ensure that anything that's tweening has a z-index. Setting "WebkitPerspective" to a non-zero value worked too except that on iOS Safari things would flicker randomly. Plus zIndex is less memory-intensive.
5007					this._addLazySet(style, "zIndex", 0);
5008				}
5009			}
5010
5011			if (typeof(vars) === "string") {
5012				first = style.cssText;
5013				v = _getAllStyles(target, _cs);
5014				style.cssText = first + ";" + vars;
5015				v = _cssDif(target, v, _getAllStyles(target)).difs;
5016				if (!_supportsOpacity && _opacityValExp.test(vars)) {
5017					v.opacity = parseFloat( RegExp.$1 );
5018				}
5019				vars = v;
5020				style.cssText = first;
5021			}
5022
5023			if (vars.className) { //className tweens will combine any differences they find in the css with the vars that are passed in, so {className:"myClass", scale:0.5, left:20} would work.
5024				this._firstPT = pt = _specialProps.className.parse(target, vars.className, "className", this, null, null, vars);
5025			} else {
5026				this._firstPT = pt = this.parse(target, vars, null);
5027			}
5028
5029			if (this._transformType) {
5030				threeD = (this._transformType === 3);
5031				if (!_transformProp) {
5032					style.zoom = 1; //helps correct an IE issue.
5033				} else if (_isSafari) {
5034					_reqSafariFix = true;
5035					//if zIndex isn't set, iOS Safari doesn't repaint things correctly sometimes (seemingly at random).
5036					if (style.zIndex === "") {
5037						zIndex = _getStyle(target, "zIndex", _cs);
5038						if (zIndex === "auto" || zIndex === "") {
5039							this._addLazySet(style, "zIndex", 0);
5040						}
5041					}
5042					//Setting WebkitBackfaceVisibility corrects 3 bugs:
5043					// 1) [non-Android] Safari skips rendering changes to "top" and "left" that are made on the same frame/render as a transform update.
5044					// 2) iOS Safari sometimes neglects to repaint elements in their new positions. Setting "WebkitPerspective" to a non-zero value worked too except that on iOS Safari things would flicker randomly.
5045					// 3) Safari sometimes displayed odd artifacts when tweening the transform (or WebkitTransform) property, like ghosts of the edges of the element remained. Definitely a browser bug.
5046					//Note: we allow the user to override the auto-setting by defining WebkitBackfaceVisibility in the vars of the tween.
5047					if (_isSafariLT6) {
5048						this._addLazySet(style, "WebkitBackfaceVisibility", this._vars.WebkitBackfaceVisibility || (threeD ? "visible" : "hidden"));
5049					}
5050				}
5051				pt2 = pt;
5052				while (pt2 && pt2._next) {
5053					pt2 = pt2._next;
5054				}
5055				tpt = new CSSPropTween(target, "transform", 0, 0, null, 2);
5056				this._linkCSSP(tpt, null, pt2);
5057				tpt.setRatio = _transformProp ? _setTransformRatio : _setIETransformRatio;
5058				tpt.data = this._transform || _getTransform(target, _cs, true);
5059				tpt.tween = tween;
5060				tpt.pr = -1; //ensures that the transforms get applied after the components are updated.
5061				_overwriteProps.pop(); //we don't want to force the overwrite of all "transform" tweens of the target - we only care about individual transform properties like scaleX, rotation, etc. The CSSPropTween constructor automatically adds the property to _overwriteProps which is why we need to pop() here.
5062			}
5063
5064			if (_hasPriority) {
5065				//reorders the linked list in order of pr (priority)
5066				while (pt) {
5067					next = pt._next;
5068					pt2 = first;
5069					while (pt2 && pt2.pr > pt.pr) {
5070						pt2 = pt2._next;
5071					}
5072					if ((pt._prev = pt2 ? pt2._prev : last)) {
5073						pt._prev._next = pt;
5074					} else {
5075						first = pt;
5076					}
5077					if ((pt._next = pt2)) {
5078						pt2._prev = pt;
5079					} else {
5080						last = pt;
5081					}
5082					pt = next;
5083				}
5084				this._firstPT = first;
5085			}
5086			return true;
5087		};
5088
5089
5090		p.parse = function(target, vars, pt, plugin) {
5091			var style = target.style,
5092				p, sp, bn, en, bs, es, bsfx, esfx, isStr, rel;
5093			for (p in vars) {
5094				es = vars[p]; //ending value string
5095				if (typeof(es) === "function") {
5096					es = es(_index, _target);
5097				}
5098				sp = _specialProps[p]; //SpecialProp lookup.
5099				if (sp) {
5100					pt = sp.parse(target, es, p, this, pt, plugin, vars);
5101				} else if (p.substr(0,2) === "--") { //for tweening CSS variables (which always start with "--"). To maximize performance and simplicity, we bypass CSSPlugin altogether and just add a normal property tween to the tween instance itself.
5102					this._tween._propLookup[p] = this._addTween.call(this._tween, target.style, "setProperty", _getComputedStyle(target).getPropertyValue(p) + "", es + "", p, false, p);
5103					continue;
5104				} else {
5105					bs = _getStyle(target, p, _cs) + "";
5106					isStr = (typeof(es) === "string");
5107					if (p === "color" || p === "fill" || p === "stroke" || p.indexOf("Color") !== -1 || (isStr && _rgbhslExp.test(es))) { //Opera uses background: to define color sometimes in addition to backgroundColor:
5108						if (!isStr) {
5109							es = _parseColor(es);
5110							es = ((es.length > 3) ? "rgba(" : "rgb(") + es.join(",") + ")";
5111						}
5112						pt = _parseComplex(style, p, bs, es, true, "transparent", pt, 0, plugin);
5113
5114					} else if (isStr && _complexExp.test(es)) {
5115						pt = _parseComplex(style, p, bs, es, true, null, pt, 0, plugin);
5116
5117					} else {
5118						bn = parseFloat(bs);
5119						bsfx = (bn || bn === 0) ? bs.substr((bn + "").length) : ""; //remember, bs could be non-numeric like "normal" for fontWeight, so we should default to a blank suffix in that case.
5120
5121						if (bs === "" || bs === "auto") {
5122							if (p === "width" || p === "height") {
5123								bn = _getDimension(target, p, _cs);
5124								bsfx = "px";
5125							} else if (p === "left" || p === "top") {
5126								bn = _calculateOffset(target, p, _cs);
5127								bsfx = "px";
5128							} else {
5129								bn = (p !== "opacity") ? 0 : 1;
5130								bsfx = "";
5131							}
5132						}
5133
5134						rel = (isStr && es.charAt(1) === "=");
5135						if (rel) {
5136							en = parseInt(es.charAt(0) + "1", 10);
5137							es = es.substr(2);
5138							en *= parseFloat(es);
5139							esfx = es.replace(_suffixExp, "");
5140						} else {
5141							en = parseFloat(es);
5142							esfx = isStr ? es.replace(_suffixExp, "") : "";
5143						}
5144
5145						if (esfx === "") {
5146							esfx = (p in _suffixMap) ? _suffixMap[p] : bsfx; //populate the end suffix, prioritizing the map, then if none is found, use the beginning suffix.
5147						}
5148
5149						es = (en || en === 0) ? (rel ? en + bn : en) + esfx : vars[p]; //ensures that any += or -= prefixes are taken care of. Record the end value before normalizing the suffix because we always want to end the tween on exactly what they intended even if it doesn't match the beginning value's suffix.
5150						//if the beginning/ending suffixes don't match, normalize them...
5151						if (bsfx !== esfx) if (esfx !== "" || p === "lineHeight") if (en || en === 0) if (bn) { //note: if the beginning value (bn) is 0, we don't need to convert units!
5152							bn = _convertToPixels(target, p, bn, bsfx);
5153							if (esfx === "%") {
5154								bn /= _convertToPixels(target, p, 100, "%") / 100;
5155								if (vars.strictUnits !== true) { //some browsers report only "px" values instead of allowing "%" with getComputedStyle(), so we assume that if we're tweening to a %, we should start there too unless strictUnits:true is defined. This approach is particularly useful for responsive designs that use from() tweens.
5156									bs = bn + "%";
5157								}
5158
5159							} else if (esfx === "em" || esfx === "rem" || esfx === "vw" || esfx === "vh") {
5160								bn /= _convertToPixels(target, p, 1, esfx);
5161
5162							//otherwise convert to pixels.
5163							} else if (esfx !== "px") {
5164								en = _convertToPixels(target, p, en, esfx);
5165								esfx = "px"; //we don't use bsfx after this, so we don't need to set it to px too.
5166							}
5167							if (rel) if (en || en === 0) {
5168								es = (en + bn) + esfx; //the changes we made affect relative calculations, so adjust the end value here.
5169							}
5170						}
5171
5172						if (rel) {
5173							en += bn;
5174						}
5175
5176						if ((bn || bn === 0) && (en || en === 0)) { //faster than isNaN(). Also, previously we required en !== bn but that doesn't really gain much performance and it prevents _parseToProxy() from working properly if beginning and ending values match but need to get tweened by an external plugin anyway. For example, a bezier tween where the target starts at left:0 and has these points: [{left:50},{left:0}] wouldn't work properly because when parsing the last point, it'd match the first (current) one and a non-tweening CSSPropTween would be recorded when we actually need a normal tween (type:0) so that things get updated during the tween properly.
5177							pt = new CSSPropTween(style, p, bn, en - bn, pt, 0, p, (_autoRound !== false && (esfx === "px" || p === "zIndex")), 0, bs, es);
5178							pt.xs0 = esfx;
5179							//DEBUG: _log("tween "+p+" from "+pt.b+" ("+bn+esfx+") to "+pt.e+" with suffix: "+pt.xs0);
5180						} else if (style[p] === undefined || !es && (es + "" === "NaN" || es == null)) {
5181							_log("invalid " + p + " tween value: " + vars[p]);
5182						} else {
5183							pt = new CSSPropTween(style, p, en || bn || 0, 0, pt, -1, p, false, 0, bs, es);
5184							pt.xs0 = (es === "none" && (p === "display" || p.indexOf("Style") !== -1)) ? bs : es; //intermediate value should typically be set immediately (end value) except for "display" or things like borderTopStyle, borderBottomStyle, etc. which should use the beginning value during the tween.
5185							//DEBUG: _log("non-tweening value "+p+": "+pt.xs0);
5186						}
5187					}
5188				}
5189				if (plugin) if (pt && !pt.plugin) {
5190					pt.plugin = plugin;
5191				}
5192			}
5193			return pt;
5194		};
5195
5196
5197		//gets called every time the tween updates, passing the new ratio (typically a value between 0 and 1, but not always (for example, if an Elastic.easeOut is used, the value can jump above 1 mid-tween). It will always start and 0 and end at 1.
5198		p.setRatio = function(v) {
5199			var pt = this._firstPT,
5200				min = 0.000001,
5201				val, str, i;
5202			//at the end of the tween, we set the values to exactly what we received in order to make sure non-tweening values (like "position" or "float" or whatever) are set and so that if the beginning/ending suffixes (units) didn't match and we normalized to px, the value that the user passed in is used here. We check to see if the tween is at its beginning in case it's a from() tween in which case the ratio will actually go from 1 to 0 over the course of the tween (backwards).
5203			if (v === 1 && (this._tween._time === this._tween._duration || this._tween._time === 0)) {
5204				while (pt) {
5205					if (pt.type !== 2) {
5206						if (pt.r && pt.type !== -1) {
5207							val = pt.r(pt.s + pt.c);
5208							if (!pt.type) {
5209								pt.t[pt.p] = val + pt.xs0;
5210							} else if (pt.type === 1) { //complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)"
5211								i = pt.l;
5212								str = pt.xs0 + val + pt.xs1;
5213								for (i = 1; i < pt.l; i++) {
5214									str += pt["xn"+i] + pt["xs"+(i+1)];
5215								}
5216								pt.t[pt.p] = str;
5217							}
5218						} else {
5219							pt.t[pt.p] = pt.e;
5220						}
5221					} else {
5222						pt.setRatio(v);
5223					}
5224					pt = pt._next;
5225				}
5226
5227			} else if (v || !(this._tween._time === this._tween._duration || this._tween._time === 0) || this._tween._rawPrevTime === -0.000001) {
5228				while (pt) {
5229					val = pt.c * v + pt.s;
5230					if (pt.r) {
5231						val = pt.r(val);
5232					} else if (val < min) if (val > -min) {
5233						val = 0;
5234					}
5235					if (!pt.type) {
5236						pt.t[pt.p] = val + pt.xs0;
5237					} else if (pt.type === 1) { //complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)"
5238						i = pt.l;
5239						if (i === 2) {
5240							pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2;
5241						} else if (i === 3) {
5242							pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3;
5243						} else if (i === 4) {
5244							pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3 + pt.xn3 + pt.xs4;
5245						} else if (i === 5) {
5246							pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3 + pt.xn3 + pt.xs4 + pt.xn4 + pt.xs5;
5247						} else {
5248							str = pt.xs0 + val + pt.xs1;
5249							for (i = 1; i < pt.l; i++) {
5250								str += pt["xn"+i] + pt["xs"+(i+1)];
5251							}
5252							pt.t[pt.p] = str;
5253						}
5254
5255					} else if (pt.type === -1) { //non-tweening value
5256						pt.t[pt.p] = pt.xs0;
5257
5258					} else if (pt.setRatio) { //custom setRatio() for things like SpecialProps, external plugins, etc.
5259						pt.setRatio(v);
5260					}
5261					pt = pt._next;
5262				}
5263
5264			//if the tween is reversed all the way back to the beginning, we need to restore the original values which may have different units (like % instead of px or em or whatever).
5265			} else {
5266				while (pt) {
5267					if (pt.type !== 2) {
5268						pt.t[pt.p] = pt.b;
5269					} else {
5270						pt.setRatio(v);
5271					}
5272					pt = pt._next;
5273				}
5274			}
5275		};
5276
5277		/**
5278		 * @private
5279		 * Forces rendering of the target's transforms (rotation, scale, etc.) whenever the CSSPlugin's setRatio() is called.
5280		 * Basically, this tells the CSSPlugin to create a CSSPropTween (type 2) after instantiation that runs last in the linked
5281		 * list and calls the appropriate (3D or 2D) rendering function. We separate this into its own method so that we can call
5282		 * it from other plugins like BezierPlugin if, for example, it needs to apply an autoRotation and this CSSPlugin
5283		 * doesn't have any transform-related properties of its own. You can call this method as many times as you
5284		 * want and it won't create duplicate CSSPropTweens.
5285		 *
5286		 * @param {boolean} threeD if true, it should apply 3D tweens (otherwise, just 2D ones are fine and typically faster)
5287		 */
5288		p._enableTransforms = function(threeD) {
5289			this._transform = this._transform || _getTransform(this._target, _cs, true); //ensures that the element has a _gsTransform property with the appropriate values.
5290			this._transformType = (!(this._transform.svg && _useSVGTransformAttr) && (threeD || this._transformType === 3)) ? 3 : 2;
5291		};
5292
5293		var lazySet = function(v) {
5294			this.t[this.p] = this.e;
5295			this.data._linkCSSP(this, this._next, null, true); //we purposefully keep this._next even though it'd make sense to null it, but this is a performance optimization, as this happens during the while (pt) {} loop in setRatio() at the bottom of which it sets pt = pt._next, so if we null it, the linked list will be broken in that loop.
5296		};
5297		/** @private Gives us a way to set a value on the first render (and only the first render). **/
5298		p._addLazySet = function(t, p, v) {
5299			var pt = this._firstPT = new CSSPropTween(t, p, 0, 0, this._firstPT, 2);
5300			pt.e = v;
5301			pt.setRatio = lazySet;
5302			pt.data = this;
5303		};
5304
5305		/** @private **/
5306		p._linkCSSP = function(pt, next, prev, remove) {
5307			if (pt) {
5308				if (next) {
5309					next._prev = pt;
5310				}
5311				if (pt._next) {
5312					pt._next._prev = pt._prev;
5313				}
5314				if (pt._prev) {
5315					pt._prev._next = pt._next;
5316				} else if (this._firstPT === pt) {
5317					this._firstPT = pt._next;
5318					remove = true; //just to prevent resetting this._firstPT 5 lines down in case pt._next is null. (optimized for speed)
5319				}
5320				if (prev) {
5321					prev._next = pt;
5322				} else if (!remove && this._firstPT === null) {
5323					this._firstPT = pt;
5324				}
5325				pt._next = next;
5326				pt._prev = prev;
5327			}
5328			return pt;
5329		};
5330
5331		p._mod = function(lookup) {
5332			var pt = this._firstPT;
5333			while (pt) {
5334				if (typeof(lookup[pt.p]) === "function") { //only gets called by RoundPropsPlugin (ModifyPlugin manages all the rendering internally for CSSPlugin properties that need modification). Remember, we handle rounding a bit differently in this plugin for performance reasons, leveraging "r" as an indicator that the value should be roun
5334ded internally.
5335					pt.r = lookup[pt.p];
5336				}
5337				pt = pt._next;
5338			}
5339		};
5340
5341		//we need to make sure that if alpha or autoAlpha is killed, opacity is too. And autoAlpha affects the "visibility" property.
5342		p._kill = function(lookup) {
5343			var copy = lookup,
5344				pt, p, xfirst;
5345			if (lookup.autoAlpha || lookup.alpha) {
5346				copy = {};
5347				for (p in lookup) { //copy the lookup so that we're not changing the original which may be passed elsewhere.
5348					copy[p] = lookup[p];
5349				}
5350				copy.opacity = 1;
5351				if (copy.autoAlpha) {
5352					copy.visibility = 1;
5353				}
5354			}
5355			if (lookup.className && (pt = this._classNamePT)) { //for className tweens, we need to kill any associated CSSPropTweens too; a linked list starts at the className's "xfirst".
5356				xfirst = pt.xfirst;
5357				if (xfirst && xfirst._prev) {
5358					this._linkCSSP(xfirst._prev, pt._next, xfirst._prev._prev); //break off the prev
5359				} else if (xfirst === this._firstPT) {
5360					this._firstPT = pt._next;
5361				}
5362				if (pt._next) {
5363					this._linkCSSP(pt._next, pt._next._next, xfirst._prev);
5364				}
5365				this._classNamePT = null;
5366			}
5367			pt = this._firstPT;
5368			while (pt) {
5369				if (pt.plugin && pt.plugin !== p && pt.plugin._kill) { //for plugins that are registered with CSSPlugin, we should notify them of the kill.
5370					pt.plugin._kill(lookup);
5371					p = pt.plugin;
5372				}
5373				pt = pt._next;
5374			}
5375			return TweenPlugin.prototype._kill.call(this, copy);
5376		};
5377
5378
5379
5380		//used by cascadeTo() for gathering all the style properties of each child element into an array for comparison.
5381		var _getChildStyles = function(e, props, targets) {
5382				var children, i, child, type;
5383				if (e.slice) {
5384					i = e.length;
5385					while (--i > -1) {
5386						_getChildStyles(e[i], props, targets);
5387					}
5388					return;
5389				}
5390				children = e.childNodes;
5391				i = children.length;
5392				while (--i > -1) {
5393					child = children[i];
5394					type = child.type;
5395					if (child.style) {
5396						props.push(_getAllStyles(child));
5397						if (targets) {
5398							targets.push(child);
5399						}
5400					}
5401					if ((type === 1 || type === 9 || type === 11) && child.childNodes.length) {
5402						_getChildStyles(child, props, targets);
5403					}
5404				}
5405			};
5406
5407		/**
5408		 * Typically only useful for className tweens that may affect child elements, this method creates a TweenLite
5409		 * and then compares the style properties of all the target's child elements at the tween's start and end, and
5410		 * if any are different, it also creates tweens for those and returns an array containing ALL of the resulting
5411		 * tweens (so that you can easily add() them to a TimelineLite, for example). The reason this functionality is
5412		 * wrapped into a separate static method of CSSPlugin instead of being integrated into all regular className tweens
5413		 * is because it creates entirely new tweens that may have completely different targets than the original tween,
5414		 * so if they were all lumped into the original tween instance, it would be inconsistent with the rest of the API
5415		 * and it would create other problems. For example:
5416		 *  - If I create a tween of elementA, that tween instance may suddenly change its target to include 50 other elements (unintuitive if I specifically defined the target I wanted)
5417		 *  - We can't just create new independent tweens because otherwise, what happens if the original/parent tween is reversed or pause or dropped into a TimelineLite for tight control? You'd expect that tween's behavior to affect all the others.
5418		 *  - Analyzing every style property of every child before and after the tween is an expensive operation when there are many children, so this behavior shouldn't be imposed on all className tweens by default, especially since it's probably rare that this extra functionality is needed.
5419		 *
5420		 * @param {Object} target object to be tweened
5421		 * @param {number} Duration in seconds (or frames for frames-based tweens)
5422		 * @param {Object} Object containing the end values, like {className:"newClass", ease:Linear.easeNone}
5423		 * @return {Array} An array of TweenLite instances
5424		 */
5425		CSSPlugin.cascadeTo = function(target, duration, vars) {
5426			var tween = TweenLite.to(target, duration, vars),
5427				results = [tween],
5428				b = [],
5429				e = [],
5430				targets = [],
5431				_reservedProps = TweenLite._internals.reservedProps,
5432				i, difs, p, from;
5433			target = tween._targets || tween.target;
5434			_getChildStyles(target, b, targets);
5435			tween.render(duration, true, true);
5436			_getChildStyles(target, e);
5437			tween.render(0, true, true);
5438			tween._enabled(true);
5439			i = targets.length;
5440			while (--i > -1) {
5441				difs = _cssDif(targets[i], b[i], e[i]);
5442				if (difs.firstMPT) {
5443					difs = difs.difs;
5444					for (p in vars) {
5445						if (_reservedProps[p]) {
5446							difs[p] = vars[p];
5447						}
5448					}
5449					from = {};
5450					for (p in difs) {
5451						from[p] = b[i][p];
5452					}
5453					results.push(TweenLite.fromTo(targets[i], duration, from, difs));
5454				}
5455			}
5456			return results;
5457		};
5458
5459		TweenPlugin.activate([CSSPlugin]);
5460		return CSSPlugin;
5461
5462	}, true);
5463
5464	
5465	
5466	
5467	
5468	
5469	
5470	
5471	
5472	
5473	
5474/*
5475 * ----------------------------------------------------------------
5476 * RoundPropsPlugin
5477 * ----------------------------------------------------------------
5478 */
5479	(function() {
5480
5481		var RoundPropsPlugin = _gsScope._gsDefine.plugin({
5482				propName: "roundProps",
5483				version: "1.7.0",
5484				priority: -1,
5485				API: 2,
5486
5487				//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
5488				init: function(target, value, tween) {
5489					this._tween = tween;
5490					return true;
5491				}
5492
5493			}),
5494			_getRoundFunc = function(v) { //pass in 0.1 get a function that'll round to the nearest tenth, or 5 to round to the closest 5, or 0.001 to the closest 1000th, etc.
5495				var p = v < 1 ? Math.pow(10, (v + "").length - 2) : 1; //to avoid floating point math errors (like 24 * 0.1 == 2.4000000000000004), we chop off at a specific number of decimal places (much faster than toFixed()
5496				return function(n) {
5497					return ((Math.round(n / v) * v * p) | 0) / p;
5498				};
5499			},
5500			_roundLinkedList = function(node, mod) {
5501				while (node) {
5502					if (!node.f && !node.blob) {
5503						node.m = mod || Math.round;
5504					}
5505					node = node._next;
5506				}
5507			},
5508			p = RoundPropsPlugin.prototype;
5509
5510		p._onInitAllProps = function() {
5511			var tween = this._tween,
5512				rp = tween.vars.roundProps,
5513				lookup = {},
5514				rpt = tween._propLookup.roundProps,
5515				pt, next, i, p;
5516			if (typeof(rp) === "object" && !rp.push) {
5517				for (p in rp) {
5518					lookup[p] = _getRoundFunc(rp[p]);
5519				}
5520			} else {
5521				if (typeof(rp) === "string") {
5522					rp = rp.split(",");
5523				}
5524				i = rp.length;
5525				while (--i > -1) {
5526					lookup[rp[i]] = Math.round;
5527				}
5528			}
5529
5530			for (p in lookup) {
5531				pt = tween._firstPT;
5532				while (pt) {
5533					next = pt._next; //record here, because it may get removed
5534					if (pt.pg) {
5535						pt.t._mod(lookup);
5536					} else if (pt.n === p) {
5537						if (pt.f === 2 && pt.t) { //a blob (text containing multiple numeric values)
5538							_roundLinkedList(pt.t._firstPT, lookup[p]);
5539						} else {
5540							this._add(pt.t, p, pt.s, pt.c, lookup[p]);
5541							//remove from linked list
5542							if (next) {
5543								next._prev = pt._prev;
5544							}
5545							if (pt._prev) {
5546								pt._prev._next = next;
5547							} else if (tween._firstPT === pt) {
5548								tween._firstPT = next;
5549							}
5550							pt._next = pt._prev = null;
5551							tween._propLookup[p] = rpt;
5552						}
5553					}
5554					pt = next;
5555				}
5556			}
5557			return false;
5558		};
5559
5560		p._add = function(target, p, s, c, mod) {
5561			this._addTween(target, p, s, s + c, p, mod || Math.round);
5562			this._overwriteProps.push(p);
5563		};
5564
5565	}());
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576/*
5577 * ----------------------------------------------------------------
5578 * AttrPlugin
5579 * ----------------------------------------------------------------
5580 */
5581
5582	(function() {
5583
5584		_gsScope._gsDefine.plugin({
5585			propName: "attr",
5586			API: 2,
5587			version: "0.6.1",
5588
5589			//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
5590			init: function(target, value, tween, index) {
5591				var p, end;
5592				if (typeof(target.setAttribute) !== "function") {
5593					return false;
5594				}
5595				for (p in value) {
5596					end = value[p];
5597					if (typeof(end) === "function") {
5598						end = end(index, target);
5599					}
5600					this._addTween(target, "setAttribute", target.getAttribute(p) + "", end + "", p, false, p);
5601					this._overwriteProps.push(p);
5602				}
5603				return true;
5604			}
5605
5606		});
5607
5608	}());
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619/*
5620 * ----------------------------------------------------------------
5621 * DirectionalRotationPlugin
5622 * ----------------------------------------------------------------
5623 */
5624	_gsScope._gsDefine.plugin({
5625		propName: "directionalRotation",
5626		version: "0.3.1",
5627		API: 2,
5628
5629		//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
5630		init: function(target, value, tween, index) {
5631			if (typeof(value) !== "object") {
5632				value = {rotation:value};
5633			}
5634			this.finals = {};
5635			var cap = (value.useRadians === true) ? Math.PI * 2 : 360,
5636				min = 0.000001,
5637				p, v, start, end, dif, split;
5638			for (p in value) {
5639				if (p !== "useRadians") {
5640					end = value[p];
5641					if (typeof(end) === "function") {
5642						end = end(index, target);
5643					}
5644					split = (end + "").split("_");
5645					v = split[0];
5646					start = parseFloat( (typeof(target[p]) !== "function") ? target[p] : target[ ((p.indexOf("set") || typeof(target["get" + p.substr(3)]) !== "function") ? p : "get" + p.substr(3)) ]() );
5647					end = this.finals[p] = (typeof(v) === "string" && v.charAt(1) === "=") ? start + parseInt(v.charAt(0) + "1", 10) * Number(v.substr(2)) : Number(v) || 0;
5648					dif = end - start;
5649					if (split.length) {
5650						v = split.join("_");
5651						if (v.indexOf("short") !== -1) {
5652							dif = dif % cap;
5653							if (dif !== dif % (cap / 2)) {
5654								dif = (dif < 0) ? dif + cap : dif - cap;
5655							}
5656						}
5657						if (v.indexOf("_cw") !== -1 && dif < 0) {
5658							dif = ((dif + cap * 9999999999) % cap) - ((dif / cap) | 0) * cap;
5659						} else if (v.indexOf("ccw") !== -1 && dif > 0) {
5660							dif = ((dif - cap * 9999999999) % cap) - ((dif / cap) | 0) * cap;
5661						}
5662					}
5663					if (dif > min || dif < -min) {
5664						this._addTween(target, p, start, start + dif, p);
5665						this._overwriteProps.push(p);
5666					}
5667				}
5668			}
5669			return true;
5670		},
5671
5672		//called each time the values should be updated, and the ratio gets passed as the only parameter (typically it's a value between 0 and 1, but it can exceed those when using an ease like Elastic.easeOut or Back.easeOut, etc.)
5673		set: function(ratio) {
5674			var pt;
5675			if (ratio !== 1) {
5676				this._super.setRatio.call(this, ratio);
5677			} else {
5678				pt = this._firstPT;
5679				while (pt) {
5680					if (pt.f) {
5681						pt.t[pt.p](this.finals[pt.p]);
5682					} else {
5683						pt.t[pt.p] = this.finals[pt.p];
5684					}
5685					pt = pt._next;
5686				}
5687			}
5688		}
5689
5690	})._autoCSS = true;
5691
5692
5693
5694
5695
5696
5697
5698	
5699	
5700	
5701	
5702/*
5703 * ----------------------------------------------------------------
5704 * EasePack
5705 * ----------------------------------------------------------------
5706 */
5707	_gsScope._gsDefine("easing.Back", ["easing.Ease"], function(Ease) {
5708		
5709		var w = (_gsScope.GreenSockGlobals || _gsScope),
5710			gs = w.com.greensock,
5711			_2PI = Math.PI * 2,
5712			_HALF_PI = Math.PI / 2,
5713			_class = gs._class,
5714			_create = function(n, f) {
5715				var C = _class("easing." + n, function(){}, true),
5716					p = C.prototype = new Ease();
5717				p.constructor = C;
5718				p.getRatio = f;
5719				return C;
5720			},
5721			_easeReg = Ease.register || function(){}, //put an empty function in place just as a safety measure in case someone loads an OLD version of TweenLite.js where Ease.register doesn't exist.
5722			_wrap = function(name, EaseOut, EaseIn, EaseInOut, aliases) {
5723				var C = _class("easing."+name, {
5724					easeOut:new EaseOut(),
5725					easeIn:new EaseIn(),
5726					easeInOut:new EaseInOut()
5727				}, true);
5728				_easeReg(C, name);
5729				return C;
5730			},
5731			EasePoint = function(time, value, next) {
5732				this.t = time;
5733				this.v = value;
5734				if (next) {
5735					this.next = next;
5736					next.prev = this;
5737					this.c = next.v - value;
5738					this.gap = next.t - time;
5739				}
5740			},
5741
5742			//Back
5743			_createBack = function(n, f) {
5744				var C = _class("easing." + n, function(overshoot) {
5745						this._p1 = (overshoot || overshoot === 0) ? overshoot : 1.70158;
5746						this._p2 = this._p1 * 1.525;
5747					}, true),
5748					p = C.prototype = new Ease();
5749				p.constructor = C;
5750				p.getRatio = f;
5751				p.config = function(overshoot) {
5752					return new C(overshoot);
5753				};
5754				return C;
5755			},
5756
5757			Back = _wrap("Back",
5758				_createBack("BackOut", function(p) {
5759					return ((p = p - 1) * p * ((this._p1 + 1) * p + this._p1) + 1);
5760				}),
5761				_createBack("BackIn", function(p) {
5762					return p * p * ((this._p1 + 1) * p - this._p1);
5763				}),
5764				_createBack("BackInOut", function(p) {
5765					return ((p *= 2) < 1) ? 0.5 * p * p * ((this._p2 + 1) * p - this._p2) : 0.5 * ((p -= 2) * p * ((this._p2 + 1) * p + this._p2) + 2);
5766				})
5767			),
5768
5769
5770			//SlowMo
5771			SlowMo = _class("easing.SlowMo", function(linearRatio, power, yoyoMode) {
5772				power = (power || power === 0) ? power : 0.7;
5773				if (linearRatio == null) {
5774					linearRatio = 0.7;
5775				} else if (linearRatio > 1) {
5776					linearRatio = 1;
5777				}
5778				this._p = (linearRatio !== 1) ? power : 0;
5779				this._p1 = (1 - linearRatio) / 2;
5780				this._p2 = linearRatio;
5781				this._p3 = this._p1 + this._p2;
5782				this._calcEnd = (yoyoMode === true);
5783			}, true),
5784			p = SlowMo.prototype = new Ease(),
5785			SteppedEase, ExpoScaleEase, RoughEase, _createElastic;
5786
5787		p.constructor = SlowMo;
5788		p.getRatio = function(p) {
5789			var r = p + (0.5 - p) * this._p;
5790			if (p < this._p1) {
5791				return this._calcEnd ? 1 - ((p = 1 - (p / this._p1)) * p) : r - ((p = 1 - (p / this._p1)) * p * p * p * r);
5792			} else if (p > this._p3) {
5793				return this._calcEnd ? (p === 1 ? 0 : 1 - (p = (p - this._p3) / this._p1) * p) : r + ((p - r) * (p = (p - this._p3) / this._p1) * p * p * p); //added p === 1 ? 0 to avoid floating point rounding errors from affecting the final value, like 1 - 0.7 = 0.30000000000000004 instead of 0.3
5794			}
5795			return this._calcEnd ? 1 : r;
5796		};
5797		SlowMo.ease = new SlowMo(0.7, 0.7);
5798
5799		p.config = SlowMo.config = function(linearRatio, power, yoyoMode) {
5800			return new SlowMo(linearRatio, power, yoyoMode);
5801		};
5802
5803
5804		//SteppedEase
5805		SteppedEase = _class("easing.SteppedEase", function(steps, immediateStart) {
5806				steps = steps || 1;
5807				this._p1 = 1 / steps;
5808				this._p2 = steps + (immediateStart ? 0 : 1);
5809				this._p3 = immediateStart ? 1 : 0;
5810			}, true);
5811		p = SteppedEase.prototype = new Ease();
5812		p.constructor = SteppedEase;
5813		p.getRatio = function(p) {
5814			if (p < 0) {
5815				p = 0;
5816			} else if (p >= 1) {
5817				p = 0.999999999;
5818			}
5819			return (((this._p2 * p) | 0) + this._p3) * this._p1;
5820		};
5821		p.config = SteppedEase.config = function(steps, immediateStart) {
5822			return new SteppedEase(steps, immediateStart);
5823		};
5824
5825		//ExpoScaleEase
5826		ExpoScaleEase = _class("easing.ExpoScaleEase", function(start, end, ease) {
5827			this._p1 = Math.log(end / start);
5828			this._p2 = end - start;
5829			this._p3 = start;
5830			this._ease = ease;
5831		}, true);
5832		p = ExpoScaleEase.prototype = new Ease();
5833		p.constructor = ExpoScaleEase;
5834		p.getRatio = function(p) {
5835			if (this._ease) {
5836				p = this._ease.getRatio(p);
5837			}
5838			return (this._p3 * Math.exp(this._p1 * p) - this._p3) / this._p2;
5839		};
5840		p.config = ExpoScaleEase.config = function(start, end, ease) {
5841			return new ExpoScaleEase(start, end, ease);
5842		};
5843
5844
5845		//RoughEase
5846		RoughEase = _class("easing.RoughEase", function(vars) {
5847			vars = vars || {};
5848			var taper = vars.taper || "none",
5849				a = [],
5850				cnt = 0,
5851				points = (vars.points || 20) | 0,
5852				i = points,
5853				randomize = (vars.randomize !== false),
5854				clamp = (vars.clamp === true),
5855				template = (vars.template instanceof Ease) ? vars.template : null,
5856				strength = (typeof(vars.strength) === "number") ? vars.strength * 0.4 : 0.4,
5857				x, y, bump, invX, obj, pnt;
5858			while (--i > -1) {
5859				x = randomize ? Math.random() : (1 / points) * i;
5860				y = template ? template.getRatio(x) : x;
5861				if (taper === "none") {
5862					bump = strength;
5863				} else if (taper === "out") {
5864					invX = 1 - x;
5865					bump = invX * invX * strength;
5866				} else if (taper === "in") {
5867					bump = x * x * strength;
5868				} else if (x < 0.5) {  //"both" (start)
5869					invX = x * 2;
5870					bump = invX * invX * 0.5 * strength;
5871				} else {				//"both" (end)
5872					invX = (1 - x) * 2;
5873					bump = invX * invX * 0.5 * strength;
5874				}
5875				if (randomize) {
5876					y += (Math.random() * bump) - (bump * 0.5);
5877				} else if (i % 2) {
5878					y += bump * 0.5;
5879				} else {
5880					y -= bump * 0.5;
5881				}
5882				if (clamp) {
5883					if (y > 1) {
5884						y = 1;
5885					} else if (y < 0) {
5886						y = 0;
5887					}
5888				}
5889				a[cnt++] = {x:x, y:y};
5890			}
5891			a.sort(function(a, b) {
5892				return a.x - b.x;
5893			});
5894
5895			pnt = new EasePoint(1, 1, null);
5896			i = points;
5897			while (--i > -1) {
5898				obj = a[i];
5899				pnt = new EasePoint(obj.x, obj.y, pnt);
5900			}
5901
5902			this._prev = new EasePoint(0, 0, (pnt.t !== 0) ? pnt : pnt.next);
5903		}, true);
5904		p = RoughEase.prototype = new Ease();
5905		p.constructor = RoughEase;
5906		p.getRatio = function(p) {
5907			var pnt = this._prev;
5908			if (p > pnt.t) {
5909				while (pnt.next && p >= pnt.t) {
5910					pnt = pnt.next;
5911				}
5912				pnt = pnt.prev;
5913			} else {
5914				while (pnt.prev && p <= pnt.t) {
5915					pnt = pnt.prev;
5916				}
5917			}
5918			this._prev = pnt;
5919			return (pnt.v + ((p - pnt.t) / pnt.gap) * pnt.c);
5920		};
5921		p.config = function(vars) {
5922			return new RoughEase(vars);
5923		};
5924		RoughEase.ease = new RoughEase();
5925
5926
5927		//Bounce
5928		_wrap("Bounce",
5929			_create("BounceOut", function(p) {
5930				if (p < 1 / 2.75) {
5931					return 7.5625 * p * p;
5932				} else if (p < 2 / 2.75) {
5933					return 7.5625 * (p -= 1.5 / 2.75) * p + 0.75;
5934				} else if (p < 2.5 / 2.75) {
5935					return 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375;
5936				}
5937				return 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375;
5938			}),
5939			_create("BounceIn", function(p) {
5940				if ((p = 1 - p) < 1 / 2.75) {
5941					return 1 - (7.5625 * p * p);
5942				} else if (p < 2 / 2.75) {
5943					return 1 - (7.5625 * (p -= 1.5 / 2.75) * p + 0.75);
5944				} else if (p < 2.5 / 2.75) {
5945					return 1 - (7.5625 * (p -= 2.25 / 2.75) * p + 0.9375);
5946				}
5947				return 1 - (7.5625 * (p -= 2.625 / 2.75) * p + 0.984375);
5948			}),
5949			_create("BounceInOut", function(p) {
5950				var invert = (p < 0.5);
5951				if (invert) {
5952					p = 1 - (p * 2);
5953				} else {
5954					p = (p * 2) - 1;
5955				}
5956				if (p < 1 / 2.75) {
5957					p = 7.5625 * p * p;
5958				} else if (p < 2 / 2.75) {
5959					p = 7.5625 * (p -= 1.5 / 2.75) * p + 0.75;
5960				} else if (p < 2.5 / 2.75) {
5961					p = 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375;
5962				} else {
5963					p = 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375;
5964				}
5965				return invert ? (1 - p) * 0.5 : p * 0.5 + 0.5;
5966			})
5967		);
5968
5969
5970		//CIRC
5971		_wrap("Circ",
5972			_create("CircOut", function(p) {
5973				return Math.sqrt(1 - (p = p - 1) * p);
5974			}),
5975			_create("CircIn", function(p) {
5976				return -(Math.sqrt(1 - (p * p)) - 1);
5977			}),
5978			_create("CircInOut", function(p) {
5979				return ((p*=2) < 1) ? -0.5 * (Math.sqrt(1 - p * p) - 1) : 0.5 * (Math.sqrt(1 - (p -= 2) * p) + 1);
5980			})
5981		);
5982
5983
5984		//Elastic
5985		_createElastic = function(n, f, def) {
5986			var C = _class("easing." + n, function(amplitude, period) {
5987					this._p1 = (amplitude >= 1) ? amplitude : 1; //note: if amplitude is < 1, we simply adjust the period for a more natural feel. Otherwise the math doesn't work right and the curve starts at 1.
5988					this._p2 = (period || def) / (amplitude < 1 ? amplitude : 1);
5989					this._p3 = this._p2 / _2PI * (Math.asin(1 / this._p1) || 0);
5990					this._p2 = _2PI / this._p2; //precalculate to optimize
5991				}, true),
5992				p = C.prototype = new Ease();
5993			p.constructor = C;
5994			p.getRatio = f;
5995			p.config = function(amplitude, period) {
5996				return new C(amplitude, period);
5997			};
5998			return C;
5999		};
6000		_wrap("Elastic",
6001			_createElastic("ElasticOut", function(p) {
6002				return this._p1 * Math.pow(2, -10 * p) * Math.sin( (p - this._p3) * this._p2 ) + 1;
6003			}, 0.3),
6004			_createElastic("ElasticIn", function(p) {
6005				return -(this._p1 * Math.pow(2, 10 * (p -= 1)) * Math.sin( (p - this._p3) * this._p2 ));
6006			}, 0.3),
6007			_createElastic("ElasticInOut", function(p) {
6008				return ((p *= 2) < 1) ? -0.5 * (this._p1 * Math.pow(2, 10 * (p -= 1)) * Math.sin( (p - this._p3) * this._p2)) : this._p1 * Math.pow(2, -10 *(p -= 1)) * Math.sin( (p - this._p3) * this._p2 ) * 0.5 + 1;
6009			}, 0.45)
6010		);
6011
6012
6013		//Expo
6014		_wrap("Expo",
6015			_create("ExpoOut", function(p) {
6016				return 1 - Math.pow(2, -10 * p);
6017			}),
6018			_create("ExpoIn", function(p) {
6019				return Math.pow(2, 10 * (p - 1)) - 0.001;
6020			}),
6021			_create("ExpoInOut", function(p) {
6022				return ((p *= 2) < 1) ? 0.5 * Math.pow(2, 10 * (p - 1)) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
6023			})
6024		);
6025
6026
6027		//Sine
6028		_wrap("Sine",
6029			_create("SineOut", function(p) {
6030				return Math.sin(p * _HALF_PI);
6031			}),
6032			_create("SineIn", function(p) {
6033				return -Math.cos(p * _HALF_PI) + 1;
6034			}),
6035			_create("SineInOut", function(p) {
6036				return -0.5 * (Math.cos(Math.PI * p) - 1);
6037			})
6038		);
6039
6040		_class("easing.EaseLookup", {
6041				find:function(s) {
6042					return Ease.map[s];
6043				}
6044			}, true);
6045
6046		//register the non-standard eases
6047		_easeReg(w.SlowMo, "SlowMo", "ease,");
6048		_easeReg(RoughEase, "RoughEase", "ease,");
6049		_easeReg(SteppedEase, "SteppedEase", "ease,");
6050
6051		return Back;
6052		
6053	}, true);
6054
6055
6056});
6057
6058if (_gsScope._gsDefine) { _gsScope._gsQueue.pop()(); } //necessary in case TweenLite was already loaded separately.
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070/*
6071 * ----------------------------------------------------------------
6072 * Base classes like TweenLite, SimpleTimeline, Ease, Ticker, etc.
6073 * ----------------------------------------------------------------
6074 */
6075(function(window, moduleName) {
6076
6077		"use strict";
6078		var _exports = {},
6079			_doc = window.document,
6080			_globals = window.GreenSockGlobals = window.GreenSockGlobals || window,
6081			existingModule = _globals[moduleName];
6082		if (existingModule) {
6083			if (typeof(module) !== "undefined" && module.exports) { //node
6084				module.exports = existingModule;
6085			}
6086			return existingModule; //in case the core set of classes is already loaded, don't instantiate twice.
6087		}
6088		var _namespace = function(ns) {
6089				var a = ns.split("."),
6090					p = _globals, i;
6091				for (i = 0; i < a.length; i++) {
6092					p[a[i]] = p = p[a[i]] || {};
6093				}
6094				return p;
6095			},
6096			gs = _namespace("com.greensock"),
6097			_tinyNum = 0.0000000001,
6098			_slice = function(a) { //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
6099				var b = [],
6100					l = a.length,
6101					i;
6102				for (i = 0; i !== l; b.push(a[i++])) {}
6103				return b;
6104			},
6105			_emptyFunc = function() {},
6106			_isArray = (function() { //works around issues in iframe environments where the Array global isn't shared, thus if the object originates in a different window/iframe, "(obj instanceof Array)" will evaluate false. We added some speed optimizations to avoid Object.prototype.toString.call() unless it's absolutely necessary because it's VERY slow (like 20x slower)
6107				var toString = Object.prototype.toString,
6108					array = toString.call([]);
6109				return function(obj) {
6110					return obj != null && (obj instanceof Array || (typeof(obj) === "object" && !!obj.push && toString.call(obj) === array));
6111				};
6112			}()),
6113			a, i, p, _ticker, _tickerActive,
6114			_defLookup = {},
6115
6116			/**
6117			 * @constructor
6118			 * Defines a GreenSock class, optionally with an array of dependencies that must be instantiated first and passed into the definition.
6119			 * This allows users to load GreenSock JS files in any order even if they have interdependencies (like CSSPlugin extends TweenPlugin which is
6120			 * inside TweenLite.js, but if CSSPlugin is loaded first, it should wait to run its code until TweenLite.js loads and instantiates TweenPlugin
6121			 * and then pass TweenPlugin to CSSPlugin's definition). This is all done automatically and internally.
6122			 *
6123			 * Every definition will be added to a "com.greensock" global object (typically window, but if a window.GreenSockGlobals object is found,
6124			 * it will go there as of v1.7). For example, TweenLite will be found at window.com.greensock.TweenLite and since it's a global class that should be available anywhere,
6125			 * it is ALSO referenced at window.TweenLite. However some classes aren't considered global, like the base com.greensock.core.Animation class, so
6126			 * those will only be at the package like window.com.greensock.core.Animation. Again, if you define a GreenSockGlobals object on the window, everything
6127			 * gets tucked neatly inside there instead of on the window directly. This allows you to do advanced things like load multiple versions of GreenSock
6128			 * files and put them into distinct objects (imagine a banner ad uses a newer version but the main site uses an older one). In that case, you could
6129			 * sandbox the banner one like:
6130			 *
6131			 * <script>
6132			 *     var gs = window.GreenSockGlobals = {}; //the newer version we're about to load could now be referenced in a "gs" object, like gs.TweenLite.to(...). Use whatever alias you want as long as it's unique, "gs" or "banner" or whatever.
6133			 * </script>
6134			 * <script src="js/greensock/v1.7/TweenMax.js"></script>
6135			 * <script>
6136			 *     window.GreenSockGlobals = window._gsQueue = window._gsDefine = null; //reset it back to null (along with the special _gsQueue variable) so that the next load of TweenMax affects the window and we can reference things directly like TweenLite.to(...)
6137			 * </script>
6138			 * <script src="js/greensock/v1.6/TweenMax.js"></script>
6139			 * <script>
6140			 *     gs.TweenLite.to(...); //would use v1.7
6141			 *     TweenLite.to(...); //would use v1.6
6142			 * </script>
6143			 *
6144			 * @param {!string} ns The namespace of the class definition, leaving off "com.greensock." as that's assumed. For example, "TweenLite" or "plugins.CSSPlugin" or "easing.Back".
6145			 * @param {!Array.<string>}
6145 dependencies An array of dependencies (described as their namespaces minus "com.greensock." prefix). For example ["TweenLite","plugins.TweenPlugin","core.Animation"]
6146			 * @param {!function():Object} func The function that should be called and passed the resolved dependencies which will return the actual class for this definition.
6147			 * @param {boolean=} global If true, the class will be added to the global scope (typically window unless you define a window.GreenSockGlobals object)
6148			 */
6149			Definition = function(ns, dependencies, func, global) {
6150				this.sc = (_defLookup[ns]) ? _defLookup[ns].sc : []; //subclasses
6151				_defLookup[ns] = this;
6152				this.gsClass = null;
6153				this.func = func;
6154				var _classes = [];
6155				this.check = function(init) {
6156					var i = dependencies.length,
6157						missing = i,
6158						cur, a, n, cl;
6159					while (--i > -1) {
6160						if ((cur = _defLookup[dependencies[i]] || new Definition(dependencies[i], [])).gsClass) {
6161							_classes[i] = cur.gsClass;
6162							missing--;
6163						} else if (init) {
6164							cur.sc.push(this);
6165						}
6166					}
6167					if (missing === 0 && func) {
6168						a = ("com.greensock." + ns).split(".");
6169						n = a.pop();
6170						cl = _namespace(a.join("."))[n] = this.gsClass = func.apply(func, _classes);
6171
6172						//exports to multiple environments
6173						if (global) {
6174							_globals[n] = _exports[n] = cl; //provides a way to avoid global namespace pollution. By default, the main classes like TweenLite, Power1, Strong, etc. are added to window unless a GreenSockGlobals is defined. So if you want to have things added to a custom object instead, just do something like window.GreenSockGlobals = {} before loading any GreenSock files. You can even set up an alias like window.GreenSockGlobals = windows.gs = {} so that you can access everything like gs.TweenLite. Also remember that ALL classes are added to the window.com.greensock object (in their respective packages, like com.greensock.easing.Power1, com.greensock.TweenLite, etc.)
6175							if (typeof(module) !== "undefined" && module.exports) { //node
6176								if (ns === moduleName) {
6177									module.exports = _exports[moduleName] = cl;
6178									for (i in _exports) {
6179										cl[i] = _exports[i];
6180									}
6181								} else if (_exports[moduleName]) {
6182									_exports[moduleName][n] = cl;
6183								}
6184							} else if (typeof(define) === "function" && define.amd){ //AMD
6185								define((window.GreenSockAMDPath ? window.GreenSockAMDPath + "/" : "") + ns.split(".").pop(), [], function() { return cl; });
6186							}
6187						}
6188						for (i = 0; i < this.sc.length; i++) {
6189							this.sc[i].check();
6190						}
6191					}
6192				};
6193				this.check(true);
6194			},
6195
6196			//used to create Definition instances (which basically registers a class that has dependencies).
6197			_gsDefine = window._gsDefine = function(ns, dependencies, func, global) {
6198				return new Definition(ns, dependencies, func, global);
6199			},
6200
6201			//a quick way to create a class that doesn't have any dependencies. Returns the class, but first registers it in the GreenSock namespace so that other classes can grab it (other classes might be dependent on the class).
6202			_class = gs._class = function(ns, func, global) {
6203				func = func || function() {};
6204				_gsDefine(ns, [], function(){ return func; }, global);
6205				return func;
6206			};
6207
6208		_gsDefine.globals = _globals;
6209
6210
6211
6212/*
6213 * ----------------------------------------------------------------
6214 * Ease
6215 * ----------------------------------------------------------------
6216 */
6217		var _baseParams = [0, 0, 1, 1],
6218			Ease = _class("easing.Ease", function(func, extraParams, type, power) {
6219				this._func = func;
6220				this._type = type || 0;
6221				this._power = power || 0;
6222				this._params = extraParams ? _baseParams.concat(extraParams) : _baseParams;
6223			}, true),
6224			_easeMap = Ease.map = {},
6225			_easeReg = Ease.register = function(ease, names, types, create) {
6226				var na = names.split(","),
6227					i = na.length,
6228					ta = (types || "easeIn,easeOut,easeInOut").split(","),
6229					e, name, j, type;
6230				while (--i > -1) {
6231					name = na[i];
6232					e = create ? _class("easing."+name, null, true) : gs.easing[name] || {};
6233					j = ta.length;
6234					while (--j > -1) {
6235						type = ta[j];
6236						_easeMap[name + "." + type] = _easeMap[type + name] = e[type] = ease.getRatio ? ease : ease[type] || new ease();
6237					}
6238				}
6239			};
6240
6241		p = Ease.prototype;
6242		p._calcEnd = false;
6243		p.getRatio = function(p) {
6244			if (this._func) {
6245				this._params[0] = p;
6246				return this._func.apply(null, this._params);
6247			}
6248			var t = this._type,
6249				pw = this._power,
6250				r = (t === 1) ? 1 - p : (t === 2) ? p : (p < 0.5) ? p * 2 : (1 - p) * 2;
6251			if (pw === 1) {
6252				r *= r;
6253			} else if (pw === 2) {
6254				r *= r * r;
6255			} else if (pw === 3) {
6256				r *= r * r * r;
6257			} else if (pw === 4) {
6258				r *= r * r * r * r;
6259			}
6260			return (t === 1) ? 1 - r : (t === 2) ? r : (p < 0.5) ? r / 2 : 1 - (r / 2);
6261		};
6262
6263		//create all the standard eases like Linear, Quad, Cubic, Quart, Quint, Strong, Power0, Power1, Power2, Power3, and Power4 (each with easeIn, easeOut, and easeInOut)
6264		a = ["Linear","Quad","Cubic","Quart","Quint,Strong"];
6265		i = a.length;
6266		while (--i > -1) {
6267			p = a[i]+",Power"+i;
6268			_easeReg(new Ease(null,null,1,i), p, "easeOut", true);
6269			_easeReg(new Ease(null,null,2,i), p, "easeIn" + ((i === 0) ? ",easeNone" : ""));
6270			_easeReg(new Ease(null,null,3,i), p, "easeInOut");
6271		}
6272		_easeMap.linear = gs.easing.Linear.easeIn;
6273		_easeMap.swing = gs.easing.Quad.easeInOut; //for jQuery folks
6274
6275
6276/*
6277 * ----------------------------------------------------------------
6278 * EventDispatcher
6279 * ----------------------------------------------------------------
6280 */
6281		var EventDispatcher = _class("events.EventDispatcher", function(target) {
6282			this._listeners = {};
6283			this._eventTarget = target || this;
6284		});
6285		p = EventDispatcher.prototype;
6286
6287		p.addEventListener = function(type, callback, scope, useParam, priority) {
6288			priority = priority || 0;
6289			var list = this._listeners[type],
6290				index = 0,
6291				listener, i;
6292			if (this === _ticker && !_tickerActive) {
6293				_ticker.wake();
6294			}
6295			if (list == null) {
6296				this._listeners[type] = list = [];
6297			}
6298			i = list.length;
6299			while (--i > -1) {
6300				listener = list[i];
6301				if (listener.c === callback && listener.s === scope) {
6302					list.splice(i, 1);
6303				} else if (index === 0 && listener.pr < priority) {
6304					index = i + 1;
6305				}
6306			}
6307			list.splice(index, 0, {c:callback, s:scope, up:useParam, pr:priority});
6308		};
6309
6310		p.removeEventListener = function(type, callback) {
6311			var list = this._listeners[type], i;
6312			if (list) {
6313				i = list.length;
6314				while (--i > -1) {
6315					if (list[i].c === callback) {
6316						list.splice(i, 1);
6317						return;
6318					}
6319				}
6320			}
6321		};
6322
6323		p.dispatchEvent = function(type) {
6324			var list = this._listeners[type],
6325				i, t, listener;
6326			if (list) {
6327				i = list.length;
6328				if (i > 1) {
6329					list = list.slice(0); //in case addEventListener() is called from within a listener/callback (otherwise the index could change, resulting in a skip)
6330				}
6331				t = this._eventTarget;
6332				while (--i > -1) {
6333					listener = list[i];
6334					if (listener) {
6335						if (listener.up) {
6336							listener.c.call(listener.s || t, {type:type, target:t});
6337						} else {
6338							listener.c.call(listener.s || t);
6339						}
6340					}
6341				}
6342			}
6343		};
6344
6345
6346/*
6347 * ----------------------------------------------------------------
6348 * Ticker
6349 * ----------------------------------------------------------------
6350 */
6351 		var _reqAnimFrame = window.requestAnimationFrame,
6352			_cancelAnimFrame = window.cancelAnimationFrame,
6353			_getTime = Date.now || function() {return new Date().getTime();},
6354			_lastUpdate = _getTime();
6355
6356		//now try to determine the requestAnimationFrame and cancelAnimationFrame functions and if none are found, we'll use a setTimeout()/clearTimeout() polyfill.
6357		a = ["ms","moz","webkit","o"];
6358		i = a.length;
6359		while (--i > -1 && !_reqAnimFrame) {
6360			_reqAnimFrame = window[a[i] + "RequestAnimationFrame"];
6361			_cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"];
6362		}
6363
6364		_class("Ticker", function(fps, useRAF) {
6365			var _self = this,
6366				_startTime = _getTime(),
6367				_useRAF = (useRAF !== false && _reqAnimFrame) ? "auto" : false,
6368				_lagThreshold = 500,
6369				_adjustedLag = 33,
6370				_tickWord = "tick", //helps reduce gc burden
6371				_fps, _req, _id, _gap, _nextTime,
6372				_tick = function(manual) {
6373					var elapsed = _getTime() - _lastUpdate,
6374						overlap, dispatch;
6375					if (elapsed > _lagThreshold) {
6376						_startTime += elapsed - _adjustedLag;
6377					}
6378					_lastUpdate += elapsed;
6379					_self.time = (_lastUpdate - _startTime) / 1000;
6380					overlap = _self.time - _nextTime;
6381					if (!_fps || overlap > 0 || manual === true) {
6382						_self.frame++;
6383						_nextTime += overlap + (overlap >= _gap ? 0.004 : _gap - overlap);
6384						dispatch = true;
6385					}
6386					if (manual !== true) { //make sure the request is made before we dispatch the "tick" event so that timing is maintained. Otherwise, if processing the "tick" requires a bunch of time (like 15ms) and we're using a setTimeout() that's based on 16.7ms, it'd technically take 31.7ms between frames otherwise.
6387						_id = _req(_tick);
6388					}
6389					if (dispatch) {
6390						_self.dispatchEvent(_tickWord);
6391					}
6392				};
6393
6394			EventDispatcher.call(_self);
6395			_self.time = _self.frame = 0;
6396			_self.tick = function() {
6397				_tick(true);
6398			};
6399
6400			_self.lagSmoothing = function(threshold, adjustedLag) {
6401				if (!arguments.length) { //if lagSmoothing() is called with no arguments, treat it like a getter that returns a boolean indicating if it's enabled or not. This is purposely undocumented and is for internal use.
6402					return (_lagThreshold < 1 / _tinyNum);
6403				}
6404				_lagThreshold = threshold || (1 / _tinyNum); //zero should be interpreted as basically unlimited
6405				_adjustedLag = Math.min(adjustedLag, _lagThreshold, 0);
6406			};
6407
6408			_self.sleep = function() {
6409				if (_id == null) {
6410					return;
6411				}
6412				if (!_useRAF || !_cancelAnimFrame) {
6413					clearTimeout(_id);
6414				} else {
6415					_cancelAnimFrame(_id);
6416				}
6417				_req = _emptyFunc;
6418				_id = null;
6419				if (_self === _ticker) {
6420					_tickerActive = false;
6421				}
6422			};
6423
6424			_self.wake = function(seamless) {
6425				if (_id !== null) {
6426					_self.sleep();
6427				} else if (seamless) {
6428					_startTime += -_lastUpdate + (_lastUpdate = _getTime());
6429				} else if (_self.frame > 10) { //don't trigger lagSmoothing if we're just waking up, and make sure that at least 10 frames have elapsed because of the iOS bug that we work around below with the 1.5-second setTimout().
6430					_lastUpdate = _getTime() - _lagThreshold + 5;
6431				}
6432				_req = (_fps === 0) ? _emptyFunc : (!_useRAF || !_reqAnimFrame) ? function(f) { return setTimeout(f, ((_nextTime - _self.time) * 1000 + 1) | 0); } : _reqAnimFrame;
6433				if (_self === _ticker) {
6434					_tickerActive = true;
6435				}
6436				_tick(2);
6437			};
6438
6439			_self.fps = function(value) {
6440				if (!arguments.length) {
6441					return _fps;
6442				}
6443				_fps = value;
6444				_gap = 1 / (_fps || 60);
6445				_nextTime = this.time + _gap;
6446				_self.wake();
6447			};
6448
6449			_self.useRAF = function(value) {
6450				if (!arguments.length) {
6451					return _useRAF;
6452				}
6453				_self.sleep();
6454				_useRAF = value;
6455				_self.fps(_fps);
6456			};
6457			_self.fps(fps);
6458
6459			//a bug in iOS 6 Safari occasionally prevents the requestAnimationFrame from working initially, so we use a 1.5-second timeout that automatically falls back to setTimeout() if it senses this condition.
6460			setTimeout(function() {
6461				if (_useRAF === "auto" && _self.frame < 5 && (_doc || {}).visibilityState !== "hidden") {
6462					_self.useRAF(false);
6463				}
6464			}, 1500);
6465		});
6466
6467		p = gs.Ticker.prototype = new gs.events.EventDispatcher();
6468		p.constructor = gs.Ticker;
6469
6470
6471/*
6472 * ----------------------------------------------------------------
6473 * Animation
6474 * ----------------------------------------------------------------
6475 */
6476		var Animation = _class("core.Animation", function(duration, vars) {
6477				this.vars = vars = vars || {};
6478				this._duration = this._totalDuration = duration || 0;
6479				this._delay = Number(vars.delay) || 0;
6480				this._timeScale = 1;
6481				this._active = (vars.immediateRender === true);
6482				this.data = vars.data;
6483				this._reversed = (vars.reversed === true);
6484
6485				if (!_rootTimeline) {
6486					return;
6487				}
6488				if (!_tickerActive) { //some browsers (like iOS 6 Safari) shut down JavaScript execution when the tab is disabled and they [occasionally] neglect to start up requestAnimationFrame again when returning - this code ensures that the engine starts up again properly.
6489					_ticker.wake();
6490				}
6491
6492				var tl = this.vars.useFrames ? _rootFramesTimeline : _rootTimeline;
6493				tl.add(this, tl._time);
6494
6495				if (this.vars.paused) {
6496					this.paused(true);
6497				}
6498			});
6499
6500		_ticker = Animation.ticker = new gs.Ticker();
6501		p = Animation.prototype;
6502		p._dirty = p._gc = p._initted = p._paused = false;
6503		p._totalTime = p._time = 0;
6504		p._rawPrevTime = -1;
6505		p._next = p._last = p._onUpdate = p._timeline = p.timeline = null;
6506		p._paused = false;
6507
6508
6509		//some browsers (like iOS) occasionally drop the requestAnimationFrame event when the user switches to a different tab and then comes back again, so we use a 2-second setTimeout() to sense if/when that condition occurs and then wake() the ticker.
6510		var _checkTimeout = function() {
6511				if (_tickerActive && _getTime() - _lastUpdate > 2000 && ((_doc || {}).visibilityState !== "hidden" || !_ticker.lagSmoothing())) { //note: if the tab is hidden, we should still wake if lagSmoothing has been disabled.
6512					_ticker.wake();
6513				}
6514				var t = setTimeout(_checkTimeout, 2000);
6515				if (t.unref) {
6516					// allows a node process to exit even if the timeout’s callback hasn't been invoked. Without it, the node process could hang as this function is called every two seconds.
6517					t.unref();
6518				}
6519			};
6520		_checkTimeout();
6521
6522
6523		p.play = function(from, suppressEvents) {
6524			if (from != null) {
6525				this.seek(from, suppressEvents);
6526			}
6527			return this.reversed(false).paused(false);
6528		};
6529
6530		p.pause = function(atTime, suppressEvents) {
6531			if (atTime != null) {
6532				this.seek(atTime, suppressEvents);
6533			}
6534			return this.paused(true);
6535		};
6536
6537		p.resume = function(from, suppressEvents) {
6538			if (from != null) {
6539				this.seek(from, suppressEvents);
6540			}
6541			return this.paused(false);
6542		};
6543
6544		p.seek = function(time, suppressEvents) {
6545			return this.totalTime(Number(time), suppressEvents !== false);
6546		};
6547
6548		p.restart = function(includeDelay, suppressEvents) {
6549			return this.reversed(false).paused(false).totalTime(includeDelay ? -this._delay : 0, (suppressEvents !== false), true);
6550		};
6551
6552		p.reverse = function(from, suppressEvents) {
6553			if (from != null) {
6554				this.seek((from || this.totalDuration()), suppressEvents);
6555			}
6556			return this.reversed(true).paused(false);
6557		};
6558
6559		p.render = function(time, suppressEvents, force) {
6560			//stub - we override this method in subclasses.
6561		};
6562
6563		p.invalidate = function() {
6564			this._time = this._totalTime = 0;
6565			this._initted = this._gc = false;
6566			this._rawPrevTime = -1;
6567			if (this._gc || !this.timeline) {
6568				this._enabled(true);
6569			}
6570			return this;
6571		};
6572
6573		p.isActive = function() {
6574			var tl = this._timeline, //the 2 root timelines won't have a _timeline; they're always active.
6575				startTime = this._startTime,
6576				rawTime;
6577			return (!tl || (!this._gc && !this._paused && tl.isActive() && (rawTime = tl.rawTime(true)) >= startTime && rawTime < startTime + this.totalDuration() / this._timeScale - 0.0000001));
6578		};
6579
6580		p._enabled = function (enabled, ignoreTimeline) {
6581			if (!_tickerActive) {
6582				_ticker.wake();
6583			}
6584			this._gc = !enabled;
6585			this._active = this.isActive();
6586			if (ignoreTimeline !== true) {
6587				if (enabled && !this.timeline) {
6588					this._timeline.add(this, this._startTime - this._delay);
6589				} else if (!enabled && this.timeline) {
6590					this._timeline._remove(this, true);
6591				}
6592			}
6593			return false;
6594		};
6595
6596
6597		p._kill = function(vars, target) {
6598			return this._enabled(false, false);
6599		};
6600
6601		p.kill = function(vars, target) {
6602			this._kill(vars, target);
6603			return this;
6604		};
6605
6606		p._uncache = function(includeSelf) {
6607			var tween = includeSelf ? this : this.timeline;
6608			while (tween) {
6609				tween._dirty = true;
6610				tween = tween.timeline;
6611			}
6612			return this;
6613		};
6614
6615		p._swapSelfInParams = function(params) {
6616			var i = params.length,
6617				copy = params.concat();
6618			while (--i > -1) {
6619				if (params[i] === "{self}") {
6620					copy[i] = this;
6621				}
6622			}
6623			return copy;
6624		};
6625
6626		p._callback = function(type) {
6627			var v = this.vars,
6628				callback = v[type],
6629				params = v[type + "Params"],
6630				scope = v[type + "Scope"] || v.callbackScope || this,
6631				l = params ? params.length : 0;
6632			switch (l) { //speed optimization; call() is faster than apply() so use it when there are only a few parameters (which is by far most common). Previously we simply did var v = this.vars; v[type].apply(v[type + "Scope"] || v.callbackScope || this, v[type + "Params"] || _blankArray);
6633				case 0: callback.call(scope); break;
6634				case 1: callback.call(scope, params[0]); break;
6635				case 2: callback.call(scope, params[0], params[1]); break;
6636				default: callback.apply(scope, params);
6637			}
6638		};
6639
6640//----Animation getters/setters --------------------------------------------------------
6641
6642		p.eventCallback = function(type, callback, params, scope) {
6643			if ((type || "").substr(0,2) === "on") {
6644				var v = this.vars;
6645				if (arguments.length === 1) {
6646					return v[type];
6647				}
6648				if (callback == null) {
6649					delete v[type];
6650				} else {
6651					v[type] = callback;
6652					v[type + "Params"] = (_isArray(params) && params.join("").indexOf("{self}") !== -1) ? this._swapSelfInParams(params) : params;
6653					v[type + "Scope"] = scope;
6654				}
6655				if (type === "onUpdate") {
6656					this._onUpdate = callback;
6657				}
6658			}
6659			return this;
6660		};
6661
6662		p.delay = function(value) {
6663			if (!arguments.length) {
6664				return this._delay;
6665			}
6666			if (this._timeline.smoothChildTiming) {
6667				this.startTime( this._startTime + value - this._delay );
6668			}
6669			this._delay = value;
6670			return this;
6671		};
6672
6673		p.duration = function(value) {
6674			if (!arguments.length) {
6675				this._dirty = false;
6676				return this._duration;
6677			}
6678			this._duration = this._totalDuration = value;
6679			this._uncache(true); //true in case it's a TweenMax or TimelineMax that has a repeat - we'll need to refresh the totalDuration.
6680			if (this._timeline.smoothChildTiming) if (this._time > 0) if (this._time < this._duration) if (value !== 0) {
6681				this.totalTime(this._totalTime * (value / this._duration), true);
6682			}
6683			return this;
6684		};
6685
6686		p.totalDuration = function(value) {
6687			this._dirty = false;
6688			return (!arguments.length) ? this._totalDuration : this.duration(value);
6689		};
6690
6691		p.time = function(value, suppressEvents) {
6692			if (!arguments.length) {
6693				return this._time;
6694			}
6695			if (this._dirty) {
6696				this.totalDuration();
6697			}
6698			return this.totalTime((value > this._duration) ? this._duration : value, suppressEvents);
6699		};
6700
6701		p.totalTime = function(time, suppressEvents, uncapped) {
6702			if (!_tickerActive) {
6703				_ticker.wake();
6704			}
6705			if (!arguments.length) {
6706				return this._totalTime;
6707			}
6708			if (this._timeline) {
6709				if (time < 0 && !uncapped) {
6710					time += this.totalDuration();
6711				}
6712				if (this._timeline.smoothChildTiming) {
6713					if (this._dirty) {
6714						this.totalDuration();
6715					}
6716					var totalDuration = this._totalDuration,
6717						tl = this._timeline;
6718					if (time > totalDuration && !uncapped) {
6719						time = totalDuration;
6720					}
6721					this._startTime = (this._paused ? this._pauseTime : tl._time) - ((!this._reversed ? time : totalDuration - time) / this._timeScale);
6722					if (!tl._dirty) { //for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here.
6723						this._uncache(false);
6724					}
6725					//in case any of the ancestor timelines had completed but should now be enabled, we should reset the
6725ir totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The startTime of that child would get pushed out, but one of the ancestors may have completed.
6726					if (tl._timeline) {
6727						while (tl._timeline) {
6728							if (tl._timeline._time !== (tl._startTime + tl._totalTime) / tl._timeScale) {
6729								tl.totalTime(tl._totalTime, true);
6730							}
6731							tl = tl._timeline;
6732						}
6733					}
6734				}
6735				if (this._gc) {
6736					this._enabled(true, false);
6737				}
6738				if (this._totalTime !== time || this._duration === 0) {
6739					if (_lazyTweens.length) {
6740						_lazyRender();
6741					}
6742					this.render(time, suppressEvents, false);
6743					if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when someone calls seek() or time() or progress(), they expect an immediate render.
6744						_lazyRender();
6745					}
6746				}
6747			}
6748			return this;
6749		};
6750
6751		p.progress = p.totalProgress = function(value, suppressEvents) {
6752			var duration = this.duration();
6753			return (!arguments.length) ? (duration ? this._time / duration : this.ratio) : this.totalTime(duration * value, suppressEvents);
6754		};
6755
6756		p.startTime = function(value) {
6757			if (!arguments.length) {
6758				return this._startTime;
6759			}
6760			if (value !== this._startTime) {
6761				this._startTime = value;
6762				if (this.timeline) if (this.timeline._sortChildren) {
6763					this.timeline.add(this, value - this._delay); //ensures that any necessary re-sequencing of Animations in the timeline occurs to make sure the rendering order is correct.
6764				}
6765			}
6766			return this;
6767		};
6768
6769		p.endTime = function(includeRepeats) {
6770			return this._startTime + ((includeRepeats != false) ? this.totalDuration() : this.duration()) / this._timeScale;
6771		};
6772
6773		p.timeScale = function(value) {
6774			if (!arguments.length) {
6775				return this._timeScale;
6776			}
6777			var pauseTime, t;
6778			value = value || _tinyNum; //can't allow zero because it'll throw the math off
6779			if (this._timeline && this._timeline.smoothChildTiming) {
6780				pauseTime = this._pauseTime;
6781				t = (pauseTime || pauseTime === 0) ? pauseTime : this._timeline.totalTime();
6782				this._startTime = t - ((t - this._startTime) * this._timeScale / value);
6783			}
6784			this._timeScale = value;
6785			t = this.timeline;
6786			while (t && t.timeline) { //must update the duration/totalDuration of all ancestor timelines immediately in case in the middle of a render loop, one tween alters another tween's timeScale which shoves its startTime before 0, forcing the parent timeline to shift around and shiftChildren() which could affect that next tween's render (startTime). Doesn't matter for the root timeline though.
6787				t._dirty = true;
6788				t.totalDuration();
6789				t = t.timeline;
6790			}
6791			return this;
6792		};
6793
6794		p.reversed = function(value) {
6795			if (!arguments.length) {
6796				return this._reversed;
6797			}
6798			if (value != this._reversed) {
6799				this._reversed = value;
6800				this.totalTime(((this._timeline && !this._timeline.smoothChildTiming) ? this.totalDuration() - this._totalTime : this._totalTime), true);
6801			}
6802			return this;
6803		};
6804
6805		p.paused = function(value) {
6806			if (!arguments.length) {
6807				return this._paused;
6808			}
6809			var tl = this._timeline,
6810				raw, elapsed;
6811			if (value != this._paused) if (tl) {
6812				if (!_tickerActive && !value) {
6813					_ticker.wake();
6814				}
6815				raw = tl.rawTime();
6816				elapsed = raw - this._pauseTime;
6817				if (!value && tl.smoothChildTiming) {
6818					this._startTime += elapsed;
6819					this._uncache(false);
6820				}
6821				this._pauseTime = value ? raw : null;
6822				this._paused = value;
6823				this._active = this.isActive();
6824				if (!value && elapsed !== 0 && this._initted && this.duration()) {
6825					raw = tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale;
6826					this.render(raw, (raw === this._totalTime), true); //in case the target's properties changed via some other tween or manual update by the user, we should force a render.
6827				}
6828			}
6829			if (this._gc && !value) {
6830				this._enabled(true, false);
6831			}
6832			return this;
6833		};
6834
6835
6836/*
6837 * ----------------------------------------------------------------
6838 * SimpleTimeline
6839 * ----------------------------------------------------------------
6840 */
6841		var SimpleTimeline = _class("core.SimpleTimeline", function(vars) {
6842			Animation.call(this, 0, vars);
6843			this.autoRemoveChildren = this.smoothChildTiming = true;
6844		});
6845
6846		p = SimpleTimeline.prototype = new Animation();
6847		p.constructor = SimpleTimeline;
6848		p.kill()._gc = false;
6849		p._first = p._last = p._recent = null;
6850		p._sortChildren = false;
6851
6852		p.add = p.insert = function(child, position, align, stagger) {
6853			var prevTween, st;
6854			child._startTime = Number(position || 0) + child._delay;
6855			if (child._paused) if (this !== child._timeline) { //we only adjust the _pauseTime if it wasn't in this timeline already. Remember, sometimes a tween will be inserted again into the same timeline when its startTime is changed so that the tweens in the TimelineLite/Max are re-ordered properly in the linked list (so everything renders in the proper order).
6856				child._pauseTime = this.rawTime() - (child._timeline.rawTime() - child._pauseTime);
6857			}
6858			if (child.timeline) {
6859				child.timeline._remove(child, true); //removes from existing timeline so that it can be properly added to this one.
6860			}
6861			child.timeline = child._timeline = this;
6862			if (child._gc) {
6863				child._enabled(true, true);
6864			}
6865			prevTween = this._last;
6866			if (this._sortChildren) {
6867				st = child._startTime;
6868				while (prevTween && prevTween._startTime > st) {
6869					prevTween = prevTween._prev;
6870				}
6871			}
6872			if (prevTween) {
6873				child._next = prevTween._next;
6874				prevTween._next = child;
6875			} else {
6876				child._next = this._first;
6877				this._first = child;
6878			}
6879			if (child._next) {
6880				child._next._prev = child;
6881			} else {
6882				this._last = child;
6883			}
6884			child._prev = prevTween;
6885			this._recent = child;
6886			if (this._timeline) {
6887				this._uncache(true);
6888			}
6889			return this;
6890		};
6891
6892		p._remove = function(tween, skipDisable) {
6893			if (tween.timeline === this) {
6894				if (!skipDisable) {
6895					tween._enabled(false, true);
6896				}
6897
6898				if (tween._prev) {
6899					tween._prev._next = tween._next;
6900				} else if (this._first === tween) {
6901					this._first = tween._next;
6902				}
6903				if (tween._next) {
6904					tween._next._prev = tween._prev;
6905				} else if (this._last === tween) {
6906					this._last = tween._prev;
6907				}
6908				tween._next = tween._prev = tween.timeline = null;
6909				if (tween === this._recent) {
6910					this._recent = this._last;
6911				}
6912
6913				if (this._timeline) {
6914					this._uncache(true);
6915				}
6916			}
6917			return this;
6918		};
6919
6920		p.render = function(time, suppressEvents, force) {
6921			var tween = this._first,
6922				next;
6923			this._totalTime = this._time = this._rawPrevTime = time;
6924			while (tween) {
6925				next = tween._next; //record it here because the value could change after rendering...
6926				if (tween._active || (time >= tween._startTime && !tween._paused && !tween._gc)) {
6927					if (!tween._reversed) {
6928						tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
6929					} else {
6930						tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force);
6931					}
6932				}
6933				tween = next;
6934			}
6935		};
6936
6937		p.rawTime = function() {
6938			if (!_tickerActive) {
6939				_ticker.wake();
6940			}
6941			return this._totalTime;
6942		};
6943
6944/*
6945 * ----------------------------------------------------------------
6946 * TweenLite
6947 * ----------------------------------------------------------------
6948 */
6949		var TweenLite = _class("TweenLite", function(target, duration, vars) {
6950				Animation.call(this, duration, vars);
6951				this.render = TweenLite.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method)
6952
6953				if (target == null) {
6954					throw "Cannot tween a null target.";
6955				}
6956
6957				this.target = target = (typeof(target) !== "string") ? target : TweenLite.selector(target) || target;
6958
6959				var isSelector = (target.jquery || (target.length && target !== window && target[0] && (target[0] === window || (target[0].nodeType && target[0].style && !target.nodeType)))),
6960					overwrite = this.vars.overwrite,
6961					i, targ, targets;
6962
6963				this._overwrite = overwrite = (overwrite == null) ? _overwriteLookup[TweenLite.defaultOverwrite] : (typeof(overwrite) === "number") ? overwrite >> 0 : _overwriteLookup[overwrite];
6964
6965				if ((isSelector || target instanceof Array || (target.push && _isArray(target))) && typeof(target[0]) !== "number") {
6966					this._targets = targets = _slice(target);  //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
6967					this._propLookup = [];
6968					this._siblings = [];
6969					for (i = 0; i < targets.length; i++) {
6970						targ = targets[i];
6971						if (!targ) {
6972							targets.splice(i--, 1);
6973							continue;
6974						} else if (typeof(targ) === "string") {
6975							targ = targets[i--] = TweenLite.selector(targ); //in case it's an array of strings
6976							if (typeof(targ) === "string") {
6977								targets.splice(i+1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case)
6978							}
6979							continue;
6980						} else if (targ.length && targ !== window && targ[0] && (targ[0] === window || (targ[0].nodeType && targ[0].style && !targ.nodeType))) { //in case the user is passing in an array of selector objects (like jQuery objects), we need to check one more level and pull things out if necessary. Also note that <select> elements pass all the criteria regarding length and the first child having style, so we must also check to ensure the target isn't an HTML node itself.
6981							targets.splice(i--, 1);
6982							this._targets = targets = targets.concat(_slice(targ));
6983							continue;
6984						}
6985						this._siblings[i] = _register(targ, this, false);
6986						if (overwrite === 1) if (this._siblings[i].length > 1) {
6987							_applyOverwrite(targ, this, null, 1, this._siblings[i]);
6988						}
6989					}
6990
6991				} else {
6992					this._propLookup = {};
6993					this._siblings = _register(target, this, false);
6994					if (overwrite === 1) if (this._siblings.length > 1) {
6995						_applyOverwrite(target, this, null, 1, this._siblings);
6996					}
6997				}
6998				if (this.vars.immediateRender || (duration === 0 && this._delay === 0 && this.vars.immediateRender !== false)) {
6999					this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render)
7000					this.render(Math.min(0, -this._delay)); //in case delay is negative
7001				}
7002			}, true),
7003			_isSelector = function(v) {
7004				return (v && v.length && v !== window && v[0] && (v[0] === window || (v[0].nodeType && v[0].style && !v.nodeType))); //we cannot check "nodeType" if the target is window from within an iframe, otherwise it will trigger a security error in some browsers like Firefox.
7005			},
7006			_autoCSS = function(vars, target) {
7007				var css = {},
7008					p;
7009				for (p in vars) {
7010					if (!_reservedProps[p] && (!(p in target) || p === "transform" || p === "x" || p === "y" || p === "width" || p === "height" || p === "className" || p === "border") && (!_plugins[p] || (_plugins[p] && _plugins[p]._autoCSS))) { //note: <img> elements contain read-only "x" and "y" properties. We should also prioritize editing css width/height rather than the element's properties.
7011						css[p] = vars[p];
7012						delete vars[p];
7013					}
7014				}
7015				vars.css = css;
7016			};
7017
7018		p = TweenLite.prototype = new Animation();
7019		p.constructor = TweenLite;
7020		p.kill()._gc = false;
7021
7022//----TweenLite defaults, overwrite management, and root updates ----------------------------------------------------
7023
7024		p.ratio = 0;
7025		p._firstPT = p._targets = p._overwrittenProps = p._startAt = null;
7026		p._notifyPluginsOfEnabled = p._lazy = false;
7027
7028		TweenLite.version = "2.0.2";
7029		TweenLite.defaultEase = p._ease = new Ease(null, null, 1, 1);
7030		TweenLite.defaultOverwrite = "auto";
7031		TweenLite.ticker = _ticker;
7032		TweenLite.autoSleep = 120;
7033		TweenLite.lagSmoothing = function(threshold, adjustedLag) {
7034			_ticker.lagSmoothing(threshold, adjustedLag);
7035		};
7036
7037		TweenLite.selector = window.$ || window.jQuery || function(e) {
7038			var selector = window.$ || window.jQuery;
7039			if (selector) {
7040				TweenLite.selector = selector;
7041				return selector(e);
7042			}
7043			if (!_doc) { //in some dev environments (like Angular 6), GSAP gets loaded before the document is defined! So re-query it here if/when necessary.
7044				_doc = window.document;
7045			}
7046			return (!_doc) ? e : (_doc.querySelectorAll ? _doc.querySelectorAll(e) : _doc.getElementById((e.charAt(0) === "#") ? e.substr(1) : e));
7047		};
7048
7049		var _lazyTweens = [],
7050			_lazyLookup = {},
7051			_numbersExp = /(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig,
7052			_relExp = /[\+-]=-?[\.\d]/,
7053			//_nonNumbersExp = /(?:([\-+](?!(\d|=)))|[^\d\-+=e]|(e(?![\-+][\d])))+/ig,
7054			_setRatio = function(v) {
7055				var pt = this._firstPT,
7056					min = 0.000001,
7057					val;
7058				while (pt) {
7059					val = !pt.blob ? pt.c * v + pt.s : (v === 1 && this.end != null) ? this.end : v ? this.join("") : this.start;
7060					if (pt.m) {
7061						val = pt.m.call(this._tween, val, this._target || pt.t, this._tween);
7062					} else if (val < min) if (val >
7062 -min && !pt.blob) { //prevents issues with converting very small numbers to strings in the browser
7063						val = 0;
7064					}
7065					if (!pt.f) {
7066						pt.t[pt.p] = val;
7067					} else if (pt.fp) {
7068						pt.t[pt.p](pt.fp, val);
7069					} else {
7070						pt.t[pt.p](val);
7071					}
7072					pt = pt._next;
7073				}
7074			},
7075			//compares two strings (start/end), finds the numbers that are different and spits back an array representing the whole value but with the changing values isolated as elements. For example, "rgb(0,0,0)" and "rgb(100,50,0)" would become ["rgb(", 0, ",", 50, ",0)"]. Notice it merges the parts that are identical (performance optimization). The array also has a linked list of PropTweens attached starting with _firstPT that contain the tweening data (t, p, s, c, f, etc.). It also stores the starting value as a "start" property so that we can revert to it if/when necessary, like when a tween rewinds fully. If the quantity of numbers differs between the start and end, it will always prioritize the end value(s). The pt parameter is optional - it's for a PropTween that will be appended to the end of the linked list and is typically for actually setting the value after all of the elements have been updated (with array.join("")).
7076			_blobDif = function(start, end, filter, pt) {
7077				var a = [],
7078					charIndex = 0,
7079					s = "",
7080					color = 0,
7081					startNums, endNums, num, i, l, nonNumbers, currentNum;
7082				a.start = start;
7083				a.end = end;
7084				start = a[0] = start + ""; //ensure values are strings
7085				end = a[1] = end + "";
7086				if (filter) {
7087					filter(a); //pass an array with the starting and ending values and let the filter do whatever it needs to the values.
7088					start = a[0];
7089					end = a[1];
7090				}
7091				a.length = 0;
7092				startNums = start.match(_numbersExp) || [];
7093				endNums = end.match(_numbersExp) || [];
7094				if (pt) {
7095					pt._next = null;
7096					pt.blob = 1;
7097					a._firstPT = a._applyPT = pt; //apply last in the linked list (which means inserting it first)
7098				}
7099				l = endNums.length;
7100				for (i = 0; i < l; i++) {
7101					currentNum = endNums[i];
7102					nonNumbers = end.substr(charIndex, end.indexOf(currentNum, charIndex)-charIndex);
7103					s += (nonNumbers || !i) ? nonNumbers : ","; //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case.
7104					charIndex += nonNumbers.length;
7105					if (color) { //sense rgba() values and round them.
7106						color = (color + 1) % 5;
7107					} else if (nonNumbers.substr(-5) === "rgba(") {
7108						color = 1;
7109					}
7110					if (currentNum === startNums[i] || startNums.length <= i) {
7111						s += currentNum;
7112					} else {
7113						if (s) {
7114							a.push(s);
7115							s = "";
7116						}
7117						num = parseFloat(startNums[i]);
7118						a.push(num);
7119						a._firstPT = {_next: a._firstPT, t:a, p: a.length-1, s:num, c:((currentNum.charAt(1) === "=") ? parseInt(currentNum.charAt(0) + "1", 10) * parseFloat(currentNum.substr(2)) : (parseFloat(currentNum) - num)) || 0, f:0, m:(color && color < 4) ? Math.round : 0};
7120						//note: we don't set _prev because we'll never need to remove individual PropTweens from this list.
7121					}
7122					charIndex += currentNum.length;
7123				}
7124				s += end.substr(charIndex);
7125				if (s) {
7126					a.push(s);
7127				}
7128				a.setRatio = _setRatio;
7129				if (_relExp.test(end)) { //if the end string contains relative values, delete it so that on the final render (in _setRatio()), we don't actually set it to the string with += or -= characters (forces it to use the calculated value).
7130					a.end = null;
7131				}
7132				return a;
7133			},
7134			//note: "funcParam" is only necessary for function-based getters/setters that require an extra parameter like getAttribute("width") and setAttribute("width", value). In this example, funcParam would be "width". Used by AttrPlugin for example.
7135			_addPropTween = function(target, prop, start, end, overwriteProp, mod, funcParam, stringFilter, index) {
7136				if (typeof(end) === "function") {
7137					end = end(index || 0, target);
7138				}
7139				var type = typeof(target[prop]),
7140					getterName = (type !== "function") ? "" : ((prop.indexOf("set") || typeof(target["get" + prop.substr(3)]) !== "function") ? prop : "get" + prop.substr(3)),
7141					s = (start !== "get") ? start : !getterName ? target[prop] : funcParam ? target[getterName](funcParam) : target[getterName](),
7142					isRelative = (typeof(end) === "string" && end.charAt(1) === "="),
7143					pt = {t:target, p:prop, s:s, f:(type === "function"), pg:0, n:overwriteProp || prop, m:(!mod ? 0 : (typeof(mod) === "function") ? mod : Math.round), pr:0, c:isRelative ? parseInt(end.charAt(0) + "1", 10) * parseFloat(end.substr(2)) : (parseFloat(end) - s) || 0},
7144					blob;
7145
7146				if (typeof(s) !== "number" || (typeof(end) !== "number" && !isRelative)) {
7147					if (funcParam || isNaN(s) || (!isRelative && isNaN(end)) || typeof(s) === "boolean" || typeof(end) === "boolean") {
7148						//a blob (string that has multiple numbers in it)
7149						pt.fp = funcParam;
7150						blob = _blobDif(s, (isRelative ? (parseFloat(pt.s) + pt.c) + (pt.s + "").replace(/[0-9\-\.]/g, "") : end), stringFilter || TweenLite.defaultStringFilter, pt);
7151						pt = {t: blob, p: "setRatio", s: 0, c: 1, f: 2, pg: 0, n: overwriteProp || prop, pr: 0, m: 0}; //"2" indicates it's a Blob property tween. Needed for RoundPropsPlugin for example.
7152					} else {
7153						pt.s = parseFloat(s);
7154						if (!isRelative) {
7155							pt.c = (parseFloat(end) - pt.s) || 0;
7156						}
7157					}
7158				}
7159				if (pt.c) { //only add it to the linked list if there's a change.
7160					if ((pt._next = this._firstPT)) {
7161						pt._next._prev = pt;
7162					}
7163					this._firstPT = pt;
7164					return pt;
7165				}
7166			},
7167			_internals = TweenLite._internals = {isArray:_isArray, isSelector:_isSelector, lazyTweens:_lazyTweens, blobDif:_blobDif}, //gives us a way to expose certain private values to other GreenSock classes without contaminating tha main TweenLite object.
7168			_plugins = TweenLite._plugins = {},
7169			_tweenLookup = _internals.tweenLookup = {},
7170			_tweenLookupNum = 0,
7171			_reservedProps = _internals.reservedProps = {ease:1, delay:1, overwrite:1, onComplete:1, onCompleteParams:1, onCompleteScope:1, useFrames:1, runBackwards:1, startAt:1, onUp
7171date:1, onUpdateParams:1, onUpdateScope:1, onStart:1, onStartParams:1, onStartScope:1, onReverseComplete:1, onReverseCompleteParams:1, onReverseCompleteScope:1, onRepeat:1, onRepeatParams:1, onRepeatScope:1, easeParams:1, yoyo:1, immediateRender:1, repeat:1, repeatDelay:1, data:1, paused:1, reversed:1, autoCSS:1, lazy:1, onOverwrite:1, callbackScope:1, stringFilter:1, id:1, yoyoEase:1},
7172			_overwriteLookup = {none:0, all:1, auto:2, concurrent:3, allOnStart:4, preexisting:5, "true":1, "false":0},
7173			_rootFramesTimeline = Animation._rootFramesTimeline = new SimpleTimeline(),
7174			_rootTimeline = Animation._rootTimeline = new SimpleTimeline(),
7175			_nextGCFrame = 30,
7176			_lazyRender = _internals.lazyRender = function() {
7177				var i = _lazyTweens.length,
7178					tween;
7179				_lazyLookup = {};
7180				while (--i > -1) {
7181					tween = _lazyTweens[i];
7182					if (tween && tween._lazy !== false) {
7183						tween.render(tween._lazy[0], tween._lazy[1], true);
7184						tween._lazy = false;
7185					}
7186				}
7187				_lazyTweens.length = 0;
7188			};
7189
7190		_rootTimeline._startTime = _ticker.time;
7191		_rootFramesTimeline._startTime = _ticker.frame;
7192		_rootTimeline._active = _rootFramesTimeline._active = true;
7193		setTimeout(_lazyRender, 1); //on some mobile devices, there isn't a "tick" before code runs which means any lazy renders wouldn't run before the next official "tick".
7194
7195		Animation._updateRoot = TweenLite.render = function() {
7196				var i, a, p;
7197				if (_lazyTweens.length) { //if code is run outside of the requestAnimationFrame loop, there may be tweens queued AFTER the engine refreshed, so we need to ensure any pending renders occur before we refresh again.
7198					_lazyRender();
7199				}
7200				_rootTimeline.render((_ticker.time - _rootTimeline._startTime) * _rootTimeline._timeScale, false, false);
7201				_rootFramesTimeline.render((_ticker.frame - _rootFramesTimeline._startTime) * _rootFramesTimeline._timeScale, false, false);
7202				if (_lazyTweens.length) {
7203					_lazyRender();
7204				}
7205				if (_ticker.frame >= _nextGCFrame) { //dump garbage every 120 frames or whatever the user sets TweenLite.autoSleep to
7206					_nextGCFrame = _ticker.frame + (parseInt(TweenLite.autoSleep, 10) || 120);
7207					for (p in _tweenLookup) {
7208						a = _tweenLookup[p].tweens;
7209						i = a.length;
7210						while (--i > -1) {
7211							if (a[i]._gc) {
7212								a.splice(i, 1);
7213							}
7214						}
7215						if (a.length === 0) {
7216							delete _tweenLookup[p];
7217						}
7218					}
7219					//if there are no more tweens in the root timelines, or if they're all paused, make the _timer sleep to reduce load on the CPU slightly
7220					p = _rootTimeline._first;
7221					if (!p || p._paused) if (TweenLite.autoSleep && !_rootFramesTimeline._first && _ticker._listeners.tick.length === 1) {
7222						while (p && p._paused) {
7223							p = p._next;
7224						}
7225						if (!p) {
7226							_ticker.sleep();
7227						}
7228					}
7229				}
7230			};
7231
7232		_ticker.addEventListener("tick", Animation._updateRoot);
7233
7234		var _register = function(target, tween, scrub) {
7235				var id = target._gsTweenID, a, i;
7236				if (!_tweenLookup[id || (target._gsTweenID = id = "t" + (_tweenLookupNum++))]) {
7237					_tweenLookup[id] = {target:target, tweens:[]};
7238				}
7239				if (tween) {
7240					a = _tweenLookup[id].tweens;
7241					a[(i = a.length)] = tween;
7242					if (scrub) {
7243						while (--i > -1) {
7244							if (a[i] === tween) {
7245								a.splice(i, 1);
7246							}
7247						}
7248					}
7249				}
7250				return _tweenLookup[id].tweens;
7251			},
7252			_onOverwrite = function(overwrittenTween, overwritingTween, target, killedProps) {
7253				var func = overwrittenTween.vars.onOverwrite, r1, r2;
7254				if (func) {
7255					r1 = func(overwrittenTween, overwritingTween, target, killedProps);
7256				}
7257				func = TweenLite.onOverwrite;
7258				if (func) {
7259					r2 = func(overwrittenTween, overwritingTween, target, killedProps);
7260				}
7261				return (r1 !== false && r2 !== false);
7262			},
7263			_applyOverwrite = function(target, tween, props, mode, siblings) {
7264				var i, changed, curTween, l;
7265				if (mode === 1 || mode >= 4) {
7266					l = siblings.length;
7267					for (i = 0; i < l; i++) {
7268						if ((curTween = siblings[i]) !== tween) {
7269							if (!curTween._gc) {
7270								if (curTween._kill(null, target, tween)) {
7271									changed = true;
7272								}
7273							}
7274						} else if (mode === 5) {
7275							break;
7276						}
7277					}
7278					return changed;
7279				}
7280				//NOTE: Add 0.0000000001 to overcome floating point errors that can cause the startTime to be VERY slightly off (when a tween's time() is set for example)
7281				var startTime = tween._startTime + _tinyNum,
7282					overlaps = [],
7283					oCount = 0,
7284					zeroDur = (tween._duration === 0),
7285					globalStart;
7286				i = siblings.length;
7287				while (--i > -1) {
7288					if ((curTween = siblings[i]) === tween || curTween._gc || curTween._paused) {
7289						//ignore
7290					} else if (curTween._timeline !== tween._timeline) {
7291						globalStart = globalStart || _checkOverlap(tween, 0, zeroDur);
7292						if (_checkOverlap(curTween, globalStart, zeroDur) === 0) {
7293							overlaps[oCount++] = curTween;
7294						}
7295					} else if (curTween._startTime <= startTime) if (curTween._startTime + curTween.totalDuration() / curTween._timeScale > startTime) if (!((zeroDur || !curTween._initted) && startTime - curTween._startTime <= 0.0000000002)) {
7296						overlaps[oCount++] = curTween;
7297					}
7298				}
7299
7300				i = oCount;
7301				while (--i > -1) {
7302					curTween = overlaps[i];
7303					l = curTween._firstPT; //we need to discern if there were property tweens originally; if they all get removed in the next line's _kill() call, the tween should be killed. See https://github.com/greensock/GreenSock-JS/issues/278
7304					if (mode === 2) if (curTween._kill(props, target, tween)) {
7305						changed = true;
7306					}
7307					if (mode !== 2 || (!curTween._firstPT && curTween._initted && l)) {
7308						if (mode !== 2 && !_onOverwrite(curTween, tween)) {
7309							continue;
7310						}
7311						if (curTween._enabled(false, false)) { //if all property tweens have been overwritten, kill the tween.
7312							changed = true;
7313						}
7314					}
7315				}
7316				return changed;
7317			},
7318			_checkOverlap = function(tween, reference, zeroDur) {
7319				var tl = tween._timeline,
7320					ts = tl._timeScale,
7321					t = tween._startTime;
7322				while (tl._timeline) {
7323					t += tl._startTime;
7324					ts *= tl._timeScale;
7325					if (tl._paused) {
7326						return -100;
7327					}
7328					tl = tl._timeline;
7329				}
7330				t /= ts;
7331				return (t > reference) ? t - reference : ((zeroDur && t === reference) || (!tween._initted && t - reference < 2 * _tinyNum)) ? _tinyNum : ((t += tween.totalDuration() / tween._timeScale / ts) > reference + _tinyNum) ? 0 : t - reference - _tinyNum;
7332			};
7333
7334
7335//---- TweenLite instance methods -----------------------------------------------------------------------------
7336
7337		p._init = function() {
7338			var v = this.vars,
7339				op = this._overwrittenProps,
7340				dur = this._duration,
7341				immediate = !!v.immediateRender,
7342				ease = v.ease,
7343				i, initPlugins, pt, p, startVars, l;
7344			if (v.startAt) {
7345				if (this._startAt) {
7346					this._startAt.render(-1, true); //if we've run a startAt previously (when the tween instantiated), we should revert it so that the values re-instantiate correctly particularly for relative tweens. Without this, a TweenLite.fromTo(obj, 1, {x:"+=100"}, {x:"-=100"}), for example, would actually jump to +=200 because the startAt would run twice, doubling the relative change.
7347					this._startAt.kill();
7348				}
7349				startVars = {};
7350				for (p in v.startAt) { //copy the properties/values into a new object to avoid collisions, like var to = {x:0}, from = {x:500}; timeline.fromTo(e, 1, from, to).fromTo(e, 1, to, from);
7351					startVars[p] = v.startAt[p];
7352				}
7353				startVars.data = "isStart";
7354				startVars.overwrite = false;
7355				startVars.immediateRender = true;
7356				startVars.lazy = (immediate && v.lazy !== false);
7357				startVars.startAt = startVars.delay = null; //no nesting of startAt objects allowed (otherwise it could cause an infinite loop).
7358				startVars.onUpdate = v.onUpdate;
7359				startVars.onUpdateParams = v.onUpdateParams;
7360				startVars.onUpdateScope = v.onUpdateScope || v.callbackScope || this;
7361				this._startAt = TweenLite.to(this.target || {}, 0, startVars);
7362				if (immediate) {
7363					if (this._time > 0) {
7364						this._startAt = null; //tweens that render immediately (like most from() and fromTo() tweens) shouldn't revert when their parent timeline's playhead goes backward past the startTime because the initial render could have happened anytime and it shouldn't be directly correlated to this tween's startTime. Imagine setting up a complex animation where the beginning states of various objects are rendered immediately but the tween doesn't happen for quite some time - if we revert to the starting values as soon as the playhead goes backward past the tween's startTime, it will throw things off visually. Reversion should only happen in TimelineLite/Max instances where immediateRender was false (which is the default in the convenience methods like from()).
7365					} else if (dur !== 0) {
7366						return; //we skip initialization here so that overwriting doesn't occur until the tween actually begins. Otherwise, if you create several immediateRender:true tweens of the same target/properties to drop into a TimelineLite or TimelineMax, the last one created would overwrite the first ones because they didn't get placed into the timeline yet before the first render occurs and kicks in overwriting.
7367					}
7368				}
7369			} else if (v.runBackwards && dur !== 0) {
7370				//from() tweens must be handled uniquely: their beginning values must be rendered but we don't want overwriting to occur yet (when time is still 0). Wait until the tween actually begins before doing all the routines like overwriting. At that time, we should render at the END of the tween to ensure that things initialize correctly (remember, from() tweens go backwards)
7371				if (this._startAt) {
7372					this._startAt.render(-1, true);
7373					this._startAt.kill();
7374					this._startAt = null;
7375				} else {
7376					if (this._time !== 0) { //in rare cases (like if a from() tween runs and then is invalidate()-ed), immediateRender could be true but the initial forced-render gets skipped, so there's no need to force the render in this context when the _time is greater than 0
7377						immediate = false;
7378					}
7379					pt = {};
7380					for (p in v) { //copy props into a new object and skip any reserved props, otherwise onComplete or onUpdate or onStart could fire. We should, however, permit autoCSS to go through.
7381						if (!_reservedProps[p] || p === "autoCSS") {
7382							pt[p] = v[p];
7383						}
7384					}
7385					pt.overwrite = 0;
7386					pt.data = "isFromStart"; //we tag the tween with as "isFromStart" so that if [inside a plugin] we need to only do something at the very END of a tween, we have a way of identifying this tween as merely the one that's setting the beginning values for a "from()" tween. For example, clearProps in CSSPlugin should only get applied at the very END of a tween and without this tag, from(...{height:100, clearProps:"height", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in.
7387					pt.lazy = (immediate && v.lazy !== false);
7388					pt.immediateRender = immediate; //zero-duration tweens render immediately by default, but if we're not specifically instructed to render this tween immediately, we should skip this and merely _init() to record the starting values (rendering them immediately would push them to completion which is wasteful in that case - we'd have to render(-1) immediately after)
7389					this._startAt = TweenLite.to(this.target, 0, pt);
7390					if (!immediate) {
7391						this._startAt._init(); //ensures that the initial values are recorded
7392						this._startAt._enabled(false); //no need to have the tween render on the next cycle. Disable it because we'll always manually control the renders of the _startAt tween.
7393						if (this.vars.immediateRender) {
7394							this._startAt = null;
7395						}
7396					} else if (this._time === 0) {
7397						return;
7398					}
7399				}
7400			}
7401			this._ease = ease = (!ease) ? TweenLite.defaultEase : (ease instanceof Ease) ? ease : (typeof(ease) === "function") ? new Ease(ease, v.easeParams) : _easeMap[ease] || TweenLite.defaultEase;
7402			if (v.easeParams instanceof Array && ease.config) {
7403				this._ease = ease.config.apply(ease, v.easeParams);
7404			}
7405			this._easeType = this._ease._type;
7406			this._easePower = this._ease._power;
7407			this._firstPT = null;
7408
7409			if (this._targets) {
7410				l = this._targets.length;
7411				for (i = 0; i < l; i++) {
7412					if ( this._initProps( this._targets[i], (this._propLookup[i] = {}), this._siblings[i], (op ? op[i] : null), i) ) {
7413						initPlugins = true;
7414					}
7415				}
7416			} else {
7417				initPlugins = this._initProps(this.target, this._propLookup, this._siblings, op, 0);
7418			}
7419
7420			if (initPlugins) {
7421				TweenLite._onPluginEvent("_onInitAllProps", this); //reorders the array in order of priority. Uses a static TweenPlugin method in order to minimize file size in TweenLite
7422			}
7423			if (op) if (!this._firstPT) if (typeof(this.target) !== "function") { //if all tweening properties have been overwritten, kill the tween. If the target is a function, it's probably a delayedCall so let it live.
7424				this._enabled(false, false);
7425			}
7426			if (v.runBackwards) {
7427				pt = this._firstPT;
7428				while (pt) {
7429					pt.s += pt.c;
7430					pt.c = -pt.c;
7431					pt = pt._next;
7432				}
7433			}
7434			this._onUpdate = v.onUpdate;
7435			this._initted = true;
7436		};
7437
7438		p._initProps = function(target, propLookup, siblings, overwrittenProps, index) {
7439			var p, i, initPlugins, plugin, pt, v;
7440			if (target == null) {
7441				return false;
7442			}
7443
7444			if (_lazyLookup[target._gsTweenID]) {
7445				_lazyRender(); //if other tweens of the same target have recently initted but haven't rendered yet, we've got to force the render so that the starting values are correct (imagine populating a timeline with a bunch of sequential tweens and then jumping to the end)
7446			}
7447
7448			if (!this.vars.css) if (target.style) if (target !== window && target.nodeType) if (_plugins.css) if (this.vars.autoCSS !== false) { //it's so common to use TweenLite/Max to animate the css of DOM elements, we assume that if the target is a DOM element, that's what is intended (a convenience so that users don't have to wrap things in css:{}, although we still recommend it for a slight performance boost and better specificity). Note: we cannot check "nodeType" on the window inside an iframe.
7449				_autoCSS(this.vars, target);
7450			}
7451			for (p in this.vars) {
7452				v = this.vars[p];
7453				if (_reservedProps[p]) {
7454					if (v) if ((v instanceof Array) || (v.push && _isArray(v))) if (v.join("").indexOf("{self}") !== -1) {
7455						this.vars[p] = v = this._swapSelfInParams(v, this);
7456					}
7457
7458				} else if (_plugins[p] && (plugin = new _plugins[p]())._onInitTween(target, this.vars[p], this, index)) {
7459
7460					//t - target 		[object]
7461					//p - property 		[string]
7462					//s - start			[number]
7463					//c - change		[number]
7464					//f - isFunction	[boolean]
7465					//n - name			[string]
7466					//pg - isPlugin 	[boolean]
7467					//pr - priority		[number]
7468					//m - mod           [function | 0]
7469					this._firstPT = pt = {_next:this._firstPT, t:plugin, p:"setRatio", s:0, c:1, f:1, n:p, pg:1, pr:plugin._priority, m:0};
7470					i = plugin._overwriteProps.length;
7471					while (--i > -1) {
7472						propLookup[plugin._overwriteProps[i]] = this._firstPT;
7473					}
7474					if (plugin._priority || plugin._onInitAllProps) {
7475						initPlugins = true;
7476					}
7477					if (plugin._onDisable || plugin._onEnable) {
7478						this._notifyPluginsOfEnabled = true;
7479					}
7480					if (pt._next) {
7481						pt._next._prev = pt;
7482					}
7483
7484				} else {
7485					propLookup[p] = _addPropTween.call(this, target, p, "get", v, p, 0, null, this.vars.stringFilter, index);
7486				}
7487			}
7488
7489			if (overwrittenProps) if (this._kill(overwrittenProps, target)) { //another tween may have tried to overwrite properties of this tween before init() was called (like if two tweens start at the same time, the one created second will run first)
7490				return this._initProps(target, propLookup, siblings, overwrittenProps, index);
7491			}
7492			if (this._overwrite > 1) if (this._firstPT) if (siblings.length > 1) if (_applyOverwrite(target, this, propLookup, this._overwrite, siblings)) {
7493				this._kill(propLookup, target);
7494				return this._initProps(target, propLookup, siblings, overwrittenProps, index);
7495			}
7496			if (this._firstPT) if ((this.vars.lazy !== false && this._duration) || (this.vars.lazy && !this._duration)) { //zero duration tweens don't lazy render by default; everything else does.
7497				_lazyLookup[target._gsTweenID] = true;
7498			}
7499			return initPlugins;
7500		};
7501
7502		p.render = function(time, suppressEvents, force) {
7503			var prevTime = this._time,
7504				duration = this._duration,
7505				prevRawPrevTime = this._rawPrevTime,
7506				isComplete, callback, pt, rawPrevTime;
7507			if (time >= duration - 0.0000001 && time >= 0) { //to work around occasional floating point math artifacts.
7508				this._totalTime = this._time = duration;
7509				this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1;
7510				if (!this._reversed ) {
7511					isComplete = true;
7512					callback = "onComplete";
7513					force = (force || this._timeline.autoRemoveChildren); //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
7514				}
7515				if (duration === 0) if (this._initted || !this.vars.lazy || force) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
7516					if (this._startTime === this._timeline._duration) { //if a zero-duration tween is at the VERY end of a timeline and that timeline renders at its end, it will typically add a tiny bit of cushion to the render time to prevent roun
7516ding errors from getting in the way of tweens rendering their VERY end. If we then reverse() that timeline, the zero-duration tween will trigger its onReverseComplete even though technically the playhead didn't pass over it again. It's a very specific edge case we must accommodate.
7517						time = 0;
7518					}
7519					if (prevRawPrevTime < 0 || (time <= 0 && time >= -0.0000001) || (prevRawPrevTime === _tinyNum && this.data !== "isPause")) if (prevRawPrevTime !== time) { //note: when this.data is "isPause", it's a callback added by addPause() on a timeline that we should not be triggered when LEAVING its exact start time. In other words, tl.addPause(1).play(1) shouldn't pause.
7520						force = true;
7521						if (prevRawPrevTime > _tinyNum) {
7522							callback = "onReverseComplete";
7523						}
7524					}
7525					this._rawPrevTime = rawPrevTime = (!suppressEvents || time || prevRawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
7526				}
7527
7528			} else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0.
7529				this._totalTime = this._time = 0;
7530				this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
7531				if (prevTime !== 0 || (duration === 0 && prevRawPrevTime > 0)) {
7532					callback = "onReverseComplete";
7533					isComplete = this._reversed;
7534				}
7535				if (time < 0) {
7536					this._active = false;
7537					if (duration === 0) if (this._initted || !this.vars.lazy || force) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
7538						if (prevRawPrevTime >= 0 && !(prevRawPrevTime === _tinyNum && this.data === "isPause")) {
7539							force = true;
7540						}
7541						this._rawPrevTime = rawPrevTime = (!suppressEvents || time || prevRawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
7542					}
7543				}
7544				if (!this._initted || (this._startAt && this._startAt.progress())) { //if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately. Also, we check progress() because if startAt has already rendered at its end, we should force a render at its beginning. Otherwise, if you put the playhead directly on top of where a fromTo({immediateRender:false}) starts, and then move it backwards, the from() won't revert its values.
7545					force = true;
7546				}
7547			} else {
7548				this._totalTime = this._time = time;
7549
7550				if (this._easeType) {
7551					var r = time / duration, type = this._easeType, pow = this._easePower;
7552					if (type === 1 || (type === 3 && r >= 0.5)) {
7553						r = 1 - r;
7554					}
7555					if (type === 3) {
7556						r *= 2;
7557					}
7558					if (pow === 1) {
7559						r *= r;
7560					} else if (pow === 2) {
7561						r *= r * r;
7562					} else if (pow === 3) {
7563						r *= r * r * r;
7564					} else if (pow === 4) {
7565						r *= r * r * r * r;
7566					}
7567
7568					if (type === 1) {
7569						this.ratio = 1 - r;
7570					} else if (type === 2) {
7571						this.ratio = r;
7572					} else if (time / duration < 0.5) {
7573						this.ratio = r / 2;
7574					} else {
7575						this.ratio = 1 - (r / 2);
7576					}
7577
7578				} else {
7579					this.ratio = this._ease.getRatio(time / duration);
7580				}
7581			}
7582
7583			if (this._time === prevTime && !force) {
7584				return;
7585			} else if (!this._initted) {
7586				this._init();
7587				if (!this._initted || this._gc) { //immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that over
7587writing occurs properly. Also, if all of the tweening properties have been overwritten (which would cause _gc to be true, as set in _init()), we shouldn't continue otherwise an onStart callback could be called for example.
7588					return;
7589				} else if (!force && this._firstPT && ((this.vars.lazy !== false && this._duration) || (this.vars.lazy && !this._duration))) {
7590					this._time = this._totalTime = prevTime;
7591					this._rawPrevTime = prevRawPrevTime;
7592					_lazyTweens.push(this);
7593					this._lazy = [time, suppressEvents];
7594					return;
7595				}
7596				//_ease is initially set to defaultEase, so now that init() has run, _ease is set properly and we need to recalculate the ratio. Overall this is faster than using conditional logic earlier in the method to avoid having to set ratio twice because we only init() once but renderTime() gets called VERY frequently.
7597				if (this._time && !isComplete) {
7598					this.ratio = this._ease.getRatio(this._time / duration);
7599				} else if (isComplete && this._ease._calcEnd) {
7600					this.ratio = this._ease.getRatio((this._time === 0) ? 0 : 1);
7601				}
7602			}
7603			if (this._lazy !== false) { //in case a lazy render is pending, we should flush it because the new render is occurring now (imagine a lazy tween instantiating and then immediately the user calls tween.seek(tween.duration()), skipping to the end - the end render would be forced, and then if we didn't flush the lazy render, it'd fire AFTER the seek(), rendering it at the wrong time.
7604				this._lazy = false;
7605			}
7606			if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) {
7607				this._active = true;  //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done.
7608			}
7609			if (prevTime === 0) {
7610				if (this._startAt) {
7611					if (time >= 0) {
7612						this._startAt.render(time, true, force);
7613					} else if (!callback) {
7614						callback = "_dummyGS"; //if no callback is defined, use a dummy value just so that the condition at the end evaluates as true because _startAt should render AFTER the normal render loop when the time is negative. We could handle this in a more intuitive way, of course, but the render loop is the MOST important thing to optimize, so this technique allows us to avoid adding extra conditional logic in a high-frequency area.
7615					}
7616				}
7617				if (this.vars.onStart) if (this._time !== 0 || duration === 0) if (!suppressEvents) {
7618					this._callback("onStart");
7619				}
7620			}
7621			pt = this._firstPT;
7622			while (pt) {
7623				if (pt.f) {
7624					pt.t[pt.p](pt.c * this.ratio + pt.s);
7625				} else {
7626					pt.t[pt.p] = pt.c * this.ratio + pt.s;
7627				}
7628				pt = pt._next;
7629			}
7630
7631			if (this._onUpdate) {
7632				if (time < 0) if (this._startAt && time !== -0.0001) { //if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values.
7633					this._startAt.render(time, true, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete.
7634				}
7635				if (!suppressEvents) if (this._time !== prevTime || isComplete || force) {
7636					this._callback("onUpdate");
7637				}
7638			}
7639			if (callback) if (!this._gc || force) { //check _gc because there's a chance that kill() could be called in an onUpdate
7640				if (time < 0 && this._startAt && !this._onUpdate && time !== -0.0001) { //-0.0001 is a special value that we use when looping back to the beginning of a repeated TimelineMax, in which case we shouldn't render the _startAt values.
7641					this._startAt.render(time, true, force);
7642				}
7643				if (isComplete) {
7644					if (this._timeline.autoRemoveChildren) {
7645						this._enabled(false, false);
7646					}
7647					this._active = false;
7648				}
7649				if (!suppressEvents && this.vars[callback]) {
7650					this._callback(callback);
7651				}
7652				if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) { //the onComplete or onReverseComplete could trigger movement of the playhead and for zero-duration tweens (which must discern direction) that land directly back on their start time, we don't want to fire again on the next render. Think of several addPause()'s in a timeline that forces the playhead to a certain spot, but what if it's already paused and another tween is tweening the "time" of the timeline? Each time it moves [forward] past that spot, it would move back, and since suppressEvents is true, it'd reset _rawPrevTime to _tinyNum so that when it begins again, the callback would fire (so ultimately it could bounce back and forth during that tween). Again, this is a very uncommon scenario, but possible nonetheless.
7653					this._rawPrevTime = 0;
7654				}
7655			}
7656		};
7657
7658		p._kill = function(vars, target, overwritingTween) {
7659			if (vars === "all") {
7660				vars = null;
7661			}
7662			if (vars == null) if (target == null || target === this.target) {
7663				this._lazy = false;
7664				return this._enabled(false, false);
7665			}
7666			target = (typeof(target) !== "string") ? (target || this._targets || this.target) : TweenLite.selector(target) || target;
7667			var simultaneousOverwrite = (overwritingTween && this._time && overwritingTween._startTime === this._startTime && this._timeline === overwritingTween._timeline),
7668				firstPT = this._firstPT,
7669				i, overwrittenProps, p, pt, propLookup, changed, killProps, record, killed;
7670			if ((_isArray(target) || _isSelector(target)) && typeof(target[0]) !== "number") {
7671				i = target.length;
7672				while (--i > -1) {
7673					if (this._kill(vars, target[i], overwritingTween)) {
7674						changed = true;
7675					}
7676				}
7677			} else {
7678				if (this._targets) {
7679					i = this._targets.length;
7680					while (--i > -1) {
7681						if (target === this._targets[i]) {
7682							propLookup = this._propLookup[i] || {};
7683							this._overwrittenProps = this._overwrittenProps || [];
7684							overwrittenProps = this._overwrittenProps[i] = vars ? this._overwrittenProps[i] || {} : "all";
7685							break;
7686						}
7687					}
7688				} else if (target !== this.target) {
7689					return false;
7690				} else {
7691					propLookup = this._propLookup;
7692					overwrittenProps = this._overwrittenProps = vars ? this._overwrittenProps || {} : "all";
7693				}
7694
7695				if (propLookup) {
7696					killProps = vars || propLookup;
7697					record = (vars !== overwrittenProps && overwrittenProps !== "all" && vars !== propLookup && (typeof(vars) !== "object" || !vars._tempKill)); //_tempKill is a super-secret way to delete a particular tweening property but NOT have it remembered as an official overwritten property (like in BezierPlugin)
7698					if (overwritingTween && (TweenLite.onOverwrite || this.vars.onOverwrite)) {
7699						for (p in killProps) {
7700							if (propLookup[p]) {
7701								if (!killed) {
7702									killed = [];
7703								}
7704								killed.push(p);
7705							}
7706						}
7707						if ((killed || !vars) && !_onOverwrite(this, overwritingTween, target, killed)) { //if the onOverwrite returned false, that means the user wants to override the overwriting (cancel it).
7708							return false;
7709						}
7710					}
7711
7712					for (p in killProps) {
7713						if ((pt = propLookup[p])) {
7714							if (simultaneousOverwrite) { //if another tween overwrites this one and they both start at exactly the same time, yet this tween has already rendered once (for example, at 0.001) because it's first in the queue, we should revert the values to where they were at 0 so that the starting values aren't contaminated on the overwriting tween.
7715								if (pt.f) {
7716									pt.t[pt.p](pt.s);
7717								} else {
7718									pt.t[pt.p] = pt.s;
7719								}
7720								changed = true;
7721							}
7722							if (pt.pg && pt.t._kill(killProps)) {
7723								changed = true; //some plugins need to be notified so they can perform cleanup tasks first
7724							}
7725							if (!pt.pg || pt.t._overwriteProps.length === 0) {
7726								if (pt._prev) {
7727									pt._prev._next = pt._next;
7728								} else if (pt === this._firstPT) {
7729									this._firstPT = pt._next;
7730								}
7731								if (pt._next) {
7732									pt._next._prev = pt._prev;
7733								}
7734								pt._next = pt._prev = null;
7735							}
7736							delete propLookup[p];
7737						}
7738						if (record) {
7739							overwrittenProps[p] = 1;
7740						}
7741					}
7742					if (!this._firstPT && this._initted && firstPT) { //if all tweening properties are killed, kill the tween. Without this line, if there's a tween with multiple targets and then you killTweensOf() each target individually, the tween would technically still remain active and fire its onComplete even though there aren't any more properties tweening.
7743						this._enabled(false, false);
7744					}
7745				}
7746			}
7747			return changed;
7748		};
7749
7750		p.invalidate = function() {
7751			if (this._notifyPluginsOfEnabled) {
7752				TweenLite._onPluginEvent("_onDisable", this);
7753			}
7754			this._firstPT = this._overwrittenProps = this._startAt = this._onUpdate = null;
7755			this._notifyPluginsOfEnabled = this._active = this._lazy = false;
7756			this._propLookup = (this._targets) ? {} : [];
7757			Animation.prototype.invalidate.call(this);
7758			if (this.vars.immediateRender) {
7759				this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render)
7760				this.render(Math.min(0, -this._delay)); //in case delay is negative.
7761			}
7762			return this;
7763		};
7764
7765		p._enabled = function(enabled, ignoreTimeline) {
7766			if (!_tickerActive) {
7767				_ticker.wake();
7768			}
7769			if (enabled && this._gc) {
7770				var targets = this._targets,
7771					i;
7772				if (targets) {
7773					i = targets.length;
7774					while (--i > -1) {
7775						this._siblings[i] = _register(targets[i], this, true);
7776					}
7777				} else {
7778					this._siblings = _register(this.target, this, true);
7779				}
7780			}
7781			Animation.prototype._enabled.call(this, enabled, ignoreTimeline);
7782			if (this._notifyPluginsOfEnabled) if (this._firstPT) {
7783				return TweenLite._onPluginEvent((enabled ? "_onEnable" : "_onDisable"), this);
7784			}
7785			return false;
7786		};
7787
7788
7789//----TweenLite static methods -----------------------------------------------------
7790
7791		TweenLite.to = function(target, duration, vars) {
7792			return new TweenLite(target, duration, vars);
7793		};
7794
7795		TweenLite.from = function(target, duration, vars) {
7796			vars.runBackwards = true;
7797			vars.immediateRender = (vars.immediateRender != false);
7798			return new TweenLite(target, duration, vars);
7799		};
7800
7801		TweenLite.fromTo = function(target, duration, fromVars, toVars) {
7802			toVars.startAt = fromVars;
7803			toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false);
7804			return new TweenLite(target, duration, toVars);
7805		};
7806
7807		TweenLite.delayedCall = function(delay, callback, params, scope, useFrames) {
7808			return new TweenLite(callback, 0, {delay:delay, onComplete:callback, onCompleteParams:params, callbackScope:scope, onReverseComplete:callback, onReverseCompleteParams:params, immediateRender:false, lazy:false, useFrames:useFrames, overwrite:0});
7809		};
7810
7811		TweenLite.set = function(target, vars) {
7812			return new TweenLite(target, 0, vars);
7813		};
7814
7815		TweenLite.getTweensOf = function(target, onlyActive) {
7816			if (target == null) { return []; }
7817			target = (typeof(target) !== "string") ? target : TweenLite.selector(target) || target;
7818			var i, a, j, t;
7819			if ((_isArray(target) || _isSelector(target)) && typeof(target[0]) !== "number") {
7820				i = target.length;
7821				a = [];
7822				while (--i > -1) {
7823					a = a.concat(TweenLite.getTweensOf(target[i], onlyActive));
7824				}
7825				i = a.length;
7826				//now get rid of any duplicates (tweens of arrays of objects could cause duplicates)
7827				while (--i > -1) {
7828					t = a[i];
7829					j = i;
7830					while (--j > -1) {
7831						if (t === a[j]) {
7832							a.splice(i, 1);
7833						}
7834					}
7835				}
7836			} else if (target._gsTweenID) {
7837				a = _register(target).concat();
7838				i = a.length;
7839				while (--i > -1) {
7840					if (a[i]._gc || (onlyActive && !a[i].isActive())) {
7841						a.splice(i, 1);
7842					}
7843				}
7844			}
7845			return a || [];
7846		};
7847
7848		TweenLite.killTweensOf = TweenLite.killDelayedCallsTo = function(target, onlyActive, vars) {
7849			if (typeof(onlyActive) === "object") {
7850				vars = onlyActive; //for backwards compatibility (before "onlyActive" parameter was inserted)
7851				onlyActive = false;
7852			}
7853			var a = TweenLite.getTweensOf(target, onlyActive),
7854				i = a.length;
7855			while (--i > -1) {
7856				a[i]._kill(vars, target);
7857			}
7858		};
7859
7860
7861
7862/*
7863 * ----------------------------------------------------------------
7864 * TweenPlugin   (could easily be split out as a separate file/class, but included for ease of use (so that people don't need to include another script call before loading plugins which is easy to forget)
7865 * ----------------------------------------------------------------
7866 */
7867		var TweenPlugin = _class("plugins.TweenPlugin", function(props, priority) {
7868					this._overwriteProps = (props || "").split(",");
7869					this._propName = this._overwriteProps[0];
7870					this._priority = priority || 0;
7871					this._super = TweenPlugin.prototype;
7872				}, true);
7873
7874		p = TweenPlugin.prototype;
7875		TweenPlugin.version = "1.19.0";
7876		TweenPlugin.API = 2;
7877		p._firstPT = null;
7878		p._addTween = _addPropTween;
7879		p.setRatio = _setRatio;
7880
7881		p._kill = function(lookup) {
7882			var a = this._overwriteProps,
7883				pt = this._firstPT,
7884				i;
7885			if (lookup[this._propName] != null) {
7886				this._overwriteProps = [];
7887			} else {
7888				i = a.length;
7889				while (--i > -1) {
7890					if (lookup[a[i]] != null) {
7891						a.splice(i, 1);
7892					}
7893				}
7894			}
7895			while (pt) {
7896				if (lookup[pt.n] != null) {
7897					if (pt._next) {
7898						pt._next._prev = pt._prev;
7899					}
7900					if (pt._prev) {
7901						pt._prev._next = pt._next;
7902						pt._prev = null;
7903					} else if (this._firstPT === pt) {
7904						this._firstPT = pt._next;
7905					}
7906				}
7907				pt = pt._next;
7908			}
7909			return false;
7910		};
7911
7912		p._mod = p._roundProps = function(lookup) {
7913			var pt = this._firstPT,
7914				val;
7915			while (pt) {
7916				val = lookup[this._propName] || (pt.n != null && lookup[ pt.n.split(this._propName + "_").join("") ]);
7917				if (val && typeof(val) === "function") { //some properties that are very plugin-specific add a prefix named after the _propName plus an underscore, so we need to ignore that extra stuff here.
7918					if (pt.f === 2) {
7919						pt.t._applyPT.m = val;
7920					} else {
7921						pt.m = val;
7922					}
7923				}
7924				pt = pt._next;
7925			}
7926		};
7927
7928		TweenLite._onPluginEvent = function(type, tween) {
7929			var pt = tween._firstPT,
7930				changed, pt2, first, last, next;
7931			if (type === "_onInitAllProps") {
7932				//sorts the PropTween linked list in order of priority because some plugins need to render earlier/later than others, like MotionBlurPlugin applies its effects after all x/y/alpha tweens have rendered on each frame.
7933				while (pt) {
7934					next = pt._next;
7935					pt2 = first;
7936					while (pt2 && pt2.pr > pt.pr) {
7937						pt2 = pt2._next;
7938					}
7939					if ((pt._prev = pt2 ? pt2._prev : last)) {
7940						pt._prev._next = pt;
7941					} else {
7942						first = pt;
7943					}
7944					if ((pt._next = pt2)) {
7945						pt2._prev = pt;
7946					} else {
7947						last = pt;
7948					}
7949					pt = next;
7950				}
7951				pt = tween._firstPT = first;
7952			}
7953			while (pt) {
7954				if (pt.pg) if (typeof(pt.t[type]) === "function") if (pt.t[type]()) {
7955					changed = true;
7956				}
7957				pt = pt._next;
7958			}
7959			return changed;
7960		};
7961
7962		TweenPlugin.activate = function(plugins) {
7963			var i = plugins.length;
7964			while (--i > -1) {
7965				if (plugins[i].API === TweenPlugin.API) {
7966					_plugins[(new plugins[i]())._propName] = plugins[i];
7967				}
7968			}
7969			return true;
7970		};
7971
7972		//provides a more concise way to define plugins that have no dependencies besides TweenPlugin and TweenLite, wrapping common boilerplate stuff into one function (added in 1.9.0). You don't NEED to use this to define a plugin - the old way still works and can be useful in certain (rare) situations.
7973		_gsDefine.plugin = function(config) {
7974			if (!config || !config.propName || !config.init || !config.API) { throw "illegal plugin definition."; }
7975			var propName = config.propName,
7976				priority = config.priority || 0,
7977				overwriteProps = config.overwriteProps,
7978				map = {init:"_onInitTween", set:"setRatio", kill:"_kill", round:"_mod", mod:"_mod", initAll:"_onInitAllProps"},
7979				Plugin = _class("plugins." + propName.charAt(0).toUpperCase() + propName.substr(1) + "Plugin",
7980					function() {
7981						TweenPlugin.call(this, propName, priority);
7982						this._overwriteProps = overwriteProps || [];
7983					}, (config.global === true)),
7984				p = Plugin.prototype = new TweenPlugin(propName),
7985				prop;
7986			p.constructor = Plugin;
7987			Plugin.API = config.API;
7988			for (prop in map) {
7989				if (typeof(config[prop]) === "function") {
7990					p[map[prop]] = config[prop];
7991				}
7992			}
7993			Plugin.version = config.version;
7994			TweenPlugin.activate([Plugin]);
7995			return Plugin;
7996		};
7997
7998
7999		//now run through all the dependencies discovered and if any are missing, log that to the console as a warning. This is why it's best to have TweenLite load last - it can check all the dependencies for you.
8000		a = window._gsQueue;
8001		if (a) {
8002			for (i = 0; i < a.length; i++) {
8003				a[i]();
8004			}
8005			for (p in _defLookup) {
8006				if (!_defLookup[p].func) {
8007					window.console.log("GSAP encountered missing dependency: " + p);
8008				}
8009			}
8010		}
8011
8012		_tickerActive = false; //ensures that the first official animation forces a ticker.tick() to update the time when it is instantiated
8013
8014})((typeof(module) !== "undefined" && module.exports && typeof(global) !== "undefined") ? global : this || window, "TweenMax");

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.