PageSourceSearch

https://e-donghak.or.kr/main/jscss/TweenMax.js?ver=1790974881

js e-donghak.or.kr collected 2026-10-02 21:04:49 UTC 343,901 bytes, 7,572 lines download raw bytes

1/*!
2 * VERSION: 1.18.0
3 * DATE: 2015-09-05
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-2015, 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.call(targets[i], 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);
41				this._repeat = this.vars.repeat || 0;
42				this._repeatDelay = this.vars.repeatDelay || 0;
43				this._dirty = true; //ensures that if there is any repeat, the totalDuration will get recalculated to accurately report it.
44				this.render = TweenMax.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method)
45			},
46			_tinyNum = 0.0000000001,
47			TweenLiteInternals = TweenLite._internals,
48			_isSelector = TweenLiteInternals.isSelector,
49			_isArray = TweenLiteInternals.isArray,
50			p = TweenMax.prototype = TweenLite.to({}, 0.1, {}),
51			_blankArray = [];
52
53		TweenMax.version = "1.18.0";
54		p.constructor = TweenMax;
55		p.kill()._gc = false;
56		TweenMax.killTweensOf = TweenMax.killDelayedCallsTo = TweenLite.killTweensOf;
57		TweenMax.getTweensOf = TweenLite.getTweensOf;
58		TweenMax.lagSmoothing = TweenLite.lagSmoothing;
59		TweenMax.ticker = TweenLite.ticker;
60		TweenMax.render = TweenLite.render;
61
62		p.invalidate = function() {
63			this._yoyo = (this.vars.yoyo === true);
64			this._repeat = this.vars.repeat || 0;
65			this._repeatDelay = this.vars.repeatDelay || 0;
66			this._uncache(true);
67			return TweenLite.prototype.invalidate.call(this);
68		};
69		
70		p.updateTo = function(vars, resetDuration) {
71			var curRatio = this.ratio,
72				immediate = this.vars.immediateRender || vars.immediateRender,
73				p;
74			if (resetDuration && this._startTime < this._timeline._time) {
75				this._startTime = this._timeline._time;
76				this._uncache(false);
77				if (this._gc) {
78					this._enabled(true, false);
79				} else {
80					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.
81				}
82			}
83			for (p in vars) {
84				this.vars[p] = vars[p];
85			}
86			if (this._initted || immediate) {
87				if (resetDuration) {
88					this._initted = false;
89					if (immediate) {
90						this.render(0, true, true);
91					}
92				} else {
93					if (this._gc) {
94						this._enabled(true, false);
95					}
96					if (this._notifyPluginsOfEnabled && this._firstPT) {
97						TweenLite._onPluginEvent("_onDisable", this); //in case a plugin like MotionBlur must perform some cleanup tasks
98					}
99					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. 
100						var prevTime = this._time;
101						this.render(0, true, false);
102						this._initted = false;
103						this.render(prevTime, true, false);
104					} else if (this._time > 0 || immediate) {
105						this._initted = false;
106						this._init();
107						var inv = 1 / (1 - curRatio),
108							pt = this._firstPT, endValue;
109						while (pt) {
110							endValue = pt.s + pt.c; 
111							pt.c *= inv;
112							pt.s = endValue - pt.c;
113							pt = pt._next;
114						}
115					}
116				}
117			}
118			return this;
119		};
120				
121		p.render = function(time, suppressEvents, force) {
122			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.
123				this.invalidate();
124			}
125			var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(),
126				prevTime = this._time,
127				prevTotalTime = this._totalTime, 
128				prevCycle = this._cycle,
129				duration = this._duration,
130				prevRawPrevTime = this._rawPrevTime,
131				isComplete, callback, pt, cycleDuration, r, type, pow, rawPrevTime;
132			if (time >= totalDur) {
133				this._totalTime = totalDur;
134				this._cycle = this._repeat;
135				if (this._yoyo && (this._cycle & 1) !== 0) {
136					this._time = 0;
137					this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
138				} else {
139					this._time = duration;
140					this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1;
141				}
142				if (!this._reversed) {
143					isComplete = true;
144					callback = "onComplete";
145					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.
146				}
147				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.
148					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.
149						time = 0;
150					}
151					if (time === 0 || prevRawPrevTime < 0 || prevRawPrevTime === _tinyNum) if (prevRawPrevTime !== time) {
152						force = true;
153						if (prevRawPrevTime > _tinyNum) {
154							callback = "onReverseComplete";
155						}
156					}
157					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.
158				}
159				
160			} else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0.
161				this._totalTime = this._time = this._cycle = 0;
162				this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
163				if (prevTotalTime !== 0 || (duration === 0 && prevRawPrevTime > 0)) {
164					callback = "onReverseComplete";
165					isComplete = this._reversed;
166				}
167				if (time < 0) {
168					this._active = false;
169					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.
170						if (prevRawPrevTime >= 0) {
171							force = true;
172						}
173						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.
174					}
175				}
176				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.
177					force = true;
178				}
179			} else {
180				this._totalTime = this._time = time;
181				
182				if (this._repeat !== 0) {
183					cycleDuration = duration + this._repeatDelay;
184					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 Flash reports it as 0.79999999!)
185					if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration) {
186						this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning)
187					}
188					this._time = this._totalTime - (this._cycle * cycleDuration);
189					if (this._yoyo) if ((this._cycle & 1) !== 0) {
190						this._time = duration - this._time;
191					}
192					if (this._time > duration) {
193						this._time = duration;
194					} else if (this._time < 0) {
195						this._time = 0;
196					}
197				}
198
199				if (this._easeType) {
200					r = this._time / duration;
201					type = this._easeType;
202					pow = this._easePower;
203					if (type === 1 || (type === 3 && r >= 0.5)) {
204						r = 1 - r;
205					}
206					if (type === 3) {
207						r *= 2;
208					}
209					if (pow === 1) {
210						r *= r;
211					} else if (pow === 2) {
212						r *= r * r;
213					} else if (pow === 3) {
214						r *= r * r * r;
215					} else if (pow === 4) {
216						r *= r * r * r * r;
217					}
218
219					if (type === 1) {
220						this.ratio = 1 - r;
221					} else if (type === 2) {
222						this.ratio = r;
223					} else if (this._time / duration < 0.5) {
224						this.ratio = r / 2;
225					} else {
226						this.ratio = 1 - (r / 2);
227					}
228
229				} else {
230					this.ratio = this._ease.getRatio(this._time / duration);
231				}
232				
233			}
234				
235			if (prevTime === this._time && !force && prevCycle === this._cycle) {
236				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.
237					this._callback("onUpdate");
238				}
239				return;
240			} else if (!this._initted) {
241				this._init();
242				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
242writing 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.
243					return;
244				} 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.
245					this._time = prevTime;
246					this._totalTime = prevTotalTime;
247					this._rawPrevTime = prevRawPrevTime;
248					this._cycle = prevCycle;
249					TweenLiteInternals.lazyTweens.push(this);
250					this._lazy = [time, suppressEvents];
251					return;
252				}
253				//_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.
254				if (this._time && !isComplete) {
255					this.ratio = this._ease.getRatio(this._time / duration);
256				} else if (isComplete && this._ease._calcEnd) {
257					this.ratio = this._ease.getRatio((this._time === 0) ? 0 : 1);
258				}
259			}
260			if (this._lazy !== false) {
261				this._lazy = false;
262			}
263
264			if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) {
265				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.
266			}
267			if (prevTotalTime === 0) {
268				if (this._initted === 2 && time > 0) {
269					//this.invalidate();
270					this._init(); //will just apply overwriting since _initted of (2) means it was a from() tween that had immediateRender:true
271				}
272				if (this._startAt) {
273					if (time >= 0) {
274						this._startAt.render(time, suppressEvents, force);
275					} else if (!callback) {
276						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.
277					}
278				}
279				if (this.vars.onStart) if (this._totalTime !== 0 || duration === 0) if (!suppressEvents) {
280					this._callback("onStart");
281				}
282			}
283			
284			pt = this._firstPT;
285			while (pt) {
286				if (pt.f) {
287					pt.t[pt.p](pt.c * this.ratio + pt.s);
288				} else {
289					pt.t[pt.p] = pt.c * this.ratio + pt.s;
290				}
291				pt = pt._next;
292			}
293			
294			if (this._onUpdate) {
295				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.
296					this._startAt.render(time, suppressEvents, 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.
297				}
298				if (!suppressEvents) if (this._totalTime !== prevTotalTime || isComplete) {
299					this._callback("onUpdate");
300				}
301			}
302			if (this._cycle !== prevCycle) if (!suppressEvents) if (!this._gc) if (this.vars.onRepeat) {
303				this._callback("onRepeat");
304			}
305			if (callback) if (!this._gc || force) { //check gc because there's a chance that kill() could be called in an onUpdate
306				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.
307					this._startAt.render(time, suppressEvents, force);
308				}
309				if (isComplete) {
310					if (this._timeline.autoRemoveChildren) {
311						this._enabled(false, false);
312					}
313					this._active = false;
314				}
315				if (!suppressEvents && this.vars[callback]) {
316					this._callback(callback);
317				}
318				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
318nario, but possible nonetheless.
319					this._rawPrevTime = 0;
320				}
321			}
322		};
323		
324//---- STATIC FUNCTIONS -----------------------------------------------------------------------------------------------------------
325		
326		TweenMax.to = function(target, duration, vars) {
327			return new TweenMax(target, duration, vars);
328		};
329		
330		TweenMax.from = function(target, duration, vars) {
331			vars.runBackwards = true;
332			vars.immediateRender = (vars.immediateRender != false);
333			return new TweenMax(target, duration, vars);
334		};
335		
336		TweenMax.fromTo = function(target, duration, fromVars, toVars) {
337			toVars.startAt = fromVars;
338			toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false);
339			return new TweenMax(target, duration, toVars);
340		};
341		
342		TweenMax.staggerTo = TweenMax.allTo = function(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
343			stagger = stagger || 0;
344			var delay = vars.delay || 0,
345				a = [],
346				finalComplete = function() {
347					if (vars.onComplete) {
348						vars.onComplete.apply(vars.onCompleteScope || this, arguments);
349					}
350					onCompleteAll.apply(onCompleteAllScope || vars.callbackScope || this, onCompleteAllParams || _blankArray);
351				},
352				cycle = vars.cycle,
353				fromCycle = (vars.startAt && vars.startAt.cycle),
354				l, copy, i, p;
355			if (!_isArray(targets)) {
356				if (typeof(targets) === "string") {
357					targets = TweenLite.selector(targets) || targets;
358				}
359				if (_isSelector(targets)) {
360					targets = _slice(targets);
361				}
362			}
363			targets = targets || [];
364			if (stagger < 0) {
365				targets = _slice(targets);
366				targets.reverse();
367				stagger *= -1;
368			}
369			l = targets.length - 1;
370			for (i = 0; i <= l; i++) {
371				copy = {};
372				for (p in vars) {
373					copy[p] = vars[p];
374				}
375				if (cycle) {
376					_applyCycle(copy, targets, i);
377				}
378				if (fromCycle) {
379					fromCycle = copy.startAt = {};
380					for (p in vars.startAt) {
381						fromCycle[p] = vars.startAt[p];
382					}
383					_applyCycle(copy.startAt, targets, i);
384				}
385				copy.delay = delay;
386				if (i === l && onCompleteAll) {
387					copy.onComplete = finalComplete;
388				}
389				a[i] = new TweenMax(targets[i], duration, copy);
390				delay += stagger;
391			}
392			return a;
393		};
394		
395		TweenMax.staggerFrom = TweenMax.allFrom = function(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
396			vars.runBackwards = true;
397			vars.immediateRender = (vars.immediateRender != false);
398			return TweenMax.staggerTo(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
399		};
400		
401		TweenMax.staggerFromTo = TweenMax.allFromTo = function(targets, duration, fromVars, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
402			toVars.startAt = fromVars;
403			toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false);
404			return TweenMax.staggerTo(targets, duration, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
405		};
406				
407		TweenMax.delayedCall = function(delay, callback, params, scope, useFrames) {
408			return new TweenMax(callback, 0, {delay:delay, onComplete:callback, onCompleteParams:params, callbackScope:scope, onReverseComplete:callback, onReverseCompleteParams:params, immediateRender:false, useFrames:useFrames, overwrite:0});
409		};
410		
411		TweenMax.set = function(target, vars) {
412			return new TweenMax(target, 0, vars);
413		};
414		
415		TweenMax.isTweening = function(target) {
416			return (TweenLite.getTweensOf(target, true).length > 0);
417		};
418		
419		var _getChildrenOf = function(timeline, includeTimelines) {
420				var a = [],
421					cnt = 0,
422					tween = timeline._first;
423				while (tween) {
424					if (tween instanceof TweenLite) {
425						a[cnt++] = tween;
426					} else {
427						if (includeTimelines) {
428							a[cnt++] = tween;
429						}
430						a = a.concat(_getChildrenOf(tween, includeTimelines));
431						cnt = a.length;
432					}
433					tween = tween._next;
434				}
435				return a;
436			}, 
437			getAllTweens = TweenMax.getAllTweens = function(includeTimelines) {
438				return _getChildrenOf(Animation._rootTimeline, includeTimelines).concat( _getChildrenOf(Animation._rootFramesTimeline, includeTimelines) );
439			};
440		
441		TweenMax.killAll = function(complete, tweens, delayedCalls, timelines) {
442			if (tweens == null) {
443				tweens = true;
444			}
445			if (delayedCalls == null) {
446				delayedCalls = true;
447			}
448			var a = getAllTweens((timelines != false)),
449				l = a.length,
450				allTrue = (tweens && delayedCalls && timelines),
451				isDC, tween, i;
452			for (i = 0; i < l; i++) {
453				tween = a[i];
454				if (allTrue || (tween instanceof SimpleTimeline) || ((isDC = (tween.target === tween.vars.onComplete)) && delayedCalls) || (tweens && !isDC)) {
455					if (complete) {
456						tween.totalTime(tween._reversed ? 0 : tween.totalDuration());
457					} else {
458						tween._enabled(false, false);
459					}
460				}
461			}
462		};
463		
464		TweenMax.killChildTweensOf = function(parent, complete) {
465			if (parent == null) {
466				return;
467			}
468			var tl = TweenLiteInternals.tweenLookup,
469				a, curParent, p, i, l;
470			if (typeof(parent) === "string") {
471				parent = TweenLite.selector(parent) || parent;
472			}
473			if (_isSelector(parent)) {
474				parent = _slice(parent);
475			}
476			if (_isArray(parent)) {
477				i = parent.length;
478				while (--i > -1) {
479					TweenMax.killChildTweensOf(parent[i], complete);
480				}
481				return;
482			}
483			a = [];
484			for (p in tl) {
485				curParent = tl[p].target.parentNode;
486				while (curParent) {
487					if (curParent === parent) {
488						a = a.concat(tl[p].tweens);
489					}
490					curParent = curParent.parentNode;
491				}
492			}
493			l = a.length;
494			for (i = 0; i < l; i++) {
495				if (complete) {
496					a[i].totalTime(a[i].totalDuration());
497				}
498				a[i]._enabled(false, false);
499			}
500		};
501
502		var _changePause = function(pause, tweens, delayedCalls, timelines) {
503			tweens = (tweens !== false);
504			delayedCalls = (delayedCalls !== false);
505			timelines = (timelines !== false);
506			var a = getAllTweens(timelines),
507				allTrue = (tweens && delayedCalls && timelines),
508				i = a.length,
509				isDC, tween;
510			while (--i > -1) {
511				tween = a[i];
512				if (allTrue || (tween instanceof SimpleTimeline) || ((isDC = (tween.target === tween.vars.onComplete)) && delayedCalls) || (tweens && !isDC)) {
513					tween.paused(pause);
514				}
515			}
516		};
517		
518		TweenMax.pauseAll = function(tweens, delayedCalls, timelines) {
519			_changePause(true, tweens, delayedCalls, timelines);
520		};
521		
522		TweenMax.resumeAll = function(tweens, delayedCalls, timelines) {
523			_changePause(false, tweens, delayedCalls, timelines);
524		};
525
526		TweenMax.globalTimeScale = function(value) {
527			var tl = Animation._rootTimeline,
528				t = TweenLite.ticker.time;
529			if (!arguments.length) {
530				return tl._timeScale;
531			}
532			value = value || _tinyNum; //can't allow zero because it'll throw the math off
533			tl._startTime = t - ((t - tl._startTime) * tl._timeScale / value);
534			tl = Animation._rootFramesTimeline;
535			t = TweenLite.ticker.frame;
536			tl._startTime = t - ((t - tl._startTime) * tl._timeScale / value);
537			tl._timeScale = Animation._rootTimeline._timeScale = value;
538			return value;
539		};
540		
541	
542//---- GETTERS / SETTERS ----------------------------------------------------------------------------------------------------------
543		
544		p.progress = function(value) {
545			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)), false);
546		};
547		
548		p.totalProgress = function(value) {
549			return (!arguments.length) ? this._totalTime / this.totalDuration() : this.totalTime( this.totalDuration() * value, false);
550		};
551		
552		p.time = function(value, suppressEvents) {
553			if (!arguments.length) {
554				return this._time;
555			}
556			if (this._dirty) {
557				this.totalDuration();
558			}
559			if (value > this._duration) {
560				value = this._duration;
561			}
562			if (this._yoyo && (this._cycle & 1) !== 0) {
563				value = (this._duration - value) + (this._cycle * (this._duration + this._repeatDelay));
564			} else if (this._repeat !== 0) {
565				value += this._cycle * (this._duration + this._repeatDelay);
566			}
567			return this.totalTime(value, suppressEvents);
568		};
569
570		p.duration = function(value) {
571			if (!arguments.length) {
572				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.
573			}
574			return Animation.prototype.duration.call(this, value);
575		};
576
577		p.totalDuration = function(value) {
578			if (!arguments.length) {
579				if (this._dirty) {
580					//instead of Infinity, we use 999999999999 so that we can accommodate reverses
581					this._totalDuration = (this._repeat === -1) ? 999999999999 : this._duration * (this._repeat + 1) + (this._repeatDelay * this._repeat);
582					this._dirty = false;
583				}
584				return this._totalDuration;
585			}
586			return (this._repeat === -1) ? this : this.duration( (value - (this._repeat * this._repeatDelay)) / (this._repeat + 1) );
587		};
588		
589		p.repeat = function(value) {
590			if (!arguments.length) {
591				return this._repeat;
592			}
593			this._repeat = value;
594			return this._uncache(true);
595		};
596		
597		p.repeatDelay = function(value) {
598			if (!arguments.length) {
599				return this._repeatDelay;
600			}
601			this._repeatDelay = value;
602			return this._uncache(true);
603		};
604		
605		p.yoyo = function(value) {
606			if (!arguments.length) {
607				return this._yoyo;
608			}
609			this._yoyo = value;
610			return this;
611		};
612		
613		
614		return TweenMax;
615		
616	}, true);
617
618
619
620
621
622
623
624
625/*
626 * ----------------------------------------------------------------
627 * TimelineLite
628 * ----------------------------------------------------------------
629 */
630	_gsScope._gsDefine("TimelineLite", ["core.Animation","core.SimpleTimeline","TweenLite"], function(Animation, SimpleTimeline, TweenLite) {
631
632		var TimelineLite = function(vars) {
633				SimpleTimeline.call(this, vars);
634				this._labels = {};
635				this.autoRemoveChildren = (this.vars.autoRemoveChildren === true);
636				this.smoothChildTiming = (this.vars.smoothChildTiming === true);
637				this._sortChildren = true;
638				this._onUpdate = this.vars.onUpdate;
639				var v = this.vars,
640					val, p;
641				for (p in v) {
642					val = v[p];
643					if (_isArray(val)) if (val.join("").indexOf("{self}") !== -1) {
644						v[p] = this._swapSelfInParams(val);
645					}
646				}
647				if (_isArray(v.tweens)) {
648					this.add(v.tweens, 0, v.align, v.stagger);
649				}
650			},
651			_tinyNum = 0.0000000001,
652			TweenLiteInternals = TweenLite._internals,
653			_internals = TimelineLite._internals = {},
654			_isSelector = TweenLiteInternals.isSelector,
655			_isArray = TweenLiteInternals.isArray,
656			_lazyTweens = TweenLiteInternals.lazyTweens,
657			_lazyRender = TweenLiteInternals.lazyRender,
658			_globals = _gsScope._gsDefine.globals,
659			_copy = function(vars) {
660				var copy = {}, p;
661				for (p in vars) {
662					copy[p] = vars[p];
663				}
664				return copy;
665			},
666			_applyCycle = function(vars, targets, i) {
667				var alt = vars.cycle,
668					p, val;
669				for (p in alt) {
670					val = alt[p];
671					vars[p] = (typeof(val) === "function") ? val.call(targets[i], i) : val[i % val.length];
672				}
673				delete vars.cycle;
674			},
675			_pauseCallback = _internals.pauseCallback = function() {},
676			_slice = function(a) { //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
677				var b = [],
678					l = a.length,
679					i;
680				for (i = 0; i !== l; b.push(a[i++]));
681				return b;
682			},
683			p = TimelineLite.prototype = new SimpleTimeline();
684
685		TimelineLite.version = "1.18.0";
686		p.constructor = TimelineLite;
687		p.kill()._gc = p._forcingPlayhead = p._hasPause = false;
688
689		/* might use later...
690		//translates a local time inside an animation to the corresponding time on the root/global timeline, factoring in all nesting and timeScales.
691		function localToGlobal(time, animation) {
692			while (animation) {
693				time = (time / animation._timeScale) + animation._startTime;
694				animation = animation.timeline;
695			}
696			return time;
697		}
698
699		//translates the supplied time on the root/global timeline into the corresponding local time inside a particular animation, factoring in all nesting and timeScales
700		function globalToLocal(time, animation) {
701			var scale = 1;
702			time -= localToGlobal(0, animation);
703			while (animation) {
704				scale *= animation._timeScale;
705				animation = animation.timeline;
706			}
707			return time * scale;
708		}
709		*/
710
711		p.to = function(target, duration, vars, position) {
712			var Engine = (vars.repeat && _globals.TweenMax) || TweenLite;
713			return duration ? this.add( new Engine(target, duration, vars), position) : this.set(target, vars, position);
714		};
715
716		p.from = function(target, duration, vars, position) {
717			return this.add( ((vars.repeat && _globals.TweenMax) || TweenLite).from(target, duration, vars), position);
718		};
719
720		p.fromTo = function(target, duration, fromVars, toVars, position) {
721			var Engine = (toVars.repeat && _globals.TweenMax) || TweenLite;
722			return duration ? this.add( Engine.fromTo(target, duration, fromVars, toVars), position) : this.set(target, toVars, position);
723		};
724
725		p.staggerTo = function(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
726			var tl = new TimelineLite({onComplete:onCompleteAll, onCompleteParams:onCompleteAllParams, callbackScope:onCompleteAllScope, smoothChildTiming:this.smoothChildTiming}),
727				cycle = vars.cycle,
728				copy, i;
729			if (typeof(targets) === "string") {
730				targets = TweenLite.selector(targets) || targets;
731			}
732			targets = targets || [];
733			if (_isSelector(targets)) { //senses if the targets object is a selector. If it is, we should translate it into an array.
734				targets = _slice(targets);
735			}
736			stagger = stagger || 0;
737			if (stagger < 0) {
738				targets = _slice(targets);
739				targets.reverse();
740				stagger *= -1;
741			}
742			for (i = 0; i < targets.length; i++) {
743				copy = _copy(vars);
744				if (copy.startAt) {
745					copy.startAt = _copy(copy.startAt);
746					if (copy.startAt.cycle) {
747						_applyCycle(copy.startAt, targets, i);
748					}
749				}
750				if (cycle) {
751					_applyCycle(copy, targets, i);
752				}
753				tl.to(targets[i], duration, copy, i * stagger);
754			}
755			return this.add(tl, position);
756		};
757
758		p.staggerFrom = function(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
759			vars.immediateRender = (vars.immediateRender != false);
760			vars.runBackwards = true;
761			return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
762		};
763
764		p.staggerFromTo = function(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
765			toVars.startAt = fromVars;
766			toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false);
767			return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
768		};
769
770		p.call = function(callback, params, scope, position) {
771			return this.add( TweenLite.delayedCall(0, callback, params, scope), position);
772		};
773
774		p.set = function(target, vars, position) {
775			position = this._parseTimeOrLabel(position, 0, true);
776			if (vars.immediateRender == null) {
777				vars.immediateRender = (position === this._time && !this._paused);
778			}
779			return this.add( new TweenLite(target, 0, vars), position);
780		};
781
782		TimelineLite.exportRoot = function(vars, ignoreDelayedCalls) {
783			vars = vars || {};
784			if (vars.smoothChildTiming == null) {
785				vars.smoothChildTiming = true;
786			}
787			var tl = new TimelineLite(vars),
788				root = tl._timeline,
789				tween, next;
790			if (ignoreDelayedCalls == null) {
791				ignoreDelayedCalls = true;
792			}
793			root._remove(tl, true);
794			tl._startTime = 0;
795			tl._rawPrevTime = tl._time = tl._totalTime = root._time;
796			tween = root._first;
797			while (tween) {
798				next = tween._next;
799				if (!ignoreDelayedCalls || !(tween instanceof TweenLite && tween.target === tween.vars.onComplete)) {
800					tl.add(tween, tween._startTime - tween._delay);
801				}
802				tween = next;
803			}
804			root.add(tl, 0);
805			return tl;
806		};
807
808		p.add = function(value, position, align, stagger) {
809			var curTime, l, i, child, tl, beforeRawTime;
810			if (typeof(position) !== "number") {
811				position = this._parseTimeOrLabel(position, 0, true, value);
812			}
813			if (!(value instanceof Animation)) {
814				if ((value instanceof Array) || (value && value.push && _isArray(value))) {
815					align = align || "normal";
816					stagger = stagger || 0;
817					curTime = position;
818					l = value.length;
819					for (i = 0; i < l; i++) {
820						if (_isArray(child = value[i])) {
821							child = new TimelineLite({tweens:child});
822						}
823						this.add(child, curTime);
824						if (typeof(child) !== "string" && typeof(child) !== "function") {
825							if (align === "sequence") {
826								curTime = child._startTime + (child.totalDuration() / child._timeScale);
827							} else if (align === "start") {
828								child._startTime -= child.delay();
829							}
830						}
831						curTime += stagger;
832					}
833					return this._uncache(true);
834				} else if (typeof(value) === "string") {
835					return this.addLabel(value, position);
836				} else if (typeof(value) === "function") {
837					value = TweenLite.delayedCall(0, value);
838				} else {
839					throw("Cannot add " + value + " into the timeline; it is not a tween, timeline, function, or string.");
840				}
841			}
842
843			SimpleTimeline.prototype.add.call(this, value, position);
844
845			//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.
846			if (this._gc || this._time === this._duration) if (!this._paused) if (this._duration < this.duration()) {
847				//in case any of the ancestors had completed but should now be enabled...
848				tl = this;
849				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.
850				while (tl._timeline) {
851					if (beforeRawTime && tl._timeline.smoothChildTiming) {
852						tl.totalTime(tl._totalTime, true); //moves the timeline (shifts its startTime) if necessary, and also enables it.
853					} else if (tl._gc) {
854						tl._enabled(true, false);
855					}
856					tl = tl._timeline;
857				}
858			}
859
860			return this;
861		};
862
863		p.remove = function(value) {
864			if (value instanceof Animation) {
865				this._remove(value, false);
866				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.
867				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.
868				return this;
869			} else if (value instanceof Array || (value && value.push && _isArray(value))) {
870				var i = value.length;
871				while (--i > -1) {
872					this.remove(value[i]);
873				}
874				return this;
875			} else if (typeof(value) === "string") {
876				return this.removeLabel(value);
877			}
878			return this.kill(null, value);
879		};
880
881		p._remove = function(tween, skipDisable) {
882			SimpleTimeline.prototype._remove.call(this, tween, skipDisable);
883			var last = this._last;
884			if (!last) {
885				this._time = this._totalTime = this._duration = this._totalDuration = 0;
886			} else if (this._time > last._startTime + last._totalDuration / last._timeScale) {
887				this._time = this.duration();
888				this._totalTime = this._totalDuration;
889			}
890			return this;
891		};
892
893		p.append = function(value, offsetOrLabel) {
894			return this.add(value, this._parseTimeOrLabel(null, offsetOrLabel, true, value));
895		};
896
897		p.insert = p.insertMultiple = function(value, position, align, stagger) {
898			return this.add(value, position || 0, align, stagger);
899		};
900
901		p.appendMultiple = function(tweens, offsetOrLabel, align, stagger) {
902			return this.add(tweens, this._parseTimeOrLabel(null, offsetOrLabel, true, tweens), align, stagger);
903		};
904
905		p.addLabel = function(label, position) {
906			this._labels[label] = this._parseTimeOrLabel(position);
907			return this;
908		};
909
910		p.addPause = function(position, callback, params, scope) {
911			var t = TweenLite.delayedCall(0, _pauseCallback, params, scope || this);
912			t.vars.onComplete = t.vars.onReverseComplete = callback;
913			t.data = "isPause";
914			this._hasPause = true;
915			return this.add(t, position);
916		};
917
918		p.removeLabel = function(label) {
919			delete this._labels[label];
920			return this;
921		};
922
923		p.getLabelTime = function(label) {
924			return (this._labels[label] != null) ? this._labels[label] : -1;
925		};
926
927		p._parseTimeOrLabel = function(timeOrLabel, offsetOrLabel, appendIfAbsent, ignore) {
928			var i;
929			//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().
930			if (ignore instanceof Animation && ignore.timeline === this) {
931				this.remove(ignore);
932			} else if (ignore && ((ignore instanceof Array) || (ignore.push && _isArray(ignore)))) {
933				i = ignore.length;
934				while (--i > -1) {
935					if (ignore[i] instanceof Animation && ignore[i].timeline === this) {
936						this.remove(ignore[i]);
937					}
938				}
939			}
940			if (typeof(offsetOrLabel) === "string") {
941				return this._parseTimeOrLabel(offsetOrLabel, (appendIfAbsent && typeof(timeOrLabel) === "number" && this._labels[offsetOrLabel] == null) ? timeOrLabel - this.duration() : 0, appendIfAbsent);
942			}
943			offsetOrLabel = offsetOrLabel || 0;
944			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).
945				i = timeOrLabel.indexOf("=");
946				if (i === -1) {
947					if (this._labels[timeOrLabel] == null) {
948						return appendIfAbsent ? (this._labels[timeOrLabel] = this.duration() + offsetOrLabel) : offsetOrLabel;
949					}
950					return this._labels[timeOrLabel] + offsetOrLabel;
951				}
952				offsetOrLabel = parseInt(timeOrLabel.charAt(i-1) + "1", 10) * Number(timeOrLabel.substr(i+1));
953				timeOrLabel = (i > 1) ? this._parseTimeOrLabel(timeOrLabel.substr(0, i-1), 0, appendIfAbsent) : this.duration();
954			} else if (timeOrLabel == null) {
955				timeOrLabel = this.duration();
956			}
957			return Number(timeOrLabel) + offsetOrLabel;
958		};
959
960		p.seek = function(position, suppressEvents) {
961			return this.totalTime((typeof(position) === "number") ? position : this._parseTimeOrLabel(position), (suppressEvents !== false));
962		};
963
964		p.stop = function() {
965			return this.paused(true);
966		};
967
968		p.gotoAndPlay = function(position, suppressEvents) {
969			return this.play(position, suppressEvents);
970		};
971
972		p.gotoAndStop = function(position, suppressEvents) {
973			return this.pause(position, suppressEvents);
974		};
975
976		p.render = function(time, suppressEvents, force) {
977			if (this._gc) {
978				this._enabled(true, false);
979			}
980			var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(),
981				prevTime = this._time,
982				prevStart = this._startTime,
983				prevTimeScale = this._timeScale,
984				prevPaused = this._paused,
985				tween, isComplete, next, callback, internalForce, pauseTween;
986			if (time >= totalDur) {
987				this._totalTime = this._time = totalDur;
988				if (!this._reversed) if (!this._hasPausedChild()) {
989					isComplete = true;
990					callback = "onComplete";
991					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.
992					if (this._duration === 0) if (time === 0 || this._rawPrevTime < 0 || this._rawPrevTime === _tinyNum) if (this._rawPrevTime !== time && this._first) {
993						internalForce = true;
994						if (this._rawPrevTime > _tinyNum) {
995							callback = "onReverseComplete";
996						}
997					}
998				}
999				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.
1000				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.
1001
1002			} else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0.
1003				this._totalTime = this._time = 0;
1004				if (prevTime !== 0 || (this._duration === 0 && this._rawPrevTime !== _tinyNum && (this._rawPrevTime > 0 || (time < 0 && this._rawPrevTime >= 0)))) {
1005					callback = "onReverseComplete";
1006					isComplete = this._reversed;
1007				}
1008				if (time < 0) {
1009					this._active = false;
1010					if (this._timeline.autoRemoveChildren && this._reversed) { //ensures proper GC if a timeline is resumed after it's finished reversing.
1011						internalForce = isComplete = true;
1012						callback = "onReverseComplete";
1013					} 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.
1014						internalForce = true;
1015					}
1016					this._rawPrevTime = time;
1017				} else {
1018					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.
1019					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).
1020						tween = this._first;
1021						while (tween && tween._startTime === 0) {
1022							if (!tween._duration) {
1023								isComplete = false;
1024							}
1025							tween = tween._next;
1026						}
1027					}
1028					time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
1029					if (!this._initted) {
1030						internalForce = true;
1031					}
1032				}
1033
1034			} else {
1035
1036				if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
1037					if (time >= prevTime) {
1038						tween = this._first;
1039						while (tween && tween._startTime <= time && !pauseTween) {
1040							if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
1041								pauseTween = tween;
1042							}
1043							tween = tween._next;
1044						}
1045					} else {
1046						tween = this._last;
1047						while (tween && tween._startTime >= time && !pauseTween) {
1048							if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) {
1049								pauseTween = tween;
1050							}
1051							tween = tween._prev;
1052						}
1053					}
1054					if (pauseTween) {
1055						this._time = time = pauseTween._startTime;
1056						this._totalTime = time + (this._cycle * (this._totalDuration + this._repeatDelay));
1057					}
1058				}
1059
1060				this._totalTime = this._time = this._rawPrevTime = time;
1061			}
1062			if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
1063				return;
1064			} else if (!this._initted) {
1065				this._initted = true;
1066			}
1067
1068			if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) {
1069				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.
1070			}
1071
1072			if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0) if (!suppressEvents) {
1073				this._callback("onStart");
1074			}
1075
1076			if (this._time >= prevTime) {
1077				tween = this._first;
1078				while (tween) {
1079					next = tween._next; //record it here because the value could change after rendering...
1080					if (this._paused && !prevPaused) { //in case a tween pauses the timeline when rendering
1081						break;
1082					} else if (tween._active || (tween._startTime <= this._time && !tween._paused && !tween._gc)) {
1083						if (pauseTween === tween) {
1084							this.pause();
1085						}
1086						if (!tween._reversed) {
1087							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
1088						} else {
1089							tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force);
1090						}
1091					}
1092					tween = next;
1093				}
1094			} else {
1095				tween = this._last;
1096				while (tween) {
1097					next = tween._prev; //record it here because the value could change after rendering...
1098					if (this._paused && !prevPaused) { //in case a tween pauses the timeline when rendering
1099						break;
1100					} else if (tween._active || (tween._startTime <= prevTime && !tween._paused && !tween._gc)) {
1101						if (pauseTween === tween) {
1102							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.
1103							while (pauseTween && pauseTween.endTime() > this._time) {
1104								pauseTween.render( (pauseTween._reversed ? pauseTween.totalDuration() - ((time - pauseTween._startTime) * pauseTween._timeScale) : (time - pauseTween._startTime) * pauseTween._timeScale), suppressEvents, force);
1105								pauseTween = pauseTween._prev;
1106							}
1107							pauseTween = null;
1108							this.pause();
1109						}
1110						if (!tween._reversed) {
1111							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
1112						} else {
1113							tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force);
1114						}
1115					}
1116					tween = next;
1117				}
1118			}
1119
1120			if (this._onUpdate) if (!suppressEvents) {
1121				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.
1122					_lazyRender();
1123				}
1124				this._callback("onUpdate");
1125			}
1126
1127			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
1128				if (isComplete) {
1129					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.
1130						_lazyRender();
1131					}
1132					if (this._timeline.autoRemoveChildren) {
1133						this._enabled(false, false);
1134					}
1135					this._active = false;
1136				}
1137				if (!suppressEvents && this.vars[callback]) {
1138					this._callback(callback);
1139				}
1140			}
1141		};
1142
1143		p._hasPausedChild = function() {
1144			var tween = this._first;
1145			while (tween) {
1146				if (tween._paused || ((tween instanceof TimelineLite) && tween._hasPausedChild())) {
1147					return true;
1148				}
1149				tween = tween._next;
1150			}
1151			return false;
1152		};
1153
1154		p.getChildren = function(nested, tweens, timelines, ignoreBeforeTime) {
1155			ignoreBeforeTime = ignoreBeforeTime || -9999999999;
1156			var a = [],
1157				tween = this._first,
1158				cnt = 0;
1159			while (tween) {
1160				if (tween._startTime < ignoreBeforeTime) {
1161					//do nothing
1162				} else if (tween instanceof TweenLite) {
1163					if (tweens !== false) {
1164						a[cnt++] = tween;
1165					}
1166				} else {
1167					if (timelines !== false) {
1168						a[cnt++] = tween;
1169					}
1170					if (nested !== false) {
1171						a = a.concat(tween.getChildren(true, tweens, timelines));
1172						cnt = a.length;
1173					}
1174				}
1175				tween = tween._next;
1176			}
1177			return a;
1178		};
1179
1180		p.getTweensOf = function(target, nested) {
1181			var disabled = this._gc,
1182				a = [],
1183				cnt = 0,
1184				tweens, i;
1185			if (disabled) {
1186				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.
1187			}
1188			tweens = TweenLite.getTweensOf(target);
1189			i = tweens.length;
1190			while (--i > -1) {
1191				if (tweens[i].timeline === this || (nested && this._contains(tweens[i]))) {
1192					a[cnt++] = tweens[i];
1193				}
1194			}
1195			if (disabled) {
1196				this._enabled(false, true);
1197			}
1198			return a;
1199		};
1200
1201		p.recent = function() {
1202			return this._recent;
1203		};
1204
1205		p._contains = function(tween) {
1206			var tl = tween.timeline;
1207			while (tl) {
1208				if (tl === this) {
1209					return true;
1210				}
1211				tl = tl.timeline;
1212			}
1213			return false;
1214		};
1215
1216		p.shiftChildren = function(amount, adjustLabels, ignoreBeforeTime) {
1217			ignoreBeforeTime = ignoreBeforeTime || 0;
1218			var tween = this._first,
1219				labels = this._labels,
1220				p;
1221			while (tween) {
1222				if (tween._startTime >= ignoreBeforeTime) {
1223					tween._startTime += amount;
1224				}
1225				tween = tween._next;
1226			}
1227			if (adjustLabels) {
1228				for (p in labels) {
1229					if (labels[p] >= ignoreBeforeTime) {
1230						labels[p] += amount;
1231					}
1232				}
1233			}
1234			return this._uncache(true);
1235		};
1236
1237		p._kill = function(vars, target) {
1238			if (!vars && !target) {
1239				return this._enabled(false, false);
1240			}
1241			var tweens = (!target) ? this.getChildren(true, true, false) : this.getTweensOf(target),
1242				i = tweens.length,
1243				changed = false;
1244			while (--i > -1) {
1245				if (tweens[i]._kill(vars, target)) {
1246					changed = true;
1247				}
1248			}
1249			return changed;
1250		};
1251
1252		p.clear = function(labels) {
1253			var tweens = this.getChildren(false, true, true),
1254				i = tweens.length;
1255			this._time = this._totalTime = 0;
1256			while (--i > -1) {
1257				tweens[i]._enabled(false, false);
1258			}
1259			if (labels !== false) {
1260				this._labels = {};
1261			}
1262			return this._uncache(true);
1263		};
1264
1265		p.invalidate = function() {
1266			var tween = this._first;
1267			while (tween) {
1268				tween.invalidate();
1269				tween = tween._next;
1270			}
1271			return Animation.prototype.invalidate.call(this);;
1272		};
1273
1274		p._enabled = function(enabled, ignoreTimeline) {
1275			if (enabled === this._gc) {
1276				var tween = this._first;
1277				while (tween) {
1278					tween._enabled(enabled, true);
1279					tween = tween._next;
1280				}
1281			}
1282			return SimpleTimeline.prototype._enabled.call(this, enabled, ignoreTimeline);
1283		};
1284
1285		p.totalTime = function(time, suppressEvents, uncapped) {
1286			this._forcingPlayhead = true;
1287			var val = Animation.prototype.totalTime.apply(this, arguments);
1288			this._forcingPlayhead = false;
1289			return val;
1290		};
1291
1292		p.duration = function(value) {
1293			if (!arguments.length) {
1294				if (this._dirty) {
1295					this.totalDuration(); //just triggers recalculation
1296				}
1297				return this._duration;
1298			}
1299			if (this.duration() !== 0 && value !== 0) {
1300				this.timeScale(this._duration / value);
1301			}
1302			return this;
1303		};
1304
1305		p.totalDuration = function(value) {
1306			if (!arguments.length) {
1307				if (this._dirty) {
1308					var max = 0,
1309						tween = this._last,
1310						prevStart = 999999999999,
1311						prev, end;
1312					while (tween) {
1313						prev = tween._prev; //record it here in case the tween changes position in the sequence...
1314						if (tween._dirty) {
1315							tween.totalDuration(); //could change the tween._startTime, so make sure the tween's cache is clean before analyzing it.
1316						}
1317						if (tween._startTime > prevStart && this._sortChildren && !tween._paused) { //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence
1318							this.add(tween, tween._startTime - tween._delay);
1319						} else {
1320							prevStart = tween._startTime;
1321						}
1322						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.
1323							max -= tween._startTime;
1324							if (this._timeline.smoothChildTiming) {
1325								this._startTime += tween._startTime / this._timeScale;
1326							}
1327							this.shiftChildren(-tween._startTime, false, -9999999999);
1328							prevStart = 0;
1329						}
1330						end = tween._startTime + (tween._totalDuration / tween._timeScale);
1331						if (end > max) {
1332							max = end;
1333						}
1334						tween = prev;
1335					}
1336					this._duration = this._totalDuration = max;
1337					this._dirty = false;
1338				}
1339				return this._totalDuration;
1340			}
1341			if (this.totalDuration() !== 0) if (value !== 0) {
1342				this.timeScale(this._totalDuration / value);
1343			}
1344			return this;
1345		};
1346
1347		p.paused = function(value) {
1348			if (!value) { //if there's a pause directly at the spot from where we're unpausing, skip it.
1349				var tween = this._first,
1350					time = this._time;
1351				while (tween) {
1352					if (tween._startTime === time && tween.data === "isPause") {
1353						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.
1354					}
1355					tween = tween._next;
1356				}
1357			}
1358			return Animation.prototype.paused.apply(this, arguments);
1359		};
1360
1361		p.usesFrames = function() {
1362			var tl = this._timeline;
1363			while (tl._timeline) {
1364				tl = tl._timeline;
1365			}
1366			return (tl === Animation._rootFramesTimeline);
1367		};
1368
1369		p.rawTime = function() {
1370			return this._paused ? this._totalTime : (this._timeline.rawTime() - this._startTime) * this._timeScale;
1371		};
1372
1373		return TimelineLite;
1374
1375	}, true);
1376	
1377
1378
1379
1380
1381
1382
1383
1384	
1385	
1386	
1387	
1388	
1389/*
1390 * ----------------------------------------------------------------
1391 * TimelineMax
1392 * ----------------------------------------------------------------
1393 */
1394	_gsScope._gsDefine("TimelineMax", ["TimelineLite","TweenLite","easing.Ease"], function(TimelineLite, TweenLite, Ease) {
1395
1396		var TimelineMax = function(vars) {
1397				TimelineLite.call(this, vars);
1398				this._repeat = this.vars.repeat || 0;
1399				this._repeatDelay = this.vars.repeatDelay || 0;
1400				this._cycle = 0;
1401				this._yoyo = (this.vars.yoyo === true);
1402				this._dirty = true;
1403			},
1404			_tinyNum = 0.0000000001,
1405			TweenLiteInternals = TweenLite._internals,
1406			_lazyTweens = TweenLiteInternals.lazyTweens,
1407			_lazyRender = TweenLiteInternals.lazyRender,
1408			_easeNone = new Ease(null, null, 1, 0),
1409			p = TimelineMax.prototype = new TimelineLite();
1410
1411		p.constructor = TimelineMax;
1412		p.kill()._gc = false;
1413		TimelineMax.version = "1.18.0";
1414
1415		p.invalidate = function() {
1416			this._yoyo = (this.vars.yoyo === true);
1417			this._repeat = this.vars.repeat || 0;
1418			this._repeatDelay = this.vars.repeatDelay || 0;
1419			this._uncache(true);
1420			return TimelineLite.prototype.invalidate.call(this);
1421		};
1422
1423		p.addCallback = function(callback, position, params, scope) {
1424			return this.add( TweenLite.delayedCall(0, callback, params, scope), position);
1425		};
1426
1427		p.removeCallback = function(callback, position) {
1428			if (callback) {
1429				if (position == null) {
1430					this._kill(null, callback);
1431				} else {
1432					var a = this.getTweensOf(callback, false),
1433						i = a.length,
1434						time = this._parseTimeOrLabel(position);
1435					while (--i > -1) {
1436						if (a[i]._startTime === time) {
1437							a[i]._enabled(false, false);
1438						}
1439					}
1440				}
1441			}
1442			return this;
1443		};
1444
1445		p.removePause = function(position) {
1446			return this.removeCallback(TimelineLite._internals.pauseCallback, position);
1447		};
1448
1449		p.tweenTo = function(position, vars) {
1450			vars = vars || {};
1451			var copy = {ease:_easeNone, useFrames:this.usesFrames(), immediateRender:false},
1452				duration, p, t;
1453			for (p in vars) {
1454				copy[p] = vars[p];
1455			}
1456			copy.time = this._parseTimeOrLabel(position);
1457			duration = (Math.abs(Number(copy.time) - this._time) / this._timeScale) || 0.001;
1458			t = new TweenLite(this, duration, copy);
1459			copy.onStart = function() {
1460				t.target.paused(true);
1461				if (t.vars.time !== t.target.time() && duration === t.duration()) { //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.
1462					t.duration( Math.abs( t.vars.time - t.target.time()) / t.target._timeScale );
1463				}
1464				if (vars.onStart) { //in case the user had an onStart in the vars - we don't want to overwrite it.
1465					t._callback("onStart");
1466				}
1467			};
1468			return t;
1469		};
1470
1471		p.tweenFromTo = function(fromPosition, toPosition, vars) {
1472			vars = vars || {};
1473			fromPosition = this._parseTimeOrLabel(fromPosition);
1474			vars.startAt = {onComplete:this.seek, onCompleteParams:[fromPosition], callbackScope:this};
1475			vars.immediateRender = (vars.immediateRender !== false);
1476			var t = this.tweenTo(toPosition, vars);
1477			return t.duration((Math.abs( t.vars.time - fromPosition) / this._timeScale) || 0.001);
1478		};
1479
1480		p.render = function(time, suppressEvents, force) {
1481			if (this._gc) {
1482				this._enabled(true, false);
1483			}
1484			var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(),
1485				dur = this._duration,
1486				prevTime = this._time,
1487				prevTotalTime = this._totalTime,
1488				prevStart = this._startTime,
1489				prevTimeScale = this._timeScale,
1490				prevRawPrevTime = this._rawPrevTime,
1491				prevPaused = this._paused,
1492				prevCycle = this._cycle,
1493				tween, isComplete, next, callback, internalForce, cycleDuration, pauseTween;
1494			if (time >= totalDur) {
1495				if (!this._locked) {
1496					this._totalTime = totalDur;
1497					this._cycle = this._repeat;
1498				}
1499				if (!this._reversed) if (!this._hasPausedChild()) {
1500					isComplete = true;
1501					callback = "onComplete";
1502					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.
1503					if (this._duration === 0) if (time === 0 || prevRawPrevTime < 0 || prevRawPrevTime === _tinyNum) if (prevRawPrevTime !== time && this._first) {
1504						internalForce = true;
1505						if (prevRawPrevTime > _tinyNum) {
1506							callback = "onReverseComplete";
1507						}
1508					}
1509				}
1510				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.
1511				if (this._yoyo && (this._cycle & 1) !== 0) {
1512					this._time = time = 0;
1513				} else {
1514					this._time = dur;
1515					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 
1515which case adding 0.00000001, for example, causes it to act like nothing was added.
1516				}
1517
1518			} else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0.
1519				if (!this._locked) {
1520					this._totalTime = this._cycle = 0;
1521				}
1522				this._time = 0;
1523				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)
1524					callback = "onReverseComplete";
1525					isComplete = this._reversed;
1526				}
1527				if (time < 0) {
1528					this._active = false;
1529					if (this._timeline.autoRemoveChildren && this._reversed) {
1530						internalForce = isComplete = true;
1531						callback = "onReverseComplete";
1532					} 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.
1533						internalForce = true;
1534					}
1535					this._rawPrevTime = time;
1536				} else {
1537					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.
1538					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).
1539						tween = this._first;
1540						while (tween && tween._startTime === 0) {
1541							if (!tween._duration) {
1542								isComplete = false;
1543							}
1544							tween = tween._next;
1545						}
1546					}
1547					time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
1548					if (!this._initted) {
1549						internalForce = true;
1550					}
1551				}
1552
1553			} else {
1554				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.
1555					internalForce = true;
1556				}
1557				this._time = this._rawPrevTime = time;
1558				if (!this._locked) {
1559					this._totalTime = time;
1560					if (this._repeat !== 0) {
1561						cycleDuration = dur + this._repeatDelay;
1562						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!)
1563						if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration) {
1564							this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning)
1565						}
1566						this._time = this._totalTime - (this._cycle * cycleDuration);
1567						if (this._yoyo) if ((this._cycle & 1) !== 0) {
1568							this._time = dur - this._time;
1569						}
1570						if (this._time > dur) {
1571							this._time = dur;
1572							time = dur + 0.0001; //to avoid occasional floating point rounding error
1573						} else if (this._time < 0) {
1574							this._time = time = 0;
1575						} else {
1576							time = this._time;
1577						}
1578					}
1579				}
1580
1581				if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
1582					time = this._time;
1583					if (time >= prevTime) {
1584						tween = this._first;
1585						while (tween && tween._startTime <= time && !pauseTween) {
1586							if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
1587								pauseTween = tween;
1588							}
1589							tween = tween._next;
1590						}
1591					} else {
1592						tween = this._last;
1593						while (tween && tween._startTime >= time && !pauseTween) {
1594							if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) {
1595								pauseTween = tween;
1596							}
1597							tween = tween._prev;
1598						}
1599					}
1600					if (pauseTween) {
1601						this._time = time = pauseTween._startTime;
1602						this._totalTime = time + (this._cycle * (this._totalDuration + this._repeatDelay));
1603					}
1604				}
1605
1606			}
1607
1608			if (this._cycle !== prevCycle) if (!this._locked) {
1609				/*
1610				make sure children at the end/beginning of the timeline are rendered properly. If, for example,
1611				a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which
1612				would get transated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there
1613				could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So
1614				we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must
1615				ensure that zero-duration tweens at the very beginning or end of the TimelineMax work.
1616				*/
1617				var backwards = (this._yoyo && (prevCycle & 1) !== 0),
1618					wrap = (backwards === (this._yoyo && (this._cycle & 1) !== 0)),
1619					recTotalTime = this._totalTime,
1620					recCycle = this._cycle,
1621					recRawPrevTime = this._rawPrevTime,
1622					recTime = this._time;
1623
1624				this._totalTime = prevCycle * dur;
1625				if (this._cycle < prevCycle) {
1626					backwards = !backwards;
1627				} else {
1628					this._totalTime += dur;
1629				}
1630				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.
1631
1632				this._rawPrevTime = (dur === 0) ? prevRawPrevTime - 0.0001 : prevRawPrevTime;
1633				this._cycle = prevCycle;
1634				this._locked = true; //prevents changes to totalTime and skips repeat/yoyo behavior when we recursively call render()
1635				prevTime = (backwards) ? 0 : dur;
1636				this.render(prevTime, suppressEvents, (dur === 0));
1637				if (!suppressEvents) if (!this._gc) {
1638					if (this.vars.onRepeat) {
1639						this._callback("onRepeat");
1640					}
1641				}
1642				if (wrap) {
1643					prevTime = (backwards) ? dur + 0.0001 : -0.0001;
1644					this.render(prevTime, true, false);
1645				}
1646				this._locked = false;
1647				if (this._paused && !prevPaused) { //if the render() triggered callback that paused this timeline, we should abort (very rare, but possible)
1648					return;
1649				}
1650				this._time = recTime;
1651				this._totalTime = recTotalTime;
1652				this._cycle = recCycle;
1653				this._rawPrevTime = recRawPrevTime;
1654			}
1655
1656			if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
1657				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.
1658					this._callback("onUpdate");
1659				}
1660				return;
1661			} else if (!this._initted) {
1662				this._initted = true;
1663			}
1664
1665			if (!this._active) if (!this._paused && this._totalTime !== prevTotalTime && time > 0) {
1666				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.
1667			}
1668
1669			if (prevTotalTime === 0) if (this.vars.onStart) if (this._totalTime !== 0) if (!suppressEvents) {
1670				this._callback("onStart");
1671			}
1672
1673			if (this._time >= prevTime) {
1674				tween = this._first;
1675				while (tween) {
1676					next = tween._next; //record it here because the value could change after rendering...
1677					if (this._paused && !prevPaused) { //in case a tween pauses the timeline when rendering
1678						break;
1679					} else if (tween._active || (tween._startTime <= this._time && !tween._paused && !tween._gc)) {
1680						if (pauseTween === tween) {
1681							this.pause();
1682						}
1683						if (!tween._reversed) {
1684							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
1685						} else {
1686							tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force);
1687						}
1688					}
1689					tween = next;
1690				}
1691			} else {
1692				tween = this._last;
1693				while (tween) {
1694					next = tween._prev; //record it here because the value could change after rendering...
1695					if (this._paused && !prevPaused) { //in case a tween pauses the timeline when rendering
1696						break;
1697					} else if (tween._active || (tween._startTime <= prevTime && !tween._paused && !tween._gc)) {
1698						if (pauseTween === tween) {
1699							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.
1700							while (pauseTween && pauseTween.endTime() > this._time) {
1701								pauseTween.render( (pauseTween._reversed ? pauseTween.totalDuration() - ((time - pauseTween._startTime) * pauseTween._timeScale) : (time - pauseTween._startTime) * pauseTween._timeScale), suppressEvents, force);
1702								pauseTween = pauseTween._prev;
1703							}
1704							pauseTween = null;
1705							this.pause();
1706						}
1707						if (!tween._reversed) {
1708							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
1709						} else {
1710							tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force);
1711						}
1712					}
1713					tween = next;
1714				}
1715			}
1716
1717			if (this._onUpdate) if (!suppressEvents) {
1718				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.
1719					_lazyRender();
1720				}
1721				this._callback("onUpdate");
1722			}
1723			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
1724				if (isComplete) {
1725					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.
1726						_lazyRender();
1727					}
1728					if (this._timeline.autoRemoveChildren) {
1729						this._enabled(false, false);
1730					}
1731					this._active = false;
1732				}
1733				if (!suppressEvents && this.vars[callback]) {
1734					this._callback(callback);
1735				}
1736			}
1737		};
1738
1739		p.getActive = function(nested, tweens, timelines) {
1740			if (nested == null) {
1741				nested = true;
1742			}
1743			if (tweens == null) {
1744				tweens = true;
1745			}
1746			if (timelines == null) {
1747				timelines = false;
1748			}
1749			var a = [],
1750				all = this.getChildren(nested, tweens, timelines),
1751				cnt = 0,
1752				l = all.length,
1753				i, tween;
1754			for (i = 0; i < l; i++) {
1755				tween = all[i];
1756				if (tween.isActive()) {
1757					a[cnt++] = tween;
1758				}
1759			}
1760			return a;
1761		};
1762
1763
1764		p.getLabelAfter = function(time) {
1765			if (!time) if (time !== 0) { //faster than isNan()
1766				time = this._time;
1767			}
1768			var labels = this.getLabelsArray(),
1769				l = labels.length,
1770				i;
1771			for (i = 0; i < l; i++) {
1772				if (labels[i].time > time) {
1773					return labels[i].name;
1774				}
1775			}
1776			return null;
1777		};
1778
1779		p.getLabelBefore = function(time) {
1780			if (time == null) {
1781				time = this._time;
1782			}
1783			var labels = this.getLabelsArray(),
1784				i = labels.length;
1785			while (--i > -1) {
1786				if (labels[i].time < time) {
1787					return labels[i].name;
1788				}
1789			}
1790			return null;
1791		};
1792
1793		p.getLabelsArray = function() {
1794			var a = [],
1795				cnt = 0,
1796				p;
1797			for (p in this._labels) {
1798				a[cnt++] = {time:this._labels[p], name:p};
1799			}
1800			a.sort(function(a,b) {
1801				return a.time - b.time;
1802			});
1803			return a;
1804		};
1805
1806
1807//---- GETTERS / SETTERS -------------------------------------------------------------------------------------------------------
1808
1809		p.progress = function(value, suppressEvents) {
1810			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);
1811		};
1812
1813		p.totalProgress = function(value, suppressEvents) {
1814			return (!arguments.length) ? this._totalTime / this.totalDuration() : this.totalTime( this.totalDuration() * value, suppressEvents);
1815		};
1816
1817		p.totalDuration = function(value) {
1818			if (!arguments.length) {
1819				if (this._dirty) {
1820					TimelineLite.prototype.totalDuration.call(this); //just forces refresh
1821					//Instead of Infinity, we use 999999999999 so that we can accommodate reverses.
1822					this._totalDuration = (this._repeat === -1) ? 999999999999 : this._duration * (this._repeat + 1) + (this._repeatDelay * this._repeat);
1823				}
1824				return this._totalDuration;
1825			}
1826			return (this._repeat === -1) ? this : this.duration( (value - (this._repeat * this._repeatDelay)) / (this._repeat + 1) );
1827		};
1828
1829		p.time = function(value, suppressEvents) {
1830			if (!arguments.length) {
1831				return this._time;
1832			}
1833			if (this._dirty) {
1834				this.totalDuration();
1835			}
1836			if (value > this._duration) {
1837				value = this._duration;
1838			}
1839			if (this._yoyo && (this._cycle & 1) !== 0) {
1840				value = (this._duration - value) + (this._cycle * (this._duration + this._repeatDelay));
1841			} else if (this._repeat !== 0) {
1842				value += this._cycle * (this._duration + this._repeatDelay);
1843			}
1844			return this.totalTime(value, suppressEvents);
1845		};
1846
1847		p.repeat = function(value) {
1848			if (!arguments.length) {
1849				return this._repeat;
1850			}
1851			this._repeat = value;
1852			return this._uncache(true);
1853		};
1854
1855		p.repeatDelay = function(value) {
1856			if (!arguments.length) {
1857				return this._repeatDelay;
1858			}
1859			this._repeatDelay = value;
1860			return this._uncache(true);
1861		};
1862
1863		p.yoyo = function(value) {
1864			if (!arguments.length) {
1865				return this._yoyo;
1866			}
1867			this._yoyo = value;
1868			return this;
1869		};
1870
1871		p.currentLabel = function(value) {
1872			if (!arguments.length) {
1873				return this.getLabelBefore(this._time + 0.00000001);
1874			}
1875			return this.seek(value, true);
1876		};
1877
1878		return TimelineMax;
1879
1880	}, true);
1881	
1882
1883
1884
1885
1886	
1887	
1888	
1889	
1890	
1891	
1892	
1893/*
1894 * ----------------------------------------------------------------
1895 * BezierPlugin
1896 * ----------------------------------------------------------------
1897 */
1898	(function() {
1899
1900		var _RAD2DEG = 180 / Math.PI,
1901			_r1 = [],
1902			_r2 = [],
1903			_r3 = [],
1904			_corProps = {},
1905			_globals = _gsScope._gsDefine.globals,
1906			Segment = function(a, b, c, d) {
1907				this.a = a;
1908				this.b = b;
1909				this.c = c;
1910				this.d = d;
1911				this.da = d - a;
1912				this.ca = c - a;
1913				this.ba = b - a;
1914			},
1915			_correlate = ",x,y,z,left,top,right,bottom,marginTop,marginLeft,marginRight,marginBottom,paddingLeft,paddingTop,paddingRight,paddingBottom,backgroundPosition,backgroundPosition_y,",
1916			cubicToQuadratic = function(a, b, c, d) {
1917				var q1 = {a:a},
1918					q2 = {},
1919					q3 = {},
1920					q4 = {c:d},
1921					mab = (a + b) / 2,
1922					mbc = (b + c) / 2,
1923					mcd = (c + d) / 2,
1924					mabc = (mab + mbc) / 2,
1925					mbcd = (mbc + mcd) / 2,
1926					m8 = (mbcd - mabc) / 8;
1927				q1.b = mab + (a - mab) / 4;
1928				q2.b = mabc + m8;
1929				q1.c = q2.a = (q1.b + q2.b) / 2;
1930				q2.c = q3.a = (mabc + mbcd) / 2;
1931				q3.b = mbcd - m8;
1932				q4.b = mcd + (d - mcd) / 4;
1933				q3.c = q4.a = (q3.b + q4.b) / 2;
1934				return [q1, q2, q3, q4];
1935			},
1936			_calculateControlPoints = function(a, curviness, quad, basic, correlate) {
1937				var l = a.length - 1,
1938					ii = 0,
1939					cp1 = a[0].a,
1940					i, p1, p2, p3, seg, m1, m2, mm, cp2, qb, r1, r2, tl;
1941				for (i = 0; i < l; i++) {
1942					seg = a[ii];
1943					p1 = seg.a;
1944					p2 = seg.d;
1945					p3 = a[ii+1].d;
1946
1947					if (correlate) {
1948						r1 = _r1[i];
1949						r2 = _r2[i];
1950						tl = ((r2 + r1) * curviness * 0.25) / (basic ? 0.5 : _r3[i] || 0.5);
1951						m1 = p2 - (p2 - p1) * (basic ? curviness * 0.5 : (r1 !== 0 ? tl / r1 : 0));
1952						m2 = p2 + (p3 - p2) * (basic ? curviness * 0.5 : (r2 !== 0 ? tl / r2 : 0));
1953						mm = p2 - (m1 + (((m2 - m1) * ((r1 * 3 / (r1 + r2)) + 0.5) / 4) || 0));
1954					} else {
1955						m1 = p2 - (p2 - p1) * curviness * 0.5;
1956						m2 = p2 + (p3 - p2) * curviness * 0.5;
1957						mm = p2 - (m1 + m2) / 2;
1958					}
1959					m1 += mm;
1960					m2 += mm;
1961
1962					seg.c = cp2 = m1;
1963					if (i !== 0) {
1964						seg.b = cp1;
1965					} else {
1966						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.
1967					}
1968
1969					seg.da = p2 - p1;
1970					seg.ca = cp2 - p1;
1971					seg.ba = cp1 - p1;
1972
1973					if (quad) {
1974						qb = cubicToQuadratic(p1, cp1, cp2, p2);
1975						a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]);
1976						ii += 4;
1977					} else {
1978						ii++;
1979					}
1980
1981					cp1 = m2;
1982				}
1983				seg = a[ii];
1984				seg.b = cp1;
1985				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.
1986				seg.da = seg.d - seg.a;
1987				seg.ca = seg.c - seg.a;
1988				seg.ba = cp1 - seg.a;
1989				if (quad) {
1990					qb = cubicToQuadratic(seg.a, cp1, seg.c, seg.d);
1991					a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]);
1992				}
1993			},
1994			_parseAnchors = function(values, p, correlate, prepend) {
1995				var a = [],
1996					l, i, p1, p2, p3, tmp;
1997				if (prepend) {
1998					values = [prepend].concat(values);
1999					i = values.length;
2000					while (--i > -1) {
2001						if (typeof( (tmp = values[i][p]) ) === "string") if (tmp.charAt(1) === "=") {
2002							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
2003						}
2004					}
2005				}
2006				l = values.length - 2;
2007				if (l < 0) {
2008					a[0] = new Segment(values[0][p], 0, 0, values[(l < -1) ? 0 : 1][p]);
2009					return a;
2010				}
2011				for (i = 0; i < l; i++) {
2012					p1 = values[i][p];
2013					p2 = values[i+1][p];
2014					a[i] = new Segment(p1, 0, 0, p2);
2015					if (correlate) {
2016						p3 = values[i+2][p];
2017						_r1[i] = (_r1[i] || 0) + (p2 - p1) * (p2 - p1);
2018						_r2[i] = (_r2[i] || 0) + (p3 - p2) * (p3 - p2);
2019					}
2020				}
2021				a[i] = new Segment(values[i][p], 0, 0, values[i+1][p]);
2022				return a;
2023			},
2024			bezierThrough = function(values, curviness, quadratic, basic, correlate, prepend) {
2025				var obj = {},
2026					props = [],
2027					first = prepend || values[0],
2028					i, p, a, j, r, l, seamless, last;
2029				correlate = (typeof(correlate) === "string") ? ","+correlate+"," : _correlate;
2030				if (curviness == null) {
2031					curviness = 1;
2032				}
2033				for (p in values[0]) {
2034					props.push(p);
2035				}
2036				//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)
2037				if (values.length > 1) {
2038					last = values[values.length - 1];
2039					seamless = true;
2040					i = props.length;
2041					while (--i > -1) {
2042						p = props[i];
2043						if (Math.abs(first[p] - last[p]) > 0.05) { //build in a tolerance of +/-0.05 to accommodate rounding errors. For example, if you set an object's position to 4.945, Flash will make it 4.9
2044							seamless = false;
2045							break;
2046						}
2047					}
2048					if (seamless) {
2049						values = values.concat(); //duplicate the array to avoid contaminating the original which the user may be reusing for other tweens
2050						if (prepend) {
2051							values.unshift(prepend);
2052						}
2053						values.push(values[1]);
2054						prepend = values[values.length - 3];
2055					}
2056				}
2057				_r1.length = _r2.length = _r3.length = 0;
2058				i = props.length;
2059				while (--i > -1) {
2060					p = props[i];
2061					_corProps[p] = (correlate.indexOf(","+p+",") !== -1);
2062					obj[p] = _parseAnchors(values, p, _corProps[p], prepend);
2063				}
2064				i = _r1.length;
2065				while (--i > -1) {
2066					_r1[i] = Math.sqrt(_r1[i]);
2067					_r2[i] = Math.sqrt(_r2[i]);
2068				}
2069				if (!basic) {
2070					i = props.length;
2071					while (--i > -1) {
2072						if (_corProps[p]) {
2073							a = obj[props[i]];
2074							l = a.length - 1;
2075							for (j = 0; j < l; j++) {
2076								r = a[j+1].da / _r2[j] + a[j].da / _r1[j];
2077								_r3[j] = (_r3[j] || 0) + r * r;
2078							}
2079						}
2080					}
2081					i = _r3.length;
2082					while (--i > -1) {
2083						_r3[i] = Math.sqrt(_r3[i]);
2084					}
2085				}
2086				i = props.length;
2087				j = quadratic ? 4 : 1;
2088				while (--i > -1) {
2089					p = props[i];
2090					a = obj[p];
2091					_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
2092					if (seamless) {
2093						a.splice(0, j);
2094						a.splice(a.length - j, j);
2095					}
2096				}
2097				return obj;
2098			},
2099			_parseBezierData = function(values, type, prepend) {
2100				type = type || "soft";
2101				var obj = {},
2102					inc = (type === "cubic") ? 3 : 2,
2103					soft = (type === "soft"),
2104					props = [],
2105					a, b, c, d, cur, i, j, l, p, cnt, tmp;
2106				if (soft && prepend) {
2107					values = [prepend].concat(values);
2108				}
2109				if (values == null || values.length < inc + 1) { throw "invalid Bezier data"; }
2110				for (p in values[0]) {
2111					props.push(p);
2112				}
2113				i = props.length;
2114				while (--i > -1) {
2115					p = props[i];
2116					obj[p] = cur = [];
2117					cnt = 0;
2118					l = values.length;
2119					for (j = 0; j < l; j++) {
2120						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);
2121						if (soft) if (j > 1) if (j < l - 1) {
2122							cur[cnt++] = (a + cur[cnt-2]) / 2;
2123						}
2124						cur[cnt++] = a;
2125					}
2126					l = cnt - inc + 1;
2127					cnt = 0;
2128					for (j = 0; j < l; j += inc) {
2129						a = cur[j];
2130						b = cur[j+1];
2131						c = cur[j+2];
2132						d = (inc === 2) ? 0 : cur[j+3];
2133						cur[cnt++] = tmp = (inc === 3) ? new Segment(a, b, c, d) : new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c);
2134					}
2135					cur.length = cnt;
2136				}
2137				return obj;
2138			},
2139			_addCubicLengths = function(a, steps, resolution) {
2140				var inc = 1 / resolution,
2141					j = a.length,
2142					d, d1, s, da, ca, ba, p, i, inv, bez, index;
2143				while (--j > -1) {
2144					bez = a[j];
2145					s = bez.a;
2146					da = bez.d - s;
2147					ca = bez.c - s;
2148					ba = bez.b - s;
2149					d = d1 = 0;
2150					for (i = 1; i <= resolution; i++) {
2151						p = inc * i;
2152						inv = 1 - p;
2153						d = d1 - (d1 = (p * p * da + 3 * inv * (p * ca + inv * ba)) * p);
2154						index = j * resolution + i - 1;
2155						steps[index] = (steps[index] || 0) + d * d;
2156					}
2157				}
2158			},
2159			_parseLengthData = function(obj, resolution) {
2160				resolution = resolution >> 0 || 6;
2161				var a = [],
2162					lengths = [],
2163					d = 0,
2164					total = 0,
2165					threshold = resolution - 1,
2166					segments = [],
2167					curLS = [], //current length segments array
2168					p, i, l, index;
2169				for (p in obj) {
2170					_addCubicLengths(obj[p], a, resolution);
2171				}
2172				l = a.length;
2173				for (i = 0; i < l; i++) {
2174					d += Math.sqrt(a[i]);
2175					index = i % resolution;
2176					curLS[index] = d;
2177					if (index === threshold) {
2178						total += d;
2179						index = (i / resolution) >> 0;
2180						segments[index] = curLS;
2181						lengths[index] = total;
2182						d = 0;
2183						curLS = [];
2184					}
2185				}
2186				return {length:total, lengths:lengths, segments:segments};
2187			},
2188
2189
2190
2191			BezierPlugin = _gsScope._gsDefine.plugin({
2192					propName: "bezier",
2193					priority: -1,
2194					version: "1.3.4",
2195					API: 2,
2196					global:true,
2197
2198					//gets called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
2199					init: function(target, vars, tween) {
2200						this._target = target;
2201						if (vars instanceof Array) {
2202							vars = {values:vars};
2203						}
2204						this._func = {};
2205						this._round = {};
2206						this._props = [];
2207						this._timeRes = (vars.timeResolution == null) ? 6 : parseInt(vars.timeResolution, 10);
2208						var values = vars.values || [],
2209							first = {},
2210							second = values[0],
2211							autoRotate = vars.autoRotate || tween.vars.orientToBezier,
2212							p, isFunc, i, j, prepend;
2213
2214						this._autoRotate = autoRotate ? (autoRotate instanceof Array) ? autoRotate : [["x","y","rotation",((autoRotate === true) ? 0 : Number(autoRotate) || 0)]] : null;
2215						for (p in second) {
2216							this._props.push(p);
2217						}
2218
2219						i = this._props.length;
2220						while (--i > -1) {
2221							p = this._props[i];
2222
2223							this._overwriteProps.push(p);
2224							isFunc = this._func[p] = (typeof(target[p]) === "function");
2225							first[p] = (!isFunc) ? parseFloat(target[p]) : target[ ((p.indexOf("set") || typeof(target["get" + p.substr(3)]) !== "function") ? p : "get" + p.substr(3)) ]();
2226							if (!prepend) if (first[p] !== values[0][p]) {
2227								prepend = first;
2228							}
2229						}
2230						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);
2231						this._segCount = this._beziers[p].length;
2232
2233						if (this._timeRes) {
2234							var ld = _parseLengthData(this._beziers, this._timeRes);
2235							this._length = ld.length;
2236							this._lengths = ld.lengths;
2237							this._segments = ld.segments;
2238							this._l1 = this._li = this._s1 = this._si = 0;
2239							this._l2 = this._lengths[0];
2240							this._curSeg = this._segments[0];
2241							this._s2 = this._curSeg[0];
2242							this._prec = 1 / this._curSeg.length;
2243						}
2244
2245						if ((autoRotate = this._autoRotate)) {
2246							this._initialRotations = [];
2247							if (!(autoRotate[0] instanceof Array)) {
2248								this._autoRotate = autoRotate = [autoRotate];
2249							}
2250							i = autoRotate.length;
2251							while (--i > -1) {
2252								for (j = 0; j < 3; j++) {
2253									p = autoRotate[i][j];
2254									this._func[p] = (typeof(target[p]) === "function") ? target[ ((p.indexOf("set") || typeof(target["get" + p.substr(3)]) !== "function") ? p : "get" + p.substr(3)) ] : false;
2255								}
2256								p = autoRotate[i][2];
2257								this._initialRotations[i] = this._func[p] ? this._func[p].call(this._target) : this._target[p];
2258							}
2259						}
2260						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.
2261						return true;
2262					},
2263
2264					//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.)
2265					set: function(v) {
2266						var segments = this._segCount,
2267							func = this._func,
2268							target = this._target,
2269							notStart = (v !== this._startRatio),
2270							curIndex, inv, i, p, b, t, val, l, lengths, curSeg;
2271						if (!this._timeRes) {
2272							curIndex = (v < 0) ? 0 : (v >= 1) ? segments - 1 : (segments * v) >> 0;
2273							t = (v - (curIndex * (1 / segments))) * segments;
2274						} else {
2275							lengths = this._lengths;
2276							curSeg = this._curSeg;
2277							v *= this._length;
2278							i = this._li;
2279							//find the appropriate segment (if the currently cached one isn't correct)
2280							if (v > this._l2 && i < segments - 1) {
2281								l = segments - 1;
2282								while (i < l && (this._l2 = lengths[++i]) <= v) {	}
2283								this._l1 = lengths[i-1];
2284								this._li = i;
2285								this._curSeg = curSeg = this._segments[i];
2286								this._s2 = curSeg[(this._s1 = this._si = 0)];
2287							} else if (v < this._l1 && i > 0) {
2288								while (i > 0 && (this._l1 = lengths[--i]) >= v) { }
2289								if (i === 0 && v < this._l1) {
2290									this._l1 = 0;
2291								} else {
2292									i++;
2293								}
2294								this._l2 = lengths[i];
2295								this._li = i;
2296								this._curSeg = curSeg = this._segments[i];
2297								this._s1 = curSeg[(this._si = curSeg.length - 1) - 1] || 0;
2298								this._s2 = curSeg[this._si];
2299							}
2300							curIndex = i;
2301							//now find the appropriate sub-segment (we split it into the number of pieces that was defined by "precision" and measured each one)
2302							v -= this._l1;
2303							i = this._si;
2304							if (v > this._s2 && i < curSeg.length - 1) {
2305								l = curSeg.length - 1;
2306								while (i < l && (this._s2 = curSeg[++i]) <= v) {	}
2307								this._s1 = curSeg[i-1];
2308								this._si = i;
2309							} else if (v < this._s1 && i > 0) {
2310								while (i > 0 && (this._s1 = curSeg[--i]) >= v) {	}
2311								if (i === 0 && v < this._s1) {
2312									this._s1 = 0;
2313								} else {
2314									i++;
2315								}
2316								this._s2 = curSeg[i];
2317								this._si = i;
2318							}
2319							t = (i + (v - this._s1) / (this._s2 - this._s1)) * this._prec;
2320						}
2321						inv = 1 - t;
2322
2323						i = this._props.length;
2324						while (--i > -1) {
2325							p = this._props[i];
2326							b = this._beziers[p][curIndex];
2327							val = (t * t * b.da + 3 * inv * (t * b.ca + inv * b.ba)) * t + b.a;
2328							if (this._round[p]) {
2329								val = Math.round(val);
2330							}
2331							if (func[p]) {
2332								target[p](val);
2333							} else {
2334								target[p] = val;
2335							}
2336						}
2337
2338						if (this._autoRotate) {
2339							var ar = this._autoRotate,
2340								b2, x1, y1, x2, y2, add, conv;
2341							i = ar.length;
2342							while (--i > -1) {
2343								p = ar[i][2];
2344								add = ar[i][3] || 0;
2345								conv = (ar[i][4] === true) ? 1 : _RAD2DEG;
2346								b = this._beziers[ar[i][0]];
2347								b2 = this._beziers[ar[i][1]];
2348
2349								if (b && b2) { //in case one of the properties got overwritten.
2350									b = b[curIndex];
2351									b2 = b2[curIndex];
2352
2353									x1 = b.a + (b.b - b.a) * t;
2354									x2 = b.b + (b.c - b.b) * t;
2355									x1 += (x2 - x1) * t;
2356									x2 += ((b.c + (b.d - b.c) * t) - x2) * t;
2357
2358									y1 = b2.a + (b2.b - b2.a) * t;
2359									y2 = b2.b + (b2.c - b2.b) * t;
2360									y1 += (y2 - y1) * t;
2361									y2 += ((b2.c + (b2.d - b2.c) * t) - y2) * t;
2362
2363									val = notStart ? Math.atan2(y2 - y1, x2 - x1) * conv + add : this._initialRotations[i];
2364
2365									if (func[p]) {
2366										target[p](val);
2367									} else {
2368										target[p] = val;
2369									}
2370								}
2371							}
2372						}
2373					}
2374			}),
2375			p = BezierPlugin.prototype;
2376
2377
2378		BezierPlugin.bezierThrough = bezierThrough;
2379		BezierPlugin.cubicToQuadratic = cubicToQuadratic;
2380		BezierPlugin._autoCSS = true; //indicates that this plugin can be inserted into the "css" object using the autoCSS feature of TweenLite
2381		BezierPlugin.quadraticToCubic = function(a, b, c) {
2382			return new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c);
2383		};
2384
2385		BezierPlugin._cssRegister = function() {
2386			var CSSPlugin = _globals.CSSPlugin;
2387			if (!CSSPlugin) {
2388				return;
2389			}
2390			var _internals = CSSPlugin._internals,
2391				_parseToProxy = _internals._parseToProxy,
2392				_setPluginRatio = _internals._setPluginRatio,
2393				CSSPropTween = _internals.CSSPropTween;
2394			_internals._registerComplexSpecialProp("bezier", {parser:function(t, e, prop, cssp, pt, plugin) {
2395				if (e instanceof Array) {
2396					e = {values:e};
2397				}
2398				plugin = new BezierPlugin();
2399				var values = e.values,
2400					l = values.length - 1,
2401					pluginValues = [],
2402					v = {},
2403					i, p, data;
2404				if (l < 0) {
2405					return pt;
2406				}
2407				for (i = 0; i <= l; i++) {
2408					data = _parseToProxy(t, values[i], cssp, pt, plugin, (l !== i));
2409					pluginValues[i] = data.end;
2410				}
2411				for (p in e) {
2412					v[p] = e[p]; //duplicate the vars object because we need to alter some things which w
2412ould cause problems if the user plans to reuse the same vars object for another tween.
2413				}
2414				v.values = pluginValues;
2415				pt = new CSSPropTween(t, "bezier", 0, 0, data.pt, 2);
2416				pt.data = data;
2417				pt.plugin = plugin;
2418				pt.setRatio = _setPluginRatio;
2419				if (v.autoRotate === 0) {
2420					v.autoRotate = true;
2421				}
2422				if (v.autoRotate && !(v.autoRotate instanceof Array)) {
2423					i = (v.autoRotate === true) ? 0 : Number(v.autoRotate);
2424					v.autoRotate = (data.end.left != null) ? [["left","top","rotation",i,false]] : (data.end.x != null) ? [["x","y","rotation",i,false]] : false;
2425				}
2426				if (v.autoRotate) {
2427					if (!cssp._transform) {
2428						cssp._enableTransforms(false);
2429					}
2430					data.autoRotate = cssp._target._gsTransform;
2431				}
2432				plugin._onInitTween(data.proxy, v, cssp._tween);
2433				return pt;
2434			}});
2435		};
2436
2437		p._roundProps = function(lookup, value) {
2438			var op = this._overwriteProps,
2439				i = op.length;
2440			while (--i > -1) {
2441				if (lookup[op[i]] || lookup.bezier || lookup.bezierThrough) {
2442					this._round[op[i]] = value;
2443				}
2444			}
2445		};
2446
2447		p._kill = function(lookup) {
2448			var a = this._props,
2449				p, i;
2450			for (p in this._beziers) {
2451				if (p in lookup) {
2452					delete this._beziers[p];
2453					delete this._func[p];
2454					i = a.length;
2455					while (--i > -1) {
2456						if (a[i] === p) {
2457							a.splice(i, 1);
2458						}
2459					}
2460				}
2461			}
2462			return this._super._kill.call(this, lookup);
2463		};
2464
2465	}());
2466
2467
2468
2469
2470
2471
2472	
2473	
2474	
2475	
2476	
2477	
2478	
2479	
2480/*
2481 * ----------------------------------------------------------------
2482 * CSSPlugin
2483 * ----------------------------------------------------------------
2484 */
2485	_gsScope._gsDefine("plugins.CSSPlugin", ["plugins.TweenPlugin","TweenLite"], function(TweenPlugin, TweenLite) {
2486
2487		/** @constructor **/
2488		var CSSPlugin = function() {
2489				TweenPlugin.call(this, "css");
2490				this._overwriteProps.length = 0;
2491				this.setRatio = CSSPlugin.prototype.setRatio; //speed optimization (avoid prototype lookup on this "hot" method)
2492			},
2493			_globals = _gsScope._gsDefine.globals,
2494			_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.
2495			_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
2496			_cs, //computed style (we store this in a shared variable to conserve memory and make minification tighter
2497			_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.
2498			_specialProps = {},
2499			p = CSSPlugin.prototype = new TweenPlugin("css");
2500
2501		p.constructor = CSSPlugin;
2502		CSSPlugin.version = "1.18.0";
2503		CSSPlugin.API = 2;
2504		CSSPlugin.defaultTransformPerspective = 0;
2505		CSSPlugin.defaultSkewType = "compensated";
2506		CSSPlugin.defaultSmoothOrigin = true;
2507		p = "px"; //we'll reuse the "p" variable to keep file size down
2508		CSSPlugin.suffixMap = {top:p, right:p, bottom:p, left:p, width:p, height:p, fontSize:p, padding:p, margin:p, perspective:p, lineHeight:""};
2509
2510
2511		var _numExp = /(?:\d|\-\d|\.\d|\-\.\d)+/g,
2512			_relNumExp = /(?:\d|\-\d|\.\d|\-\.\d|\+=\d|\-=\d|\+=.\d|\-=\.\d)+/g,
2513			_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)"
2514			_NaNExp = /(?![+-]?\d*\.?\d+|[+-]|e[+-]\d+)[^0-9]/g, //also allows scientific notation and doesn't kill the leading -/+ in -= and +=
2515			_suffixExp = /(?:\d|\-|\+|=|#|\.)*/g,
2516			_opacityExp = /opacity *= *([^)]*)/i,
2517			_opacityValExp = /opacity:([^;]*)/i,
2518			_alphaFilterExp = /alpha\(opacity *=.+?\)/i,
2519			_rgbhslExp = /^(rgb|hsl)/,
2520			_capsExp = /([A-Z])/g,
2521			_camelExp = /-([a-z])/gi,
2522			_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)
2523			_camelFunc = function(s, g) { return g.toUpperCase(); },
2524			_horizExp = /(?:Left|Right|Width)/i,
2525			_ieGetMatrixExp = /(M11|M12|M21|M22)=[\d\-\.e]+/gi,
2526			_ieSetMatrixExp = /progid\:DXImageTransform\.Microsoft\.Matrix\(.+?\)/i,
2527			_commasOutsideParenExp = /,(?=[^\)]*(?:\(|$))/gi, //finds any commas that are not within parenthesis
2528			_DEG2RAD = Math.PI / 180,
2529			_RAD2DEG = 180 / Math.PI,
2530			_forcePT = {},
2531			_doc = document,
2532			_createElement = function(type) {
2533				return _doc.createElementNS ? _doc.createElementNS("http://www.w3.org/1999/xhtml", type) : _doc.createElement(type);
2534			},
2535			_tempDiv = _createElement("div"),
2536			_tempImg = _createElement("img"),
2537			_internals = CSSPlugin._internals = {_specialProps:_specialProps}, //provides a hook to a few internal methods that we need to access from inside other plugins
2538			_agent = navigator.userAgent,
2539			_autoRound,
2540			_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).
2541
2542			_isSafari,
2543			_isFirefox, //Firefox has a bug that causes 3D transformed elements to randomly disappear unless a repaint is forced after each update on each element.
2544			_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!)
2545			_ieVers,
2546			_supportsOpacity = (function() { //we set _isSafari, _ieVers, _isFirefox, and _supportsOpacity all in one function here to reduce file size slightly, especially in the minified version.
2547				var i = _agent.indexOf("Android"),
2548					a = _createElement("a");
2549				_isSafari = (_agent.indexOf("Safari") !== -1 && _agent.indexOf("Chrome") === -1 && (i === -1 || Number(_agent.substr(i+8, 1)) > 3));
2550				_isSafariLT6 = (_isSafari && (Number(_agent.substr(_agent.indexOf("Version/")+8, 1)) < 6));
2551				_isFirefox = (_agent.indexOf("Firefox") !== -1);
2552				if ((/MSIE ([0-9]{1,}[\.0-9]{0,})/).exec(_agent) || (/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/).exec(_agent)) {
2553					_ieVers = parseFloat( RegExp.$1 );
2554				}
2555				if (!a) {
2556					return false;
2557				}
2558				a.style.cssText = "top:1px;opacity:.55;";
2559				return /^0.55/.test(a.style.opacity);
2560			}()),
2561			_getIEOpacity = function(v) {
2562				return (_opacityExp.test( ((typeof(v) === "string") ? v : (v.currentStyle ? v.currentStyle.filter : v.style.filter) || "") ) ? ( parseFloat( RegExp.$1 ) / 100 ) : 1);
2563			},
2564			_log = function(s) {//for logging messages, but in a way that won't throw errors in old versions of IE.
2565				if (window.console) {
2566					console.log(s);
2567				}
2568			},
2569
2570			_prefixCSS = "", //the non-camelCase vendor prefix like "-o-", "-moz-", "-ms-", or "-webkit-"
2571			_prefix = "", //camelCase vendor prefix like "O", "ms", "Webkit", or "Moz".
2572
2573			// @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)
2574			_checkPropPrefix = function(p, e) {
2575				e = e || _tempDiv;
2576				var s = e.style,
2577					a, i;
2578				if (s[p] !== undefined) {
2579					return p;
2580				}
2581				p = p.charAt(0).toUpperCase() + p.substr(1);
2582				a = ["O","Moz","ms","Ms","Webkit"];
2583				i = 5;
2584				while (--i > -1 && s[a[i]+p] === undefined) { }
2585				if (i >= 0) {
2586					_prefix = (i === 3) ? "ms" : a[i];
2587					_prefixCSS = "-" + _prefix.toLowerCase() + "-";
2588					return _prefix + p;
2589				}
2590				return null;
2591			},
2592
2593			_getComputedStyle = _doc.defaultView ? _doc.defaultView.getComputedStyle : function() {},
2594
2595			/**
2596			 * @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:
2597			 * var currentLeft = CSSPlugin.getStyle( document.getElementById("myElement"), "left");
2598			 *
2599			 * @param {!Object} t Target element whose style property you want to query
2600			 * @param {!string} p Property name (like "left" or "top" or "marginTop", etc.)
2601			 * @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.
2602			 * @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.
2603			 * @param {string=} dflt Default value that should be returned in the place of null, "none", "auto" or "auto auto".
2604			 * @return {?string} The current property value
2605			 */
2606			_getStyle = CSSPlugin.getStyle = function(t, p, cs, calc, dflt) {
2607				var rv;
2608				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.
2609					return _getIEOpacity(t);
2610				}
2611				if (!calc && t.style[p]) {
2612					rv = t.style[p];
2613				} else if ((cs = cs || _getComputedStyle(t))) {
2614					rv = cs[p] || cs.getPropertyValue(p) || cs.getPropertyValue(p.replace(_capsExp, "-$1").toLowerCase());
2615				} else if (t.currentStyle) {
2616					rv = t.currentStyle[p];
2617				}
2618				return (dflt != null && (!rv || rv === "none" || rv === "auto" || rv === "auto auto")) ? dflt : rv;
2619			},
2620
2621			/**
2622			 * @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.
2623			 * @param {!Object} t Target element
2624			 * @param {!string} p Property name (like "left", "top", "marginLeft", etc.)
2625			 * @param {!number} v Value
2626			 * @param {string=} sfx Suffix (like "px" or "%" or "em")
2627			 * @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.
2628			 * @return {number} value in pixels
2629			 */
2630			_convertToPixels = _internals.convertToPixels = function(t, p, v, sfx, recurse) {
2631				if (sfx === "px" || !sfx) { return v; }
2632				if (sfx === "auto" || !v) { return 0; }
2633				var horiz = _horizExp.test(p),
2634					node = t,
2635					style = _tempDiv.style,
2636					neg = (v < 0),
2637					pix, cache, time;
2638				if (neg) {
2639					v = -v;
2640				}
2641				if (sfx === "%" && p.indexOf("border") !== -1) {
2642					pix = (v / 100) * (horiz ? t.clientWidth : t.clientHeight);
2643				} else {
2644					style.cssText = "border:0 solid red;position:" + _getStyle(t, "position") + ";line-height:0;";
2645					if (sfx === "%" || !node.appendChild || sfx.charAt(0) === "v" || sfx === "rem") {
2646						node = t.parentNode || _doc.body;
2647						cache = node._gsCache;
2648						time = TweenLite.ticker.frame;
2649						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)
2650							return cache.width * v / 100;
2651						}
2652						style[(horiz ? "width" : "height")] = v + sfx;
2653					} else {
2654						style[(horiz ? "borderLeftWidth" : "borderTopWidth")] = v + sfx;
2655					}
2656					node.appendChild(_tempDiv);
2657					pix = parseFloat(_tempDiv[(horiz ? "offsetWidth" : "offsetHeight")]);
2658					node.removeChild(_tempDiv);
2659					if (horiz && sfx === "%" && CSSPlugin.cacheWidths !== false) {
2660						cache = node._gsCache = node._gsCache || {};
2661						cache.time = time;
2662						cache.width = pix / v * 100;
2663					}
2664					if (pix === 0 && !recurse) {
2665						pix = _convertToPixels(t, p, v, sfx, true);
2666					}
2667				}
2668				return neg ? -pix : pix;
2669			},
2670			_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
2671				if (_getStyle(t, "position", cs) !== "absolute") { return 0; }
2672				var dim = ((p === "left") ? "Left" : "Top"),
2673					v = _getStyle(t, "margin" + dim, cs);
2674				return t["offset" + dim] - (_convertToPixels(t, p, parseFloat(v), v.replace(_suffixExp, "")) || 0);
2675			},
2676
2677			// @private returns at object containing ALL of the style properties in camelCase and their associated values.
2678			_getAllStyles = function(t, cs) {
2679				var s = {},
2680					i, tr, p;
2681				if ((cs = cs || _getComputedStyle(t, null))) {
2682					if ((i = cs.length)) {
2683						while (--i > -1) {
2684							p = cs[i];
2685							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.
2686								s[p.replace(_camelExp, _camelFunc)] = cs.getPropertyValue(p);
2687							}
2688						}
2689					} else { //some browsers behave differently - cs.length is always 0, so we must do a for...in loop.
2690						for (i in cs) {
2691							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.
2692								s[i] = cs[i];
2693							}
2694						}
2695					}
2696				} else if ((cs = t.currentStyle || t.style)) {
2697					for (i in cs) {
2698						if (typeof(i) === "string" && s[i] === undefined) {
2699							s[i.replace(_camelExp, _camelFunc)] = cs[i];
2700						}
2701					}
2702				}
2703				if (!_supportsOpacity) {
2704					s.opacity = _getIEOpacity(t);
2705				}
2706				tr = _getTransform(t, cs, false);
2707				s.rotation = tr.rotation;
2708				s.skewX = tr.skewX;
2709				s.scaleX = tr.scaleX;
2710				s.scaleY = tr.scaleY;
2711				s.x = tr.x;
2712				s.y = tr.y;
2713				if (_supports3D) {
2714					s.z = tr.z;
2715					s.rotationX = tr.rotationX;
2716					s.rotationY = tr.rotationY;
2717					s.scaleZ = tr.scaleZ;
2718				}
2719				if (s.filters) {
2720					delete s.filters;
2721				}
2722				return s;
2723			},
2724
2725			// @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
2725ontaining 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.
2726			_cssDif = function(t, s1, s2, vars, forceLookup) {
2727				var difs = {},
2728					style = t.style,
2729					val, p, mpt;
2730				for (p in s2) {
2731					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") {
2732						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.
2733						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.
2734							mpt = new MiniPropTween(style, p, style[p], mpt);
2735						}
2736					}
2737				}
2738				if (vars) {
2739					for (p in vars) { //copy properties (except className)
2740						if (p !== "className") {
2741							difs[p] = vars[p];
2742						}
2743					}
2744				}
2745				return {difs:difs, firstMPT:mpt};
2746			},
2747			_dimensions = {width:["Left","Right"], height:["Top","Bottom"]},
2748			_margins = ["marginLeft","marginRight","marginTop","marginBottom"],
2749
2750			/**
2751			 * @private Gets the width or height of an element
2752			 * @param {!Object} t Target element
2753			 * @param {!string} p Property name ("width" or "height")
2754			 * @param {Object=} cs Computed style object (if one exists). Just a speed optimization.
2755			 * @return {number} Dimension (in pixels)
2756			 */
2757			_getDimension = function(t, p, cs) {
2758				var v = parseFloat((p === "width") ? t.offsetWidth : t.offsetHeight),
2759					a = _dimensions[p],
2760					i = a.length;
2761				cs = cs || _getComputedStyle(t, null);
2762				while (--i > -1) {
2763					v -= parseFloat( _getStyle(t, "padding" + a[i], cs, true) ) || 0;
2764					v -= parseFloat( _getStyle(t, "border" + a[i] + "Width", cs, true) ) || 0;
2765				}
2766				return v;
2767			},
2768
2769			// @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)
2770			_parsePosition = function(v, recObj) {
2771				if (v === "contain" || v === "auto" || v === "auto auto") {
2772					return v + " ";
2773				}
2774				if (v == null || v === "") { //note: Firefox uses "auto auto" as default whereas Chrome uses "auto".
2775					v = "0 0";
2776				}
2777				var a = v.split(" "),
2778					x = (v.indexOf("left") !== -1) ? "0%" : (v.indexOf("right") !== -1) ? "100%" : a[0],
2779					y = (v.indexOf("top") !== -1) ? "0%" : (v.indexOf("bottom") !== -1) ? "100%" : a[1];
2780				if (y == null) {
2781					y = (x === "center") ? "50%" : "0";
2782				} else if (y === "center") {
2783					y = "50%";
2784				}
2785				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
2785ould be used to describe horizontal or vertical, hence the isNaN(). If there's an "=" sign in the value, it's relative.
2786					x = "50%";
2787				}
2788				v = x + " " + y + ((a.length > 2) ? " " + a[2] : "");
2789				if (recObj) {
2790					recObj.oxp = (x.indexOf("%") !== -1);
2791					recObj.oyp = (y.indexOf("%") !== -1);
2792					recObj.oxr = (x.charAt(1) === "=");
2793					recObj.oyr = (y.charAt(1) === "=");
2794					recObj.ox = parseFloat(x.replace(_NaNExp, ""));
2795					recObj.oy = parseFloat(y.replace(_NaNExp, ""));
2796					recObj.v = v;
2797				}
2798				return recObj || v;
2799			},
2800
2801			/**
2802			 * @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!)
2803			 * @param {(number|string)} e End value which is typically a string, but could be a number
2804			 * @param {(number|string)} b Beginning value which is typically a string but could be a number
2805			 * @return {number} Amount of change between the beginning and ending values (relative values that have a "+=" or "-=" are recognized)
2806			 */
2807			_parseChange = function(e, b) {
2808				return (typeof(e) === "string" && e.charAt(1) === "=") ? parseInt(e.charAt(0) + "1", 10) * parseFloat(e.substr(2)) : parseFloat(e) - parseFloat(b);
2809			},
2810
2811			/**
2812			 * @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.
2813			 * @param {Object} v Value to be parsed
2814			 * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter)
2815			 * @return {number} Parsed value
2816			 */
2817			_parseVal = function(v, d) {
2818				return (v == null) ? d : (typeof(v) === "string" && v.charAt(1) === "=") ? parseInt(v.charAt(0) + "1", 10) * parseFloat(v.substr(2)) + d : parseFloat(v);
2819			},
2820
2821			/**
2822			 * @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.
2823			 * @param {Object} v Value to be parsed
2824			 * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter)
2825			 * @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"
2826			 * @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.
2827			 * @return {number} parsed angle in radians
2828			 */
2829			_parseAngle = function(v, d, p, directionalEnd) {
2830				var min = 0.000001,
2831					cap, split, dif, result, isRelative;
2832				if (v == null) {
2833					result = d;
2834				} else if (typeof(v) === "number") {
2835					result = v;
2836				} else {
2837					cap = 360;
2838					split = v.split("_");
2839					isRelative = (v.charAt(1) === "=");
2840					dif = (isRelative ? parseInt(v.charAt(0) + "1", 10) * parseFloat(split[0].substr(2)) : parseFloat(split[0])) * ((v.indexOf("rad") === -1) ? 1 : _RAD2DEG) - (isRelative ? 0 : d);
2841					if (split.length) {
2842						if (directionalEnd) {
2843							directionalEnd[p] = d + dif;
2844						}
2845						if (v.indexOf("short") !== -1) {
2846							dif = dif % cap;
2847							if (dif !== dif % (cap / 2)) {
2848								dif = (dif < 0) ? dif + cap : dif - cap;
2849							}
2850						}
2851						if (v.indexOf("_cw") !== -1 && dif < 0) {
2852							dif = ((dif + cap * 9999999999) % cap) - ((dif / cap) | 0) * cap;
2853						} else if (v.indexOf("ccw") !== -1 && dif > 0) {
2854							dif = ((dif - cap * 9999999999) % cap) - ((dif / cap) | 0) * cap;
2855						}
2856					}
2857					result = d + dif;
2858				}
2859				if (result < min && result > -min) {
2860					result = 0;
2861				}
2862				return result;
2863			},
2864
2865			_colorLookup = {aqua:[0,255,255],
2866				lime:[0,255,0],
2867				silver:[192,192,192],
2868				black:[0,0,0],
2869				maroon:[128,0,0],
2870				teal:[0,128,128],
2871				blue:[0,0,255],
2872				navy:[0,0,128],
2873				white:[255,255,255],
2874				fuchsia:[255,0,255],
2875				olive:[128,128,0],
2876				yellow:[255,255,0],
2877				orange:[255,165,0],
2878				gray:[128,128,128],
2879				purple:[128,0,128],
2880				green:[0,128,0],
2881				red:[255,0,0],
2882				pink:[255,192,203],
2883				cyan:[0,255,255],
2884				transparent:[255,255,255,0]},
2885
2886			_hue = function(h, m1, m2) {
2887				h = (h < 0) ? h + 1 : (h > 1) ? h - 1 : h;
2888				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;
2889			},
2890
2891			/**
2892			 * @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).
2893			 * @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.
2894			 * @param {(boolean)} toHSL If true, an hsl() or hsla() value will be returned instead of rgb() or rgba()
2895			 * @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.
2896			 */
2897			_parseColor = CSSPlugin.parseColor = function(v, toHSL) {
2898				var a, r, g, b, h, s, l, max, min, d, wasHSL;
2899				if (!v) {
2900					a = _colorLookup.black;
2901				} else if (typeof(v) === "number") {
2902					a = [v >> 16, (v >> 8) & 255, v & 255];
2903				} else {
2904					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.
2905						v = v.substr(0, v.length - 1);
2906					}
2907					if (_colorLookup[v]) {
2908						a = _colorLookup[v];
2909					} else if (v.charAt(0) === "#") {
2910						if (v.length === 4) { //for shorthand like #9F0
2911							r = v.charAt(1);
2912							g = v.charAt(2);
2913							b = v.charAt(3);
2914							v = "#" + r + r + g + g + b + b;
2915						}
2916						v = parseInt(v.substr(1), 16);
2917						a = [v >> 16, (v >> 8) & 255, v & 255];
2918					} else if (v.substr(0, 3) === "hsl") {
2919						a = wasHSL = v.match(_numExp);
2920						if (!toHSL) {
2921							h = (Number(a[0]) % 360) / 360;
2922							s = Number(a[1]) / 100;
2923							l = Number(a[2]) / 100;
2924							g = (l <= 0.5) ? l * (s + 1) : l + s - l * s;
2925							r = l * 2 - g;
2926							if (a.length > 3) {
2927								a[3] = Number(v[3]);
2928							}
2929							a[0] = _hue(h + 1 / 3, r, g);
2930							a[1] = _hue(h, r, g);
2931							a[2] = _hue(h - 1 / 3, r, g);
2932						} else if (v.indexOf("=") !== -1) { //if relative values are found, just return the raw strings with the relative prefixes in place.
2933							return v.match(_relNumExp);
2934						}
2935					} else {
2936						a = v.match(_numExp) || _colorLookup.transparent;
2937					}
2938					a[0] = Number(a[0]);
2939					a[1] = Number(a[1]);
2940					a[2] = Number(a[2]);
2941					if (a.length > 3) {
2942						a[3] = Number(a[3]);
2943					}
2944				}
2945				if (toHSL && !wasHSL) {
2946					r = a[0] / 255;
2947					g = a[1] / 255;
2948					b = a[2] / 255;
2949					max = Math.max(r, g, b);
2950					min = Math.min(r, g, b);
2951					l = (max + min) / 2;
2952					if (max === min) {
2953						h = s = 0;
2954					} else {
2955						d = max - min;
2956						s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
2957						h = (max === r) ? (g - b) / d + (g < b ? 6 : 0) : (max === g) ? (b - r) / d + 2 : (r - g) / d + 4;
2958						h *= 60;
2959					}
2960					a[0] = (h + 0.5) | 0;
2961					a[1] = (s * 100 + 0.5) | 0;
2962					a[2] = (l * 100 + 0.5) | 0;
2963				}
2964				return a;
2965			},
2966			_formatColors = function(s, toHSL) {
2967				var colors = s.match(_colorExp) || [],
2968					charIndex = 0,
2969					parsed = colors.length ? "" : s,
2970					i, color, temp;
2971				for (i = 0; i < colors.length; i++) {
2972					color = colors[i];
2973					temp = s.substr(charIndex, s.indexOf(color, charIndex)-charIndex);
2974					charIndex += temp.length + color.length;
2975					color = _parseColor(color, toHSL);
2976					if (color.length === 3) {
2977						color.push(1);
2978					}
2979					parsed += temp + (toHSL ? "hsla(" + color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : "rgba(" + color.join(",")) + ")";
2980				}
2981				return parsed;
2982			},
2983			_colorExp = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#.+?\\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.
2984
2985		for (p in _colorLookup) {
2986			_colorExp += "|" + p + "\\b";
2987		}
2988		_colorExp = new RegExp(_colorExp+")", "gi");
2989
2990		CSSPlugin.colorStringFilter = function(a) {
2991			var combined = a[0] + a[1],
2992				toHSL;
2993			_colorExp.lastIndex = 0;
2994			if (_colorExp.test(combined)) {
2995				toHSL = (combined.indexOf("hsl(") !== -1 || combined.indexOf("hsla(") !== -1);
2996				a[0] = _formatColors(a[0], toHSL);
2997				a[1] = _formatColors(a[1], toHSL);
2998			}
2999		};
3000
3001		if (!TweenLite.defaultStringFilter) {
3002			TweenLite.defaultStringFilter = CSSPlugin.colorStringFilter;
3003		}
3004
3005		/**
3006		 * @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.
3007		 * @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.
3008		 * @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.
3009		 * @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.
3010		 * @return {Function} formatter function
3011		 */
3012		var _getFormatter = function(dflt, clr, collapsible, multi) {
3013				if (dflt == null) {
3014					return function(v) {return v;};
3015				}
3016				var dColor = clr ? (dflt.match(_colorExp) || [""])[0] : "",
3017					dVals = dflt.split(dColor).join("").match(_valuesExp) || [],
3018					pfx = dflt.substr(0, dflt.indexOf(dVals[0])),
3019					sfx = (dflt.charAt(dflt.length - 1) === ")") ? ")" : "",
3020					delim = (dflt.indexOf(" ") !== -1) ? " " : ",",
3021					numVals = dVals.length,
3022					dSfx = (numVals > 0) ? dVals[0].replace(_numExp, "") : "",
3023					formatter;
3024				if (!numVals) {
3025					return function(v) {return v;};
3026				}
3027				if (clr) {
3028					formatter = function(v) {
3029						var color, vals, i, a;
3030						if (typeof(v) === "number") {
3031							v += dSfx;
3032						} else if (multi && _commasOutsideParenExp.test(v)) {
3033							a = v.replace(_commasOutsideParenExp, "|").split("|");
3034							for (i = 0; i < a.length; i++) {
3035								a[i] = formatter(a[i]);
3036							}
3037							return a.join(",");
3038						}
3039						color = (v.match(_colorExp) || [dColor])[0];
3040						vals = v.split(color).join("").match(_valuesExp) || [];
3041						i = vals.length;
3042						if (numVals > i--) {
3043							while (++i < numVals) {
3044								vals[i] = collapsible ? vals[(((i - 1) / 2) | 0)] : dVals[i];
3045							}
3046						}
3047						return pfx + vals.join(delim) + delim + color + sfx + (v.indexOf("inset") !== -1 ? " inset" : "");
3048					};
3049					return formatter;
3050
3051				}
3052				formatter = function(v) {
3053					var vals, a, i;
3054					if (typeof(v) === "number") {
3055						v += dSfx;
3056					} else if (multi && _commasOutsideParenExp.test(v)) {
3057						a = v.replace(_commasOutsideParenExp, "|").split("|");
3058						for (i = 0; i < a.length; i++) {
3059							a[i] = formatter(a[i]);
3060						}
3061						return a.join(",");
3062					}
3063					vals = v.match(_valuesExp) || [];
3064					i = vals.length;
3065					if (numVals > i--) {
3066						while (++i < numVals) {
3067							vals[i] = collapsible ? vals[(((i - 1) / 2) | 0)] : dVals[i];
3068						}
3069					}
3070					return pfx + vals.join(delim) + sfx;
3071				};
3072				return formatter;
3073			},
3074
3075			/**
3076			 * @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.
3077			 * @param {!string} props a comma-delimited list of property names in order from top to left, like "marginTop,marginRight,marginBottom,marginLeft"
3078			 * @return {Function} a formatter function
3079			 */
3080			_getEdgeParser = function(props) {
3081				props = props.split(",");
3082				return function(t, e, p, cssp, pt, plugin, vars) {
3083					var a = (e + "").split(" "),
3084						i;
3085					vars = {};
3086					for (i = 0; i < 4; i++) {
3087						vars[props[i]] = a[i] = a[i] || a[(((i - 1) / 2) >> 0)];
3088					}
3089					return cssp.parse(t, vars, pt, plugin);
3090				};
3091			},
3092
3093			// @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.
3094			_setPluginRatio = _internals._setPluginRatio = function(v) {
3095				this.plugin.setRatio(v);
3096				var d = this.data,
3097					proxy = d.proxy,
3098					mpt = d.firstMPT,
3099					min = 0.000001,
3100					val, pt, i, str;
3101				while (mpt) {
3102					val = proxy[mpt.v];
3103					if (mpt.r) {
3104						val = Math.round(val);
3105					} else if (val < min && val > -min) {
3106						val = 0;
3107					}
3108					mpt.t[mpt.p] = val;
3109					mpt = mpt._next;
3110				}
3111				if (d.autoRotate) {
3112					d.autoRotate.rotation = proxy.rotation;
3113				}
3114				//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.
3115				if (v === 1) {
3116					mpt = d.firstMPT;
3117					while (mpt) {
3118						pt = mpt.t;
3119						if (!pt.type) {
3120							pt.e = pt.s + pt.xs0;
3121						} else if (pt.type === 1) {
3122							str = pt.xs0 + pt.s + pt.xs1;
3123							for (i = 1; i < pt.l; i++) {
3124								str += pt["xn"+i] + pt["xs"+(i+1)];
3125							}
3126							pt.e = str;
3127						}
3128						mpt = mpt._next;
3129					}
3130				}
3131			},
3132
3133			/**
3134			 * @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.
3135			 * @param {!Object} t target object whose property we're tweening (often a CSSPropTween)
3136			 * @param {!string} p property name
3137			 * @param {(number|string|object)} v value
3138			 * @param {MiniPropTween=} next next MiniPropTween in the linked list
3139			 * @param {boolean=} r if true, the tweened value should be rounded to the nearest integer
3140			 */
3141			MiniPropTween = function(t, p, v, next, r) {
3142				this.t = t;
3143				this.p = p;
3144				this.v = v;
3145				this.r = r;
3146				if (next) {
3147					next._prev = this;
3148					this._next = next;
3149				}
3150			},
3151
3152			/**
3153			 * @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.
3154			 * This method returns an object that has the following properties:
3155			 *  - 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
3156			 *  - 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
3157			 *  - firstMPT: the first MiniPropTween in the linked list
3158			 *  - 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.
3159			 * @param {!Object} t target object to be tweened
3160			 * @param {!(Object|string)} vars the object containing the information about the tweening values (typically the end/destination values) that should be parsed
3161			 * @param {!CSSPlugin} cssp The CSSPlugin instance
3162			 * @param {CSSPropTween=} pt the next CSSPropTween in the linked list
3163			 * @param {TweenPlugin=} plugin the external TweenPlugin instance that will be handling tweening the numeric values
3164			 * @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.
3165			 * @return An object containing the following properties: proxy, end, firstMPT, and pt (see above for descriptions)
3166			 */
3167			_parseToProxy = _internals._parseToProxy = function(t, vars, cssp, pt, plugin, shallow) {
3168				var bpt = pt,
3169					start = {},
3170					end = {},
3171					transform = cssp._transform,
3172					oldForce = _forcePT,
3173					i, p, xp, mpt, firstPT;
3174				cssp._transform = null;
3175				_forcePT = vars;
3176				pt = firstPT = cssp.parse(t, vars, pt, plugin);
3177				_forcePT = oldForce;
3178				//break off from the linked list so the new ones are isolated.
3179				if (shallow) {
3180					cssp._transform = transform;
3181					if (bpt) {
3182						bpt._prev = null;
3183						if (bpt._prev) {
3184							bpt._prev._next = null;
3185						}
3186					}
3187				}
3188				while (pt && pt !== bpt) {
3189					if (pt.type <= 1) {
3190						p = pt.p;
3191						end[p] = pt.s + pt.c;
3192						start[p] = pt.s;
3193						if (!shallow) {
3194							mpt = new MiniPropTween(pt, "s", p, mpt, pt.r);
3195							pt.c = 0;
3196						}
3197						if (pt.type === 1) {
3198							i = pt.l;
3199							while (--i > 0) {
3200								xp = "xn" + i;
3201								p = pt.p + "_" + xp;
3202								end[p] = pt.data[xp];
3203								start[p] = pt[xp];
3204								if (!shallow) {
3205									mpt = new MiniPropTween(pt, xp, p, mpt, pt.rxp[xp]);
3206								}
3207							}
3208						}
3209					}
3210					pt = pt._next;
3211				}
3212				return {proxy:start, end:end, firstMPT:mpt, pt:firstPT};
3213			},
3214
3215
3216
3217			/**
3218			 * @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.
3219			 * CSSPropTweens have the following optional properties as well (not defined through the constructor):
3220			 *  - 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.
3221			 *  - 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)
3222			 *  - plugin: The TweenPlugin instance that will handle the tweening of any complex values. For example, sometimes we don't want to use normal subt
3222weens (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.
3223			 *  - 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.
3224			 *  - 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.
3225			 * @param {!Object} t Target object whose property will be tweened. Often a DOM element, but not always. It could be anything.
3226			 * @param {string} p Property to tween (name). For example, to tween element.width, p would be "width".
3227			 * @param {number} s Starting numeric value
3228			 * @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.
3229			 * @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.
3230			 * @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.
3231			 * @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"
3232			 * @param {boolean=} r If true, the value(s) should be rounded
3233			 * @param {number=} pr Priority in the linked list order. Higher priority CSSPropTweens will be updated before lower priority ones. The default priority is 0.
3234			 * @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.
3235			 * @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.
3236			 */
3237			CSSPropTween = _internals.CSSPropTween = function(t, p, s, c, next, type, n, r, pr, b, e) {
3238				this.t = t; //target
3239				this.p = p; //property
3240				this.s = s; //starting value
3241				this.c = c; //change value
3242				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)
3243				if (!(t instanceof CSSPropTween)) {
3244					_overwriteProps.push(this.n);
3245				}
3246				this.r = r; //round (boolean)
3247				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
3248				if (pr) {
3249					this.pr = pr;
3250					_hasPriority = true;
3251				}
3252				this.b = (b === undefined) ? s : b;
3253				this.e = (e === undefined) ? s + c : e;
3254				if (next) {
3255					this._next = next;
3256					next._prev = this;
3257				}
3258			},
3259
3260			_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
3261				var pt = new CSSPropTween(target, prop, start, end - start, next, -1, overwriteProp);
3262				pt.b = start;
3263				pt.e = pt.xs0 = end;
3264				return pt;
3265			},
3266
3267			/**
3268			 * 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:
3269			 * 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);
3270			 * 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().
3271			 * 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.
3272			 *
3273			 * @param {!Object} t Target whose property will be tweened
3274			 * @param {!string} p Property that will be tweened (its name, like "left" or "backgroundColor" or "boxShadow")
3275			 * @param {string} b Beginning value
3276			 * @param {string} e Ending value
3277			 * @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)
3278			 * @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
3279			 * @param {?CSSPropTween} pt CSSPropTween instance that is the current head of the linked list (we'll prepend to this).
3280			 * @param {number=} pr Priority in the linked list order. Higher priority properties will be updated before lower priority ones. The default priority is 0.
3281			 * @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}
3282			 * @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.
3283			 * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parseComplex() call.
3284			 */
3285			_parseComplex = CSSPlugin.parseComplex = function(t, p, b, e, clrs, dflt, pt, pr, plugin, setRatio) {
3286				//DEBUG: _log("parseComplex: "+p+", b: "+b+", e: "+e);
3287				b = b || dflt || "";
3288				pt = new CSSPropTween(t, p, 0, 0, pt, (setRatio ? 2 : 1), null, false, pr, b, e);
3289				e += ""; //ensures it's a string
3290				var ba = b.split(", ").join(",").split(" "), //beginning array
3291					ea = e.split(", ").join(",").split(" "), //ending array
3292					l = ba.length,
3293					autoRound = (_autoRound !== false),
3294					i, xi, ni, bv, ev, bnums, enums, bn, hasAlpha, temp, cv, str, useHSL;
3295				if (e.indexOf(",") !== -1 || b.indexOf(",") !== -1) {
3296					ba = ba.join(" ").replace(_commasOutsideParenExp, ", ").split(" ");
3297					ea = ea.join(" ").replace(_commasOutsideParenExp, ", ").split(" ");
3298					l = ba.length;
3299				}
3300				if (l !== ea.length) {
3301					//DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")");
3302					ba = (dflt || "").split(" ");
3303					l = ba.length;
3304				}
3305				pt.plugin = plugin;
3306				pt.setRatio = setRatio;
3307				_colorExp.lastIndex = 0;
3308				for (i = 0; i < l; i++) {
3309					bv = ba[i];
3310					ev = ea[i];
3311					bn = parseFloat(bv);
3312					//if the value begins with a number (most common). It's fine if it has a suffix like px
3313					if (bn || bn === 0) {
3314						pt.appendXtra("", bn, _parseChange(ev, bn), ev.replace(_relNumExp, ""), (autoRound && ev.indexOf("px") !== -1), true);
3315
3316					//if the value is a color
3317					} else if (clrs && _colorExp.test(bv)) {
3318						str = ev.charAt(ev.length - 1) === "," ? ")," : ")"; //if there's a comma at the end, retain it.
3319						useHSL = (ev.indexOf("hsl") !== -1 && _supportsOpacity);
3320						bv = _parseColor(bv, useHSL);
3321						ev = _parseColor(ev, useHSL);
3322						hasAlpha = (bv.length + ev.length > 6);
3323						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
3324							pt["xs" + pt.l] += pt.l ? " transparent" : "transparent";
3325							pt.e = pt.e.split(ea[i]).join("transparent");
3326						} else {
3327							if (!_supportsOpacity) { //old versions of IE don't support rgba().
3328								hasAlpha = false;
3329							}
3330							if (useHSL) {
3331								pt.appendXtra((hasAlpha ? "hsla(" : "hsl("), bv[0], _parseChange(ev[0], bv[0]), ",", false, true)
3332									.appendXtra("", bv[1], _parseChange(ev[1], bv[1]), "%,", false)
3333									.appendXtra("", bv[2], _parseChange(ev[2], bv[2]), (hasAlpha ? "%," : "%" + str), false);
3334							} else {
3335								pt.appendXtra((hasAlpha ? "rgba(" : "rgb("), bv[0], ev[0] - bv[0], ",", true, true)
3336									.appendXtra("", bv[1], ev[1] - bv[1], ",", true)
3337									.appendXtra("", bv[2], ev[2] - bv[2], (hasAlpha ? "," : str), true);
3338							}
3339
3340							if (hasAlpha) {
3341								bv = (bv.length < 4) ? 1 : bv[3];
3342								pt.appendXtra("", bv, ((ev.length < 4) ? 1 : ev[3]) - bv, str, false);
3343							}
3344						}
3345						_colorExp.lastIndex = 0; //otherwise the test() on the RegExp could move the lastIndex and taint future results.
3346
3347					} else {
3348						bnums = bv.match(_numExp); //gets each group of numbers in the beginning value string and drops them into an array
3349
3350						//if no number is found, treat it as a non-tweening value and just append the string to the current xs.
3351						if (!bnums) {
3352							pt["xs" + pt.l] += pt.l ? " " + bv : bv;
3353
3354						//loop through all the numbers that are found and construct the extra values on the pt.
3355						} else {
3356							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
3357							if (!enums || enums.length !== bnums.length) {
3358								//DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")");
3359								return pt;
3360							}
3361							ni = 0;
3362							for (xi = 0; xi < bnums.length; xi++) {
3363								cv = bnums[xi];
3364								temp = bv.indexOf(cv, ni);
3365								pt.appendXtra(bv.substr(ni, temp - ni), Number(cv), _parseChange(enums[xi], cv), "", (autoRound && bv.substr(temp + cv.length, 2) === "px"), (xi === 0));
3366								ni = temp + cv.length;
3367							}
3368							pt["xs" + pt.l] += bv.substr(ni);
3369						}
3370					}
3371				}
3372				//if there are relative values ("+=" or "-=" prefix), we need to adjust the ending value to eliminate the prefixes and combine the values properly.
3373				if (e.indexOf("=") !== -1) if (pt.data) {
3374					str = pt.xs0 + pt.data.s;
3375					for (i = 1; i < pt.l; i++) {
3376						str += pt["xs" + i] + pt.data["xn" + i];
3377					}
3378					pt.e = str + pt["xs" + i];
3379				}
3380				if (!pt.l) {
3381					pt.type = -1;
3382					pt.xs0 = pt.e;
3383				}
3384				return pt.xfirst || pt;
3385			},
3386			i = 9;
3387
3388
3389		p = CSSPropTween.prototype;
3390		p.l = p.pr = 0; //length (number of extra properties like xn1, xn2, xn3, etc.
3391		while (--i > 0) {
3392			p["xn" + i] = 0;
3393			p["xs" + i] = "";
3394		}
3395		p.xs0 = "";
3396		p._next = p._prev = p.xfirst = p.data = p.plugin = p.setRatio = p.rxp = null;
3397
3398
3399		/**
3400		 * 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:
3401		 * xs0:"rect(", s:10, xs1:"px, ", xn1:5, xs2:"px, ", xn2:0, xs3:"px, ", xn3:20, xn4:"px)"
3402		 * And they'd all get joined together when the CSSPlugin renders (in the setRatio() method).
3403		 * @param {string=} pfx Prefix (if any)
3404		 * @param {!number} s Starting value
3405		 * @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.
3406		 * @param {string=} sfx Suffix (if any)
3407		 * @param {boolean=} r Round (if true).
3408		 * @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.
3409		 * @return {CSSPropTween} returns itself so that multiple methods can be chained together.
3410		 */
3411		p.appendXtra = function(pfx, s, c, sfx, r, pad) {
3412			var pt = this,
3413				l = pt.l;
3414			pt["xs" + l] += (pad && l) ? " " + pfx : pfx || "";
3415			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!
3416				pt["xs" + l] += s + (sfx || "");
3417				return pt;
3418			}
3419			pt.l++;
3420			pt.type = pt.setRatio ? 2 : 1;
3421			pt["xs" + pt.l] = sfx || "";
3422			if (l > 0) {
3423				pt.data["xn" + l] = s + c;
3424				pt.rxp["xn" + l] = r; //round extra property (we need to tap into this in the _parseToProxy() method)
3425				pt["xn" + l] = s;
3426				if (!pt.plugin) {
3427					pt.xfirst = new CSSPropTween(pt, "xn" + l, s, c, pt.xfirst || pt, 0, pt.n, r, pt.pr);
3428					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.
3429				}
3430				return pt;
3431			}
3432			pt.data = {s:s + c};
3433			pt.rxp = {};
3434			pt.s = s;
3435			pt.c = c;
3436			pt.r = r;
3437			return pt;
3438		};
3439
3440		/**
3441		 * @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.
3442		 * @param {!string} p Property name (like "boxShadow" or "throwProps")
3443		 * @param {Object=}
3443 options An object containing any of the following configuration options:
3444		 *                      - defaultValue: the default value
3445		 *                      - 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)
3446		 *                      - 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.)
3447		 *                      - prefix: if true, we'll determine whether or not this property requires a vendor prefix (like Webkit or Moz or ms or O)
3448		 *                      - color: set this to true if the value for this SpecialProp may contain color-related values like rgb(), rgba(), etc.
3449		 *                      - priority: priority in the linked list order. Higher priority SpecialProps will be updated before lower priority ones. The default priority is 0.
3450		 *                      - multi: if true, the formatter should accommodate a comma-delimited list of values, like boxShadow could have multiple boxShadows listed out.
3451		 *                      - 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.
3452		 *                      - 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).
3453		 */
3454		var SpecialProp = function(p, options) {
3455				options = options || {};
3456				this.p = options.prefix ? _checkPropPrefix(p) || p : p;
3457				_specialProps[p] = _specialProps[this.p] = this;
3458				this.format = options.formatter || _getFormatter(options.defaultValue, options.color, options.collapsible, options.multi);
3459				if (options.parser) {
3460					this.parse = options.parser;
3461				}
3462				this.clrs = options.color;
3463				this.multi = options.multi;
3464				this.keyword = options.keyword;
3465				this.dflt = options.defaultValue;
3466				this.pr = options.priority || 0;
3467			},
3468
3469			//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.
3470			_registerComplexSpecialProp = _internals._registerComplexSpecialProp = function(p, options, defaults) {
3471				if (typeof(options) !== "object") {
3472					options = {parser:defaults}; //to make backwards compatible with older versions of BezierPlugin and ThrowPropsPlugin
3473				}
3474				var a = p.split(","),
3475					d = options.defaultValue,
3476					i, temp;
3477				defaults = defaults || [d];
3478				for (i = 0; i < a.length; i++) {
3479					options.prefix = (i === 0 && options.prefix);
3480					options.defaultValue = defaults[i] || d;
3481					temp = new SpecialProp(a[i], options);
3482				}
3483			},
3484
3485			//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.
3486			_registerPluginProp = function(p) {
3487				if (!_specialProps[p]) {
3488					var pluginName = p.charAt(0).toUpperCase() + p.substr(1) + "Plugin";
3489					_registerComplexSpecialProp(p, {parser:function(t, e, p, cssp, pt, plugin, vars) {
3490						var pluginClass = _globals.com.greensock.plugins[pluginName];
3491						if (!pluginClass) {
3492							_log("Error: " + pluginName + " js file not loaded.");
3493							return pt;
3494						}
3495						pluginClass._cssRegister();
3496						return _specialProps[p].parse(t, e, p, cssp, pt, plugin, vars);
3497					}});
3498				}
3499			};
3500
3501
3502		p = SpecialProp.prototype;
3503
3504		/**
3505		 * 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
3505adow) 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)
3506		 * @param {!Object} t target element
3507		 * @param {(string|number|object)} b beginning value
3508		 * @param {(string|number|object)} e ending (destination) value
3509		 * @param {CSSPropTween=} pt next CSSPropTween in the linked list
3510		 * @param {TweenPlugin=} plugin If another plugin will be tweening the complex value, that TweenPlugin instance goes here.
3511		 * @param {function=} setRatio If a custom setRatio() method should be used to handle this complex value, that goes here.
3512		 * @return {CSSPropTween=} First CSSPropTween in the linked list
3513		 */
3514		p.parseComplex = function(t, b, e, pt, plugin, setRatio) {
3515			var kwd = this.keyword,
3516				i, ba, ea, l, bi, ei;
3517			//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)
3518			if (this.multi) if (_commasOutsideParenExp.test(e) || _commasOutsideParenExp.test(b)) {
3519				ba = b.replace(_commasOutsideParenExp, "|").split("|");
3520				ea = e.replace(_commasOutsideParenExp, "|").split("|");
3521			} else if (kwd) {
3522				ba = [b];
3523				ea = [e];
3524			}
3525			if (ea) {
3526				l = (ea.length > ba.length) ? ea.length : ba.length;
3527				for (i = 0; i < l; i++) {
3528					b = ba[i] = ba[i] || this.dflt;
3529					e = ea[i] = ea[i] || this.dflt;
3530					if (kwd) {
3531						bi = b.indexOf(kwd);
3532						ei = e.indexOf(kwd);
3533						if (bi !== ei) {
3534							if (ei === -1) { //if the keyword isn't in the end value, remove it from the beginning one.
3535								ba[i] = ba[i].split(kwd).join("");
3536							} else if (bi === -1) { //if the keyword isn't in the beginning, add it.
3537								ba[i] += " " + kwd;
3538							}
3539						}
3540					}
3541				}
3542				b = ba.join(", ");
3543				e = ea.join(", ");
3544			}
3545			return _parseComplex(t, this.p, b, e, this.clrs, this.dflt, pt, this.pr, plugin, setRatio);
3546		};
3547
3548		/**
3549		 * 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:
3550		 * this._firstPT = sp.parse(element, "5px 10px 20px rgb(2550,102,51)", "boxShadow", this);
3551		 * 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).
3552		 * @param {!Object} t Target object whose property is being tweened
3553		 * @param {Object} e End value as provided in the vars object (typically a string, but not always - like a throwProps would be an object).
3554		 * @param {!string} p Property name
3555		 * @param {!CSSPlugin} cssp The CSSPlugin instance that should be associated with this tween.
3556		 * @param {?CSSPropTween} pt The CSSPropTween that is the current head of the linked list (we'll prepend to it)
3557		 * @param {TweenPlugin=} plugin If a plugin will be used to tween the parsed value, this is the plugin instance.
3558		 * @param {Object=} vars Original vars object that contains the data for parsing.
3559		 * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parse() call.
3560		 */
3561		p.parse = function(t, e, p, cssp, pt, plugin, vars) {
3562			return this.parseComplex(t.style, this.format(_getStyle(t, this.p, _cs, false, this.dflt)), this.format(e), pt, plugin);
3563		};
3564
3565		/**
3566		 * 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:
3567		 *  1) Target object whose property should be tweened (typically a DOM element)
3568		 *  2) The end/destination value (could be a string, number, object, or whatever you want)
3569		 *  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)
3570		 *
3571		 * 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:
3572		 *
3573		 * CSSPlugin.registerSpecialProp("myCustomProp", function(target, value, tween) {
3574		 *      var start = target.style.width;
3575		 *      return function(ratio) {
3576		 *              target.style.width = (start + value * ratio) + "px";
3577		 *              console.log("set width to " + target.style.width);
3578		 *          }
3579		 * }, 0);
3580		 *
3581		 * Then, when I do this tween, it will trigger my special property:
3582		 *
3583		 * TweenLite.to(element, 1, {css:{myCustomProp:100}});
3584		 *
3585		 * In the example, of course, we're just changing the width, but you can do anything you want.
3586		 *
3587		 * @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}})
3588		 * @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.
3589		 * @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.
3590		 */
3591		CSSPlugin.registerSpecialProp = function(name, onInitTween, priority) {
3592			_registerComplexSpecialProp(name, {parser:function(t, e, p, cssp, pt, plugin, vars) {
3593				var rv = new CSSPropTween(t, p, 0, 0, pt, 2, p, false, priority);
3594				rv.plugin = plugin;
3595				rv.setRatio = onInitTween(t, e, cssp._tween, p);
3596				return rv;
3597			}, priority:priority});
3598		};
3599
3600
3601
3602
3603
3604
3605		//transform-related methods and properties
3606		CSSPlugin.useSVGTransformAttr = _isSafari || _isFirefox; //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).
3607		var _transformProps = ("scaleX,scaleY,scaleZ,x,y,z,skewX,skewY,rotation,rotationX,rotationY,perspective,xPercent,yPercent").split(","),
3608			_transformProp = _checkPropPrefix("transform"), //the Javascript (camelCase) transform property, like msTransform, WebkitTransform, MozTransform, or OTransform.
3609			_transformPropCSS = _prefixCSS + "transform",
3610			_transformOriginProp = _checkPropPrefix("transformOrigin"),
3611			_supports3D = (_checkPropPrefix("perspective") !== null),
3612			Transform = _internals.Transform = function() {
3613				this.perspective = parseFloat(CSSPlugin.defaultTransformPerspective) || 0;
3614				this.force3D = (CSSPlugin.defaultForce3D === false || !_supports3D) ? false : CSSPlugin.defaultForce3D || "auto";
3615			},
3616			_SVGElement = window.SVGElement,
3617			_useSVGTransformAttr,
3618			//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.
3619
3620			_createSVG = function(type, container, attributes) {
3621				var element = _doc.createElementNS("http://www.w3.org/2000/svg", type),
3622					reg = /([a-z])([A-Z])/g,
3623					p;
3624				for (p in attributes) {
3625					element.setAttributeNS(null, p.replace(reg, "$1-$2").toLowerCase(), attributes[p]);
3626				}
3627				container.appendChild(element);
3628				return element;
3629			},
3630			_docElement = _doc.documentElement,
3631			_forceSVGTransformAttr = (function() {
3632				//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
3633				var force = _ieVers || (/Android/i.test(_agent) && !window.chrome),
3634					svg, rect, width;
3635				if (_doc.createElementNS && !force) { //IE8 and earlier doesn't support SVG anyway
3636					svg = _createSVG("svg", _docElement);
3637					rect = _createSVG("rect", svg, {width:100, height:50, x:100});
3638					width = rect.getBoundingClientRect().width;
3639					rect.style[_transformOriginProp] = "50% 50%";
3640					rect.style[_transformProp] = "scaleX(0.5)";
3641					force = (width === rect.getBoundingClientRect().width && !(_is
3641Firefox && _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).
3642					_docElement.removeChild(svg);
3643				}
3644				return force;
3645			})(),
3646			_parseSVGOrigin = function(e, local, decoratee, absolute, smoothOrigin) {
3647				var tm = e._gsTransform,
3648					m = _getMatrix(e, true),
3649					v, x, y, xOrigin, yOrigin, a, b, c, d, tx, ty, determinant, xOriginOld, yOriginOld;
3650				if (tm) {
3651					xOriginOld = tm.xOrigin; //record the original values before we alter them.
3652					yOriginOld = tm.yOrigin;
3653				}
3654				if (!absolute || (v = absolute.split(" ")).length < 2) {
3655					b = e.getBBox();
3656					local = _parsePosition(local).split(" ");
3657					v = [(local[0].indexOf("%") !== -1 ? parseFloat(local[0]) / 100 * b.width : parseFloat(local[0])) + b.x,
3658						 (local[1].indexOf("%") !== -1 ? parseFloat(local[1]) / 100 * b.height : parseFloat(local[1])) + b.y];
3659				}
3660				decoratee.xOrigin = xOrigin = parseFloat(v[0]);
3661				decoratee.yOrigin = yOrigin = parseFloat(v[1]);
3662				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.
3663					a = m[0];
3664					b = m[1];
3665					c = m[2];
3666					d = m[3];
3667					tx = m[4];
3668					ty = m[5];
3669					determinant = (a * d - b * c);
3670					x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + ((c * ty - d * tx) / determinant);
3671					y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - ((a * ty - b * tx) / determinant);
3672					xOrigin = decoratee.xOrigin = v[0] = x;
3673					yOrigin = decoratee.yOrigin = v[1] = y;
3674				}
3675				if (tm) { //avoid jump when transformOrigin is changed - adjust the x/y values accordingly
3676					if (smoothOrigin || (smoothOrigin !== false && CSSPlugin.defaultSmoothOrigin !== false)) {
3677						x = xOrigin - xOriginOld;
3678						y = yOrigin - yOriginOld;
3679						//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.
3680						//tm.x -= x - (x * m[0] + y * m[2]);
3681						//tm.y -= y - (x * m[1] + y * m[3]);
3682						tm.xOffset += (x * m[0] + y * m[2]) - x;
3683						tm.yOffset += (x * m[1] + y * m[3]) - y;
3684					} else {
3685						tm.xOffset = tm.yOffset = 0;
3686					}
3687				}
3688				e.setAttribute("data-svg-origin", v.join(" "));
3689			},
3690			_isSVG = function(e) {
3691				return !!(_SVGElement && typeof(e.getBBox) === "function" && e.getCTM && (!e.parentNode || (e.parentNode.getBBox && e.parentNode.getCTM)));
3692			},
3693			_identity2DMatrix = [1,0,0,1,0,0],
3694			_getMatrix = function(e, force2D) {
3695				var tm = e._gsTransform || new Transform(),
3696					rnd = 100000,
3697					isDefault, s, m, n, dec;
3698				if (_transformProp) {
3699					s = _getStyle(e, _transformPropCSS, null, true);
3700				} else if (e.currentStyle) {
3701					//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.
3702					s = e.currentStyle.filter.match(_ieGetMatrixExp);
3703					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(",") : "";
3704				}
3705				isDefault = (!s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)");
3706				if (tm.svg || (e.getBBox && _isSVG(e))) {
3707					if (isDefault && (e.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
3708						s = e.style[_transformProp];
3709						isDefault = 0;
3710					}
3711					m = e.getAttribute("transform");
3712					if (isDefault && m) {
3713						if (m.indexOf("matrix") !== -1) { //just in case there's a "transform" value specified as an attribute instead of CSS style. Accept either a matrix() or simple translate() value though.
3714							s = m;
3715							isDefault = 0;
3716						} else if (m.indexOf("translate") !== -1) {
3717							s = "matrix(1,0,0,1," + m.match(/(?:\-|\b)[\d\-\.e]+\b/gi).join(",") + ")";
3718							isDefault = 0;
3719						}
3720					}
3721				}
3722				if (isDefault) {
3723					return _identity2DMatrix;
3724				}
3725				//split the matrix values out into an array (m for matrix)
3726				m = (s || "").match(/(?:\-|\b)[\d\-\.e]+\b/gi) || [];
3727				i = m.length;
3728				while (--i > -1) {
3729					n = Number(m[i]);
3730					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).
3731				}
3732				return (force2D && m.length > 6) ? [m[0], m[1], m[4], m[5], m[12], m[13]] : m;
3733			},
3734
3735			/**
3736			 * 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.
3737			 * @param {!Object} t target element
3738			 * @param {Object=} cs computed style object (optional)
3739			 * @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...}
3740			 * @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)
3741			 * @return {object}
3741 object containing all of the transform properties/values like {x:0, y:0, z:0, scaleX:1...}
3742			 */
3743			_getTransform = _internals.getTransform = function(t, cs, rec, parse) {
3744				if (t._gsTransform && rec && !parse) {
3745					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.
3746				}
3747				var tm = rec ? t._gsTransform || new Transform() : new Transform(),
3748					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.
3749					min = 0.00002,
3750					rnd = 100000,
3751					zOrigin = _supports3D ? parseFloat(_getStyle(t, _transformOriginProp, cs, false, "0 0 0").split(" ")[2]) || tm.zOrigin  || 0 : 0,
3752					defaultTransformPerspective = parseFloat(CSSPlugin.defaultTransformPerspective) || 0,
3753					m, i, scaleX, scaleY, rotation, skewX;
3754
3755				tm.svg = !!(t.getBBox && _isSVG(t));
3756				if (tm.svg) {
3757					_parseSVGOrigin(t, _getStyle(t, _transformOriginProp, _cs, false, "50% 50%") + "", tm, t.getAttribute("data-svg-origin"));
3758					_useSVGTransformAttr = CSSPlugin.useSVGTransformAttr || _forceSVGTransformAttr;
3759				}
3760				m = _getMatrix(t);
3761				if (m !== _identity2DMatrix) {
3762
3763					if (m.length === 16) {
3764						//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)
3765						var a11 = m[0], a21 = m[1], a31 = m[2], a41 = m[3],
3766							a12 = m[4], a22 = m[5], a32 = m[6], a42 = m[7],
3767							a13 = m[8], a23 = m[9], a33 = m[10],
3768							a14 = m[12], a24 = m[13], a34 = m[14],
3769							a43 = m[11],
3770							angle = Math.atan2(a32, a33),
3771							t1, t2, t3, t4, cos, sin;
3772
3773						//we manually compensate for non-zero z component of transformOrigin to work around bugs in Safari
3774						if (tm.zOrigin) {
3775							a34 = -tm.zOrigin;
3776							a14 = a13*a34-m[12];
3777							a24 = a23*a34-m[13];
3778							a34 = a33*a34+tm.zOrigin-m[14];
3779						}
3780						tm.rotationX = angle * _RAD2DEG;
3781						//rotationX
3782						if (angle) {
3783							cos = Math.cos(-angle);
3784							sin = Math.sin(-angle);
3785							t1 = a12*cos+a13*sin;
3786							t2 = a22*cos+a23*sin;
3787							t3 = a32*cos+a33*sin;
3788							a13 = a12*-sin+a13*cos;
3789							a23 = a22*-sin+a23*cos;
3790							a33 = a32*-sin+a33*cos;
3791							a43 = a42*-sin+a43*cos;
3792							a12 = t1;
3793							a22 = t2;
3794							a32 = t3;
3795						}
3796						//rotationY
3797						angle = Math.atan2(a13, a33);
3798						tm.rotationY = angle * _RAD2DEG;
3799						if (angle) {
3800							cos = Math.cos(-angle);
3801							sin = Math.sin(-angle);
3802							t1 = a11*cos-a13*sin;
3803							t2 = a21*cos-a23*sin;
3804							t3 = a31*cos-a33*sin;
3805							a23 = a21*sin+a23*cos;
3806							a33 = a31*sin+a33*cos;
3807							a43 = a41*sin+a43*cos;
3808							a11 = t1;
3809							a21 = t2;
3810							a31 = t3;
3811						}
3812						//rotationZ
3813						angle = Math.atan2(a21, a11);
3814						tm.rotation = angle * _RAD2DEG;
3815						if (angle) {
3816							cos = Math.cos(-angle);
3817							sin = Math.sin(-angle);
3818							a11 = a11*cos+a12*sin;
3819							t2 = a21*cos+a22*sin;
3820							a22 = a21*-sin+a22*cos;
3821							a32 = a31*-sin+a32*cos;
3822							a21 = t2;
3823						}
3824
3825						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.
3826							tm.rotationX = tm.rotation = 0;
3827							tm.rotationY += 180;
3828						}
3829
3830						tm.scaleX = ((Math.sqrt(a11 * a11 + a21 * a21) * rnd + 0.5) | 0) / rnd;
3831						tm.scaleY = ((Math.sqrt(a22 * a22 + a23 * a23) * rnd + 0.5) | 0) / rnd;
3832						tm.scaleZ = ((Math.sqrt(a32 * a32 + a33 * a33) * rnd + 0.5) | 0) / rnd;
3833						tm.skewX = 0;
3834						tm.perspective = a43 ? 1 / ((a43 < 0) ? -a43 : a43) : 0;
3835						tm.x = a14;
3836						tm.y = a24;
3837						tm.z = a34;
3838						if (tm.svg) {
3839							tm.x -= tm.xOrigin - (tm.xOrigin * a11 - tm.yOrigin * a12);
3840							tm.y -= tm.yOrigin - (tm.yOrigin * a21 - tm.xOrigin * a22);
3841						}
3842
3843					} else if ((!_supports3D || parse || !m.length || tm.x !== m[4] || tm.y !== m[5] || (!tm.rotationX && !tm.rotationY)) && !(tm.x !== undefined && _getStyle(t, "display", cs) === "
3843none")) { //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.
3844						var k = (m.length >= 6),
3845							a = k ? m[0] : 1,
3846							b = m[1] || 0,
3847							c = m[2] || 0,
3848							d = k ? m[3] : 1;
3849						tm.x = m[4] || 0;
3850						tm.y = m[5] || 0;
3851						scaleX = Math.sqrt(a * a + b * b);
3852						scaleY = Math.sqrt(d * d + c * c);
3853						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).
3854						skewX = (c || d) ? Math.atan2(c, d) * _RAD2DEG + rotation : tm.skewX || 0;
3855						if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) {
3856							if (invX) {
3857								scaleX *= -1;
3858								skewX += (rotation <= 0) ? 180 : -180;
3859								rotation += (rotation <= 0) ? 180 : -180;
3860							} else {
3861								scaleY *= -1;
3862								skewX += (skewX <= 0) ? 180 : -180;
3863							}
3864						}
3865						tm.scaleX = scaleX;
3866						tm.scaleY = scaleY;
3867						tm.rotation = rotation;
3868						tm.skewX = skewX;
3869						if (_supports3D) {
3870							tm.rotationX = tm.rotationY = tm.z = 0;
3871							tm.perspective = defaultTransformPerspective;
3872							tm.scaleZ = 1;
3873						}
3874						if (tm.svg) {
3875							tm.x -= tm.xOrigin - (tm.xOrigin * a + tm.yOrigin * c);
3876							tm.y -= tm.yOrigin - (tm.xOrigin * b + tm.yOrigin * d);
3877						}
3878					}
3879					tm.zOrigin = zOrigin;
3880					//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.
3881					for (i in tm) {
3882						if (tm[i] < min) if (tm[i] > -min) {
3883							tm[i] = 0;
3884						}
3885					}
3886				}
3887				//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);
3888				if (rec) {
3889					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)
3890					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.
3891						if (_useSVGTransformAttr && t.style[_transformProp]) {
3892							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).
3893								_removeProp(t.style, _transformProp);
3894							});
3895						} else if (!_useSVGTransformAttr && t.getAttribute("transform")) {
3896							TweenLite.delayedCall(0.001, function(){
3897								t.removeAttribute("transform");
3898							});
3899						}
3900					}
3901				}
3902				return tm;
3903			},
3904
3905			//for setting 2D transforms in IE6, IE7, and IE8 (must use a "filter" to emulate the behavior of modern day browser transforms)
3906			_setIETransformRatio = function(v) {
3907				var t = this.data, //refers to the element's _gsTransform object
3908					ang = -t.rotation * _DEG2RAD,
3909					skew = ang + t.skewX * _DEG2RAD,
3910					rnd = 100000,
3911					a = ((Math.cos(ang) * t.scaleX * rnd) | 0) / rnd,
3912					b = ((Math.sin(ang) * t.scaleX * rnd) | 0) / rnd,
3913					c = ((Math.sin(skew) * -t.scaleY * rnd) | 0) / rnd,
3914					d = ((Math.cos(skew) * t.scaleY * rnd) | 0) / rnd,
3915					style = this.t.style,
3916					cs = this.t.currentStyle,
3917					filters, val;
3918				if (!cs) {
3919					return;
3920				}
3921				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)
3922				b = -c;
3923				c = -val;
3924				filters = cs.filter;
3925				style.filter = ""; //remove filters so that we can accurately measure offsetWidth/offsetHeight
3926				var w = this.t.offsetWidth,
3927					h = this.t.offsetHeight,
3928					clip = (cs.position !== "absolute"),
3929					m = "progid:DXImageTransform.Microsoft.Matrix(M11=" + a + ", M12=" + b + ", M21=" + c + ", M22=" + d,
3930					ox = t.x + (w * t.xPercent / 100),
3931					oy = t.y + (h * t.yPercent / 100),
3932					dx, dy;
3933
3934				//if transformOrigin is being used, adjust the offset x and y
3935				if (t.ox != null) {
3936					dx = ((t.oxp) ? w * t.ox * 0.01 : t.ox) - w / 2;
3937					dy = ((t.oyp) ? h * t.oy * 0.01 : t.oy) - h / 2;
3938					ox += dx - (dx * a + dy * b);
3939					oy += dy - (dx * c + dy * d);
3940				}
3941
3942				if (!clip) {
3943					m += ", sizingMethod='auto expand')";
3944				} else {
3945					dx = (w / 2);
3946					dy = (h / 2);
3947					//translate to ensure that transformations occur around the correct origin (default is center).
3948					m += ", Dx=" + (dx - (dx * a + dy * b) + ox) + ", Dy=" + (dy - (dx * c + dy * d) + oy) + ")";
3949				}
3950				if (filters.indexOf("DXImageTransform.Microsoft.Matrix(") !== -1) {
3951					style.filter = filters.replace(_ieSetMatrixExp, m);
3952				} else {
3953					style.filter = m + " " + filters; //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.
3954				}
3955
3956				//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.
3957				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) {
3958					style.removeAttribute("filter");
3959				}
3960
3961				//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).
3962				if (!clip) {
3963					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
3964						marg, prop, dif;
3965					dx = t.ieOffsetX || 0;
3966					dy = t.ieOffsetY || 0;
3967					t.ieOffsetX = Math.round((w - ((a < 0 ? -a : a) * w + (b < 0 ? -b : b) * h)) / 2 + ox);
3968					t.ieOffsetY = Math.round((h - ((d < 0 ? -d : d) * h + (c < 0 ? -c : c) * w)) / 2 + oy);
3969					for (i = 0; i < 4; i++) {
3970						prop = _margins[i];
3971						marg = cs[prop];
3972						//we need to get the current margin in case it is being tweened separately (we want to respect that tween's changes)
3973						val = (marg.indexOf("px") !== -1) ? parseFloat(marg) : _convertToPixels(this.t, prop, parseFloat(marg), marg.replace(_suffixExp, "")) || 0;
3974						if (val !== t[prop]) {
3975							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.
3976						} else {
3977							dif = (i < 2) ? dx - t.ieOffsetX : dy - t.ieOffsetY;
3978						}
3979						style[prop] = (t[prop] = Math.round( val - dif * ((i === 0 || i === 2) ? 1 : mult) )) + "px";
3980					}
3981				}
3982			},
3983
3984			/* translates a super small decimal to a string WITHOUT scientific notation
3985			_safeDecimal = function(n) {
3986				var s = (n < 0 ? -n : n) + "",
3987					a = s.split("e-");
3988				return (n < 0 ? "-0." : "0.") + new Array(parseInt(a[1], 10) || 0).join("0") + a[0].split(".").join("");
3989			},
3990			*/
3991
3992			_setTransformRatio = _internals.set3DTransformRatio = _internals.setTransformRatio = function(v) {
3993				var t = this.data, //refers to the element's _gsTransform object
3994					style = this.t.style,
3995					angle = t.rotation,
3996					rotationX = t.rotationX,
3997					rotationY = t.rotationY,
3998					sx = t.scaleX,
3999					sy = t.scaleY,
4000					sz = t.scaleZ,
4001					x = t.x,
4002					y = t.y,
4003					z = t.z,
4004					isSVG = t.svg,
4005					perspective = t.perspective,
4006					force3D = t.force3D,
4007					a11, a12, a13, a21, a22, a23, a31, a32, a33, a41, a42, a43,
4008					zOrigin, min, cos, sin, t1, t2, transform, comma, zero, skew, rnd;
4009				//check to see if we should render as 2D (and SVGs must use 2D when _useSVGTransformAttr is true)
4010				if (((((v === 1 || v === 0) && force3D === "auto" && (this.tween._totalTime === this.tween._totalDuration || !this.tween._totalTime)) || !force3D) && !z && !perspective && !rotationY && !rotationX) || (_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.
4011
4012					//2D
4013					if (angle || t.skewX || isSVG) {
4014						angle *= _DEG2RAD;
4015						skew = t.skewX * _DEG2RAD;
4016						rnd = 100000;
4017						a11 = Math.cos(angle) * sx;
4018						a21 = Math.sin(angle) * sx;
4019						a12 = Math.sin(angle - skew) * -sy;
4020						a22 = Math.cos(angle - skew) * sy;
4021						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
4022							t1 = Math.tan(skew);
4023							t1 = Math.sqrt(1 + t1 * t1);
4024							a12 *= t1;
4025							a22 *= t1;
4026							if (t.skewY) {
4027								a11 *= t1;
4028								a21 *= t1;
4029							}
4030						}
4031						if (isSVG) {
4032							x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset;
4033							y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset;
4034							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.
4035								min = this.t.getBBox();
4036								x += t.xPercent * 0.01 * min.width;
4037								y += t.yPercent * 0.01 * min.height;
4038							}
4039							min = 0.000001;
4040							if (x < min) if (x > -min) {
4041								x = 0;
4042							}
4043							if (y < min) if (y > -min) {
4044								y = 0;
4045							}
4046						}
4047						transform = (((a11 * rnd) | 0) / rnd) + "," + (((a21 * rnd) | 0) / rnd) + "," + (((a12 * rnd) | 0) / rnd) + "," + (((a22 * rnd) | 0) / rnd) + "," + x + "," + y + ")";
4048						if (isSVG && _useSVGTransformAttr) {
4049							this.t.setAttribute("transform", "matrix(" + transform);
4050						} else {
4051							//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.
4052							style[_transformProp] = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + transform;
4053						}
4054					} else {
4055						style[_transformProp] = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + sx + ",0,0," + sy + "," + x + "," + y + ")";
4056					}
4057					return;
4058
4059				}
4060				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.
4061					min = 0.0001;
4062					if (sx < min && sx > -min) {
4063						sx = sz = 0.00002;
4064					}
4065					if (sy < min && sy > -min) {
4066						sy = sz = 0.00002;
4067					}
4068					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).
4069						perspective = 0;
4070					}
4071				}
4072				if (angle || t.skewX) {
4073					angle *= _DEG2RAD;
4074					cos = a11 = Math.cos(angle);
4075					sin = a21 = Math.sin(angle);
4076					if (t.skewX) {
4077						angle -= t.skewX * _DEG2RAD;
4078						cos = Math.cos(angle);
4079						sin = Math.sin(angle);
4080						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
4081							t1 = Math.tan(t.skewX * _DEG2RAD);
4082							t1 = Math.sqrt(1 + t1 * t1);
4083							cos *= t1;
4084							sin *= t1;
4085							if (t.skewY) {
4086								a11 *= t1;
4087								a21 *= t1;
4088							}
4089						}
4090					}
4091					a12 = -sin;
4092					a22 = cos;
4093
4094				} else if (!rotationY && !rotationX && sz === 1 && !perspective && !isSVG) { //if we're only translating and/or 2D scaling, this is faster...
4095					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 + ")" : "");
4096					return;
4097				} else {
4098					a11 = a22 = 1;
4099					a12 = a21 = 0;
4100				}
4101				// KEY  INDEX   AFFECTS
4102				// a11  0       rotation, rotationY, scaleX
4103				// a21  1       rotation, rotationY, scaleX
4104				// a31  2       rotationY, scaleX
4105				// a41  3       rotationY, scaleX
4106				// a12  4       rotation, skewX, rotationX, scaleY
4107				// a22  5       rotation, skewX, rotationX, scaleY
4108				// a32  6       rotationX, scaleY
4109				// a42  7       rotationX, scaleY
4110				// a13  8       rotationY, rotationX, scaleZ
4111				// a23  9       rotationY, rotationX, scaleZ
4112				// a33  10      rotationY, rotationX, scaleZ
4113				// a43  11      rotationY, rotationX, perspective, scaleZ
4114				// a14  12      x, zOrigin, svgOrigin
4115				// a24  13      y, zOrigin, svgOrigin
4116				// a34  14      z, zOrigin
4117				// a44  15
4118				// rotation: Math.atan2(a21, a11)
4119				// rotationY: Math.atan2(a13, a33) (or Math.atan2(a13, a11))
4120				// rotationX: Math.atan2(a32, a33)
4121				a33 = 1;
4122				a13 = a23 = a31 = a32 = a41 = a42 = 0;
4123				a43 = (perspective) ? -1 / perspective : 0;
4124				zOrigin = t.zOrigin;
4125				min = 0.000001; //threshold below which browsers use scientific notation which won't work.
4126				comma = ",";
4127				zero = "0";
4128				angle = rotationY * _DEG2RAD;
4129				if (angle) {
4130					cos = Math.cos(angle);
4131					sin = Math.sin(angle);
4132					a31 = -sin;
4133					a41 = a43*-sin;
4134					a13 = a11*sin;
4135					a23 = a21*sin;
4136					a33 = cos;
4137					a43 *= cos;
4138					a11 *= cos;
4139					a21 *= cos;
4140				}
4141				angle = rotationX * _DEG2RAD;
4142				if (angle) {
4143					cos = Math.cos(angle);
4144					sin = Math.sin(angle);
4145					t1 = a12*cos+a13*sin;
4146					t2 = a22*cos+a23*sin;
4147					a32 = a33*sin;
4148					a42 = a43*sin;
4149					a13 = a12*-sin+a13*cos;
4150					a23 = a22*-sin+a23*cos;
4151					a33 = a33*cos;
4152					a43 = a43*cos;
4153					a12 = t1;
4154					a22 = t2;
4155				}
4156				if (sz !== 1) {
4157					a13*=sz;
4158					a23*=sz;
4159					a33*=sz;
4160					a43*=sz;
4161				}
4162				if (sy !== 1) {
4163					a12*=sy;
4164					a22*=sy;
4165					a32*=sy;
4166					a42*=sy;
4167				}
4168				if (sx !== 1) {
4169					a11*=sx;
4170					a21*=sx;
4171					a31*=sx;
4172					a41*=sx;
4173				}
4174
4175				if (zOrigin || isSVG) {
4176					if (zOrigin) {
4177						x += a13*-zOrigin;
4178						y += a23*-zOrigin;
4179						z += a33*-zOrigin+zOrigin;
4180					}
4181					if (isSVG) { //due to bugs in some browsers, we need to manage the transform-origin of SVG manually
4182						x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset;
4183						y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset;
4184					}
4185					if (x < min && x > -min) {
4186						x = zero;
4187					}
4188					if (y < min && y > -min) {
4189						y = zero;
4190					}
4191					if (z < min && z > -min) {
4192						z = 0; //don't use string because we calculate perspective later and need the number.
4193					}
4194				}
4195
4196				//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:
4197				transform = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix3d(" : "matrix3d(");
4198				transform += ((a11 < min && a11 > -min) ? zero : a11) + comma + ((a21 < min && a21 > -min) ? zero : a21) + comma + ((a31 < min && a31 > -min) ? zero : a31);
4199				transform += comma + ((a41 < min && a41 > -min) ? zero : a41) + comma + ((a12 < min && a12 > -min) ? zero : a12) + comma + ((a22 < min && a22 > -min) ? zero : a22);
4200				if (rotationX || rotationY) { //performance optimization (often there's no rotationX or rotationY, so we can skip these calculations)
4201					transform += comma + ((a32 < min && a32 > -min) ? zero : a32) + comma + ((a42 < min && a42 > -min) ? zero : a42) + comma + ((a13 < min && a13 > -min) ? zero : a13);
4202					transform += comma + ((a23 < min && a23 > -min) ? zero : a23) + comma + ((a33 < min && a33 > -min) ? zero : a33) + comma + ((a43 < min && a43 > -min) ? zero : a43) + comma;
4203				} else {
4204					transform += ",0,0,0,0,1,0,";
4205				}
4206				transform += x + comma + y + comma + z + comma + (perspective ? (1 + (-z / perspective)) : 1) + ")";
4207
4208				style[_transformProp] = transform;
4209			};
4210
4211		p = Transform.prototype;
4212		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;
4213		p.scaleX = p.scaleY = p.scaleZ = 1;
4214
4215		_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, p, cssp, pt, plugin, vars) {
4216			if (cssp._lastParsedTransform === vars) { return pt; } //only need to parse the transform once, and only if the browser supports it.
4217			cssp._lastParsedTransform = vars;
4218			var originalGSTransform = t._gsTransform,
4219				style = t.style,
4220				min = 0.000001,
4221				i = _transformProps.length,
4222				v = vars,
4223				endRotations = {},
4224				transformOriginString = "transformOrigin",
4225				m1, m2, skewY, copy, orig, has3D, hasChange, dr, x, y;
4226			if (vars.display) { //if the user is setting display during this tween, it may not be instantiated yet but we must force it here in order to get accurate readings. If display is "none", some browsers refuse to report the transform properties correctly.
4227				copy = _getStyle(t, "display");
4228				style.display = "block";
4229				m1 = _getTransform(t, _cs, true, vars.parseTransform);
4230				style.display = copy;
4231			} else {
4232				m1 = _getTransform(t, _cs, true, vars.parseTransform);
4233			}
4234			cssp._transform = m1;
4235			if (typeof(v.transform) === "string" && _transformProp) { //for values like transform:"rotate(60deg) scale(0.5, 0.8)"
4236				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.
4237				copy[_transformProp] = v.transform;
4238				copy.display = "block"; //if display is "none", the browser often refuses to report the transform properties correctly.
4239				copy.position = "absolute";
4240				_doc.body.appendChild(_tempDiv);
4241				m2 = _getTransform(_tempDiv, null, false);
4242				_doc.body.removeChild(_tempDiv);
4243				if (!m2.perspective) {
4244					m2.perspective = m1.perspective; //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case.
4245				}
4246				if (v.xPercent != null) {
4247					m2.xPercent = _parseVal(v.xPercent, m1.xPercent);
4248				}
4249				if (v.yPercent != null) {
4250					m2.yPercent = _parseVal(v.yPercent, m1.yPercent);
4251				}
4252			} else if (typeof(v) === "object") { //for values like scaleX, scaleY, rotation, x, y, skewX, and skewY or transform:{...} (object)
4253				m2 = {scaleX:_parseVal((v.scaleX != null) ? v.scaleX : v.scale, m1.scaleX),
4254					scaleY:_parseVal((v.scaleY != null) ? v.scaleY : v.scale, m1.scaleY),
4255					scaleZ:_parseVal(v.scaleZ, m1.scaleZ),
4256					x:_parseVal(v.x, m1.x),
4257					y:_parseVal(v.y, m1.y),
4258					z:_parseVal(v.z, m1.z),
4259					xPercent:_parseVal(v.xPercent, m1.xPercent),
4260					yPercent:_parseVal(v.yPercent, m1.yPercent),
4261					perspective:_parseVal(v.transformPerspective, m1.perspective)};
4262				dr = v.directionalRotation;
4263				if (dr != null) {
4264					if (typeof(dr) === "object") {
4265						for (copy in dr) {
4266							v[copy] = dr[copy];
4267						}
4268					} else {
4269						v.rotation = dr;
4270					}
4271				}
4272				if (typeof(v.x) === "string" && v.x.indexOf("%") !== -1) {
4273					m2.x = 0;
4274					m2.xPercent = _parseVal(v.x, m1.xPercent);
4275				}
4276				if (typeof(v.y) === "string" && v.y.indexOf("%") !== -1) {
4277					m2.y = 0;
4278					m2.yPercent = _parseVal(v.y, m1.yPercent);
4279				}
4280
4281				m2.rotation = _parseAngle(("rotation" in v) ? v.rotation : ("shortRotation" in v) ? v.shortRotation + "_short" : ("rotationZ" in v) ? v.rotationZ : m1.rotation, m1.rotation, "rotation", endRotations);
4282				if (_supports3D) {
4283					m2.rotationX = _parseAngle(("rotationX" in v) ? v.rotationX : ("shortRotationX" in v) ? v.shortRotationX + "_short" : m1.rotationX || 0, m1.rotationX, "rotationX", endRotations);
4284					m2.rotationY = _parseAngle(("rotationY" in v) ? v.rotationY : ("shortRotationY" in v) ? v.shortRotationY + "_short" : m1.rotationY || 0, m1.rotationY, "rotationY", endRotations);
4285				}
4286				m2.skewX = (v.skewX == null) ? m1.skewX : _parseAngle(v.skewX, m1.skewX);
4287
4288				//note: for performance reasons, we combine all skewing into the skewX and rotation values, ignoring skewY but we must still record it so that we can discern how much of the overall skew is attributed to skewX vs. skewY. Otherwise, if the skewY would always act relative (tween skewY to 10deg, for example, multiple times and if we always combine things into skewX, we can't remember that skewY was 10 from last time). Remember, a skewY of 10 degrees looks the same as a rotation of 10 degrees plus a skewX of -10 degrees.
4289				m2.skewY = (v.skewY == null) ? m1.skewY : _parseAngle(v.skewY, m1.skewY);
4290				if ((skewY = m2.skewY - m1.skewY)) {
4291					m2.skewX += skewY;
4292					m2.rotation += skewY;
4293				}
4294			}
4295			if (_supports3D && v.force3D != null) {
4296				m1.force3D = v.force3D;
4297				hasChange = true;
4298			}
4299
4300			m1.skewType = v.skewType || m1.skewType || CSSPlugin.defaultSkewType;
4301
4302			has3D = (m1.force3D || m1.z || m1.rotationX || m1.rotationY || m2.z || m2.rotationX || m2.rotationY || m2.perspective);
4303			if (!has3D && v.scale != null) {
4304				m2.scaleZ = 1; //no need to tween scaleZ.
4305			}
4306
4307			while (--i > -1) {
4308				p = _transformProps[i];
4309				orig = m2[p] - m1[p];
4310				if (orig > min || orig < -min || v[p] != null || _forcePT[p] != null) {
4311					hasChange = true;
4312					pt = new CSSPropTween(m1, p, m1[p], orig, pt);
4313					if (p in endRotations) {
4314						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
4315					}
4316					pt.xs0 = 0; //ensures the value stays numeric in setRatio()
4317					pt.plugin = plugin;
4318					cssp._overwriteProps.push(pt.n);
4319				}
4320			}
4321
4322			orig = v.transformOrigin;
4323			if (m1.svg && (orig || v.svgOrigin)) {
4324				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
4325				y = m1.yOffset;
4326				_parseSVGOrigin(t, _parsePosition(orig), m2, v.svgOrigin, v.smoothOrigin);
4327				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.
4328				pt = _addNonTweeningNumericPT(m1, "yOrigin", (originalGSTransform ? m1 : m2).yOrigin, m2.yOrigin, pt, transformOriginString);
4329				if (x !== m1.xOffset || y !== m1.yOffset) {
4330					pt = _addNonTweeningNumericPT(m1, "xOffset", (originalGSTransform ? x : m1.xOffset), m1.xOffset, pt, transformOriginString);
4331					pt = _addNonTweeningNumericPT(m1, "yOffset", (originalGSTransform ? y : m1.yOffset), m1.yOffset, pt, transformOriginString);
4332				}
4333				orig = _useSVGTransformAttr ? null : "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
4334			}
4335			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).
4336				if (_transformProp) {
4337					hasChange = true;
4338					p = _transformOriginProp;
4339					orig = (orig || _getStyle(t, p, _cs, false, "50% 50%")) + ""; //cast as string to avoid errors
4340					pt = new CSSPropTween(style, p, 0, 0, pt, -1, transformOriginString);
4341					pt.b = style[p];
4342					pt.plugin = plugin;
4343					if (_supports3D) {
4344						copy = m1.zOrigin;
4345						orig = orig.split(" ");
4346						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.
4347						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)!
4348						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)
4349						pt.b = copy;
4350						pt.xs0 = pt.e = m1.zOrigin;
4351					} else {
4352						pt.xs0 = pt.e = orig;
4353					}
4354
4355					//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).
4356				} else {
4357					_parsePosition(orig + "", m1);
4358				}
4359			}
4360			if (hasChange) {
4361				cssp._transformType = (!(m1.svg && _useSVGTransformAttr) && (has3D || this._transformType === 3)) ? 3 : 2; //quicker than calling cssp._enableTransforms();
4362			}
4363			return pt;
4364		}, prefix:true});
4365
4366		_registerComplexSpecialProp("boxShadow", {defaultValue:"0px 0px 0px 0px #999", prefix:true, color:true, multi:true, keyword:"inset"});
4367
4368		_registerComplexSpecialProp("borderRadius", {defaultValue:"0px", parser:function(t, e, p, cssp, pt, plugin) {
4369			e = this.format(e);
4370			var props = ["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"],
4371				style = t.style,
4372				ea1, i, es2, bs2, bs, es, bn, en, w, h, esfx, bsfx, rel, hn, vn, em;
4373			w = parseFloat(t.offsetWidth);
4374			h = parseFloat(t.offsetHeight);
4375			ea1 = e.split(" ");
4376			for (i = 0; i < props.length; i++) { //if we're dealing with percentages, we must convert things separately for the horizontal and vertical axis!
4377				if (this.p.indexOf("border")) { //older browsers used a prefix
4378					props[i] = _checkPropPrefix(props[i]);
4379				}
4380				bs = bs2 = _getStyle(t, props[i], _cs, false, "0px");
4381				if (bs.indexOf(" ") !== -1) {
4382					bs2 = bs.split(" ");
4383					bs = bs2[0];
4384					bs2 = bs2[1];
4385				}
4386				es = es2 = ea1[i];
4387				bn = parseFloat(bs);
4388				bsfx = bs.substr((bn + "").length);
4389				rel = (es.charAt(1) === "=");
4390				if (rel) {
4391					en = parseInt(es.charAt(0)+"1", 10);
4392					es = es.substr(2);
4393					en *= parseFloat(es);
4394					esfx = es.substr((en + "").length - (en < 0 ? 1 : 0)) || "";
4395				} else {
4396					en = parseFloat(es);
4397					esfx = es.substr((en + "").length);
4398				}
4399				if (esfx === "") {
4400					esfx = _suffixMap[p] || bsfx;
4401				}
4402				if (esfx !== bsfx) {
4403					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.
4404					vn = _convertToPixels(t, "borderTop", bn, bsfx); //vertical number
4405					if (esfx === "%") {
4406						bs = (hn / w * 100) + "%";
4407						bs2 = (vn / h * 100) + "%";
4408					} else if (esfx === "em") {
4409						em = _convertToPixels(t, "borderLeft", 1, "em");
4410						bs = (hn / em) + "em";
4411						bs2 = (vn / em) + "em";
4412					} else {
4413						bs = hn + "px";
4414						bs2 = vn + "px";
4415					}
4416					if (rel) {
4417						es = (parseFloat(bs) + en) + esfx;
4418						es2 = (parseFloat(bs2) + en) + esfx;
4419					}
4420				}
4421				pt = _parseComplex(style, props[i], bs + " " + bs2, es + " " + es2, false, "0px", pt);
4422			}
4423			return pt;
4424		}, prefix:true, formatter:_getFormatter("0px 0px 0px 0px", false, true)});
4425		_registerComplexSpecialProp("backgroundPosition", {defaultValue:"0 0", parser:function(t, e, p, cssp, pt, plugin) {
4426			var bp = "background-position",
4427				cs = (_cs || _getComputedStyle(t, null)),
4428				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
4429				es = this.format(e),
4430				ba, ea, i, pct, overlap, src;
4431			if ((bs.indexOf("%") !== -1) !== (es.indexOf("%") !== -1)) {
4432				src = _getStyle(t, "backgroundImage").replace(_urlExp, "");
4433				if (src && src !== "none") {
4434					ba = bs.split(" ");
4435					ea = es.split(" ");
4436					_tempImg.setAttribute("src", src); //set the temp IMG's src to the background-image so that we can measure its width/height
4437					i = 2;
4438					while (--i > -1) {
4439						bs = ba[i];
4440						pct = (bs.indexOf("%") !== -1);
4441						if (pct !== (ea[i].indexOf("%") !== -1)) {
4442							overlap = (i === 0) ? t.offsetWidth - _tempImg.width : t.offsetHeight - _tempImg.height;
4443							ba[i] = pct ? (parseFloat(bs) / 100 * overlap) + "px" : (parseFloat(bs) / overlap * 100) + "%";
4444						}
4445					}
4446					bs = ba.join(" ");
4447				}
4448			}
4449			return this.parseComplex(t.style, bs, es, pt, plugin);
4450		}, formatter:_parsePosition});
4451		_registerComplexSpecialProp("backgroundSize", {defaultValue:"0 0", formatter:_parsePosition});
4452		_registerComplexSpecialProp("perspective", {defaultValue:"0px", prefix:true});
4453		_registerComplexSpecialProp("perspectiveOrigin", {defaultValue:"50% 50%", prefix:true});
4454		_registerComplexSpecialProp("transformStyle", {prefix:true});
4455		_registerComplexSpecialProp("backfaceVisibility", {prefix:true});
4456		_registerComplexSpecialProp("userSelect", {prefix:true});
4457		_registerComplexSpecialProp("margin", {parser:_getEdgeParser("marginTop,marginRight,marginBottom,marginLeft")});
4458		_registerComplexSpecialProp("padding", {parser:_getEdgeParser("paddingTop,paddingRight,paddingBottom,paddingLeft")});
4459		_registerComplexSpecialProp("clip", {defaultValue:"rect(0px,0px,0px,0px)", parser:function(t, e, p, cssp, pt, plugin){
4460			var b, cs, delim;
4461			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.
4462				cs = t.currentStyle;
4463				delim = _ieVers < 8 ? " " : ",";
4464				b = "rect(" + cs.clipTop + delim + cs.clipRight + delim + cs.clipBottom + delim + cs.clipLeft + ")";
4465				e = this.format(e).split(",").join(delim);
4466			} else {
4467				b = this.format(_getStyle(t, this.p, _cs, false, this.dflt));
4468				e = this.format(e);
4469			}
4470			return this.parseComplex(t.style, b, e, pt, plugin);
4471		}});
4472		_registerComplexSpecialProp("textShadow", {defaultValue:"0px 0px 0px #999", color:true, multi:true});
4473		_registerComplexSpecialProp("autoRound,strictUnits", {parser:function(t, e, p, cssp, pt) {return pt;}}); //just so that we can ignore these properties (not tween them)
4474		_registerComplexSpecialProp("border", {defaultValue:"0px solid #000", parser:function(t, e, p, cssp, pt, plugin) {
4475				return this.parseComplex(t.style, this.format(_getStyle(t, "borderTopWidth", _cs, false, "0px") + " " + _getStyle(t, "borderTopStyle", _cs, false, "solid") + " " + _getStyle(t, "borderTopColor", _cs, false, "#000")), this.format(e), pt, plugin);
4476			}, color:true, formatter:function(v) {
4477				var a = v.split(" ");
4478				return a[0] + " " + (a[1] || "solid") + " " + (v.match(_colorExp) || ["#000"])[0];
4479			}});
4480		_registerComplexSpecialProp("borderWidth", {parser:_getEdgeParser("borderTopWidth,borderRightWidth,borderBottomWidth,borderLeftWidth")}); //Firefox doesn't pick up on borderWidth set in style sheets (only inline).
4481		_registerComplexSpecialProp("float,cssFloat,styleFloat", {parser:function(t, e, p, cssp, pt, plugin) {
4482			var s = t.style,
4483				prop = ("cssFloat" in s) ? "cssFloat" : "styleFloat";
4484			return new CSSPropTween(s, prop, 0, 0, pt, -1, p, false, 0, s[prop], e);
4485		}});
4486
4487		//opacity-related
4488		var _setIEOpacityRatio = function(v) {
4489				var t = this.t, //refers to the element's style property
4490					filters = t.filter || _getStyle(this.data, "filter") || "",
4491					val = (this.s + this.c * v) | 0,
4492					skip;
4493				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.
4494					if (filters.indexOf("atrix(") === -1 && filters.indexOf("radient(") === -1 && filters.indexOf("oader(") === -1) {
4495						t.removeAttribute("filter");
4496						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.
4497					} else {
4498						t.filter = filters.replace(_alphaFilterExp, "");
4499						skip = true;
4500					}
4501				}
4502				if (!skip) {
4503					if (this.xn1) {
4504						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.
4505					}
4506					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
4507						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)
4508							t.filter = filters + " alpha(opacity=" + val + ")"; //we round the value because otherwise, bugs in IE7/8 can prevent "visibility" changes from being applied properly.
4509						}
4510					} else {
4511						t.filter = filters.replace(_opacityExp, "opacity=" + val);
4512					}
4513				}
4514			};
4515		_registerComplexSpecialProp("opacity,alpha,autoAlpha", {defaultValue:"1", parser:function(t, e, p, cssp, pt, plugin) {
4516			var b = parseFloat(_getStyle(t, "opacity", _cs, false, "1")),
4517				style = t.style,
4518				isAutoAlpha = (p === "autoAlpha");
4519			if (typeof(e) === "string" && e.charAt(1) === "=") {
4520				e = ((e.charAt(0) === "-") ? -1 : 1) * parseFloat(e.substr(2)) + b;
4521			}
4522			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)
4523				b = 0;
4524			}
4525			if (_supportsOpacity) {
4526				pt = new CSSPropTween(style, "opacity", b, e - b, pt);
4527			} else {
4528				pt = new CSSPropTween(style, "opacity", b * 100, (e - b) * 100, pt);
4529				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.
4530				style.zoom = 1; //helps correct an IE issue.
4531				pt.type = 2;
4532				pt.b = "alpha(opacity=" + pt.s + ")";
4533				pt.e = "alpha(opacity=" + (pt.s + pt.c) + ")";
4534				pt.data = t;
4535				pt.plugin = plugin;
4536				pt.setRatio = _setIEOpacityRatio;
4537			}
4538			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
4539				pt = new CSSPropTween(style, "visibility", 0, 0, pt, -1, null, false, 0, ((b !== 0) ? "inherit" : "hidden"), ((e === 0) ? "hidden" : "inherit"));
4540				pt.xs0 = "inherit";
4541				cssp._overwriteProps.push(pt.n);
4542				cssp._overwriteProps.push(p);
4543			}
4544			return pt;
4545		}});
4546
4547
4548		var _removeProp = function(s, p) {
4549				if (p) {
4550					if (s.removeProperty) {
4551						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)
4552							p = "-" + p;
4553						}
4554						s.removeProperty(p.replace(_capsExp, "-$1").toLowerCase());
4555					} else { //note: old versions of IE use "removeAttribute()" instead of "removeProperty()"
4556						s.removeAttribute(p);
4557					}
4558				}
4559			},
4560			_setClassNameRatio = function(v) {
4561				this.t._gsClassPT = this;
4562				if (v === 1 || v === 0) {
4563					this.t.setAttribute("class", (v === 0) ? this.b : this.e);
4564					var mpt = this.data, //first MiniPropTween
4565						s = this.t.style;
4566					while (mpt) {
4567						if (!mpt.v) {
4568							_removeProp(s, mpt.p);
4569						} else {
4570							s[mpt.p] = mpt.v;
4571						}
4572						mpt = mpt._next;
4573					}
4574					if (v === 1 && this.t._gsClassPT === this) {
4575						this.t._gsClassPT = null;
4576					}
4577				} else if (this.t.getAttribute("class") !== this.e) {
4578					this.t.setAttribute("class", this.e);
4579				}
4580			};
4581		_registerComplexSpecialProp("className", {parser:function(t, e, p, cssp, pt, plugin, vars) {
4582			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.
4583				cssText = t.style.cssText,
4584				difData, bs, cnpt, cnptLookup, mpt;
4585			pt = cssp._classNamePT = new CSSPropTween(t, p, 0, 0, pt, 2);
4586			pt.setRatio = _setClassNameRatio;
4587			pt.pr = -11;
4588			_hasPriority = true;
4589			pt.b = b;
4590			bs = _getAllStyles(t, _cs);
4591			//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
4591ing that were there just for class-specific values)
4592			cnpt = t._gsClassPT;
4593			if (cnpt) {
4594				cnptLookup = {};
4595				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.
4596				while (mpt) {
4597					cnptLookup[mpt.p] = 1;
4598					mpt = mpt._next;
4599				}
4600				cnpt.setRatio(1);
4601			}
4602			t._gsClassPT = pt;
4603			pt.e = (e.charAt(1) !== "=") ? e : b.replace(new RegExp("\\s*\\b" + e.substr(2) + "\\b"), "") + ((e.charAt(0) === "+") ? " " + e.substr(2) : "");
4604			t.setAttribute("class", pt.e);
4605			difData = _cssDif(t, bs, _getAllStyles(t), vars, cnptLookup);
4606			t.setAttribute("class", b);
4607			pt.data = difData.firstMPT;
4608			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).
4609			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)
4610			return pt;
4611		}});
4612
4613
4614		var _setClearPropsRatio = function(v) {
4615			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).
4616				var s = this.t.style,
4617					transformParse = _specialProps.transform.parse,
4618					a, p, i, clearTransform, transform;
4619				if (this.e === "all") {
4620					s.cssText = "";
4621					clearTransform = true;
4622				} else {
4623					a = this.e.split(" ").join("").split(",");
4624					i = a.length;
4625					while (--i > -1) {
4626						p = a[i];
4627						if (_specialProps[p]) {
4628							if (_specialProps[p].parse === transformParse) {
4629								clearTransform = true;
4630							} else {
4631								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"
4632							}
4633						}
4634						_removeProp(s, p);
4635					}
4636				}
4637				if (clearTransform) {
4638					_removeProp(s, _transformProp);
4639					transform = this.t._gsTransform;
4640					if (transform) {
4641						if (transform.svg) {
4642							this.t.removeAttribute("data-svg-origin");
4643						}
4644						delete this.t._gsTransform;
4645					}
4646				}
4647
4648			}
4649		};
4650		_registerComplexSpecialProp("clearProps", {parser:function(t, e, p, cssp, pt) {
4651			pt = new CSSPropTween(t, p, 0, 0, pt, 2);
4652			pt.setRatio = _setClearPropsRatio;
4653			pt.e = e;
4654			pt.pr = -10;
4655			pt.data = cssp._tween;
4656			_hasPriority = true;
4657			return pt;
4658		}});
4659
4660		p = "bezier,throwProps,physicsProps,physics2D".split(",");
4661		i = p.length;
4662		while (i--) {
4663			_registerPluginProp(p[i]);
4664		}
4665
4666
4667
4668
4669
4670
4671
4672
4673		p = CSSPlugin.prototype;
4674		p._firstPT = p._lastParsedTransform = p._transform = null;
4675
4676		//gets called when the tween renders for the first time. This kicks everything off, recording start/end values, etc.
4677		p._onInitTween = function(target, vars, tween) {
4678			if (!target.nodeType) { //css is only for dom elements
4679				return false;
4680			}
4681			this._target = target;
4682			this._tween = tween;
4683			this._vars = vars;
4684			_autoRound = vars.autoRound;
4685			_hasPriority = false;
4686			_suffixMap = vars.suffixMap || CSSPlugin.suffixMap;
4687			_cs = _getComputedStyle(target, "");
4688			_overwriteProps = this._overwriteProps;
4689			var style = target.style,
4690				v, pt, pt2, first, last, next, zIndex, tpt, threeD;
4691			if (_reqSafariFix) if (style.zIndex === "") {
4692				v = _getStyle(target, "zIndex", _cs);
4693				if (v === "auto" || v === "") {
4694					//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.
4695					this._addLazySet(style, "zIndex", 0);
4696				}
4697			}
4698
4699			if (typeof(vars) === "string") {
4700				first = style.cssText;
4701				v = _getAllStyles(target, _cs);
4702				style.cssText = first + ";" + vars;
4703				v = _cssDif(target, v, _getAllStyles(target)).difs;
4704				if (!_supportsOpacity && _opacityValExp.test(vars)) {
4705					v.opacity = parseFloat( RegExp.$1 );
4706				}
4707				vars = v;
4708				style.cssText = first;
4709			}
4710
4711			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.
4712				this._firstPT = pt = _specialProps.className.parse(target, vars.className, "className", this, null, null, vars);
4713			} else {
4714				this._firstPT = pt = this.parse(target, vars, null);
4715			}
4716
4717			if (this._transformType) {
4718				threeD = (this._transformType === 3);
4719				if (!_transformProp) {
4720					style.zoom = 1; //helps correct an IE issue.
4721				} else if (_isSafari) {
4722					_reqSafariFix = true;
4723					//if zIndex isn't set, iOS Safari doesn't repaint things correctly sometimes (seemingly at random).
4724					if (style.zIndex === "") {
4725						zIndex = _getStyle(target, "zIndex", _cs);
4726						if (zIndex === "auto" || zIndex === "") {
4727							this._addLazySet(style, "zIndex", 0);
4728						}
4729					}
4730					//Setting WebkitBackfaceVisibility corrects 3 bugs:
4731					// 1) [non-Android] Safari skips rendering changes to "top" and "left" that are made on the same frame/render as a transform update.
4732					// 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.
4733					// 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.
4734					//Note: we allow the user to override the auto-setting by defining WebkitBackfaceVisibility in the vars of the tween.
4735					if (_isSafariLT6) {
4736						this._addLazySet(style, "WebkitBackfaceVisibility", this._vars.WebkitBackfaceVisibility || (threeD ? "visible" : "hidden"));
4737					}
4738				}
4739				pt2 = pt;
4740				while (pt2 && pt2._next) {
4741					pt2 = pt2._next;
4742				}
4743				tpt = new CSSPropTween(target, "transform", 0, 0, null, 2);
4744				this._linkCSSP(tpt, null, pt2);
4745				tpt.setRatio = _transformProp ? _setTransformRatio : _setIETransformRatio;
4746				tpt.data = this._transform || _getTransform(target, _cs, true);
4747				tpt.tween = tween;
4748				tpt.pr = -1; //ensures that the transforms get applied after the components are updated.
4749				_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.
4750			}
4751
4752			if (_hasPriority) {
4753				//reorders the linked list in order of pr (priority)
4754				while (pt) {
4755					next = pt._next;
4756					pt2 = first;
4757					while (pt2 && pt2.pr > pt.pr) {
4758						pt2 = pt2._next;
4759					}
4760					if ((pt._prev = pt2 ? pt2._prev : last)) {
4761						pt._prev._next = pt;
4762					} else {
4763						first = pt;
4764					}
4765					if ((pt._next = pt2)) {
4766						pt2._prev = pt;
4767					} else {
4768						last = pt;
4769					}
4770					pt = next;
4771				}
4772				this._firstPT = first;
4773			}
4774			return true;
4775		};
4776
4777
4778		p.parse = function(target, vars, pt, plugin) {
4779			var style = target.style,
4780				p, sp, bn, en, bs, es, bsfx, esfx, isStr, rel;
4781			for (p in vars) {
4782				es = vars[p]; //ending value string
4783				sp = _specialProps[p]; //SpecialProp lookup.
4784				if (sp) {
4785					pt = sp.parse(target, es, p, this, pt, plugin, vars);
4786
4787				} else {
4788					bs = _getStyle(target, p, _cs) + "";
4789					isStr = (typeof(es) === "string");
4790					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:
4791						if (!isStr) {
4792							es = _parseColor(es);
4793							es = ((es.length > 3) ? "rgba(" : "rgb(") + es.join(",") + ")";
4794						}
4795						pt = _parseComplex(style, p, bs, es, true, "transparent", pt, 0, plugin);
4796
4797					} else if (isStr && (es.indexOf(" ") !== -1 || es.indexOf(",") !== -1)) {
4798						pt = _parseComplex(style, p, bs, es, true, null, pt, 0, plugin);
4799
4800					} else {
4801						bn = parseFloat(bs);
4802						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.
4803
4804						if (bs === "" || bs === "auto") {
4805							if (p === "width" || p === "height") {
4806								bn = _getDimension(target, p, _cs);
4807								bsfx = "px";
4808							} else if (p === "left" || p === "top") {
4809								bn = _calculateOffset(target, p, _cs);
4810								bsfx = "px";
4811							} else {
4812								bn = (p !== "opacity") ? 0 : 1;
4813								bsfx = "";
4814							}
4815						}
4816
4817						rel = (isStr && es.charAt(1) === "=");
4818						if (rel) {
4819							en = parseInt(es.charAt(0) + "1", 10);
4820							es = es.substr(2);
4821							en *= parseFloat(es);
4822							esfx = es.replace(_suffixExp, "");
4823						} else {
4824							en = parseFloat(es);
4825							esfx = isStr ? es.replace(_suffixExp, "") : "";
4826						}
4827
4828						if (esfx === "") {
4829							esfx = (p in _suffixMap) ? _suffixMap[p] : bsfx; //populate the end suffix, prioritizing the map, then if none is found, use the beginning suffix.
4830						}
4831
4832						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.
4833
4834						//if the beginning/ending suffixes don't match, normalize them...
4835						if (bsfx !== esfx) if (esfx !== "") if (en || en === 0) if (bn) { //note: if the beginning value (bn) is 0, we don't need to convert units!
4836							bn = _convertToPixels(target, p, bn, bsfx);
4837							if (esfx === "%") {
4838								bn /= _convertToPixels(target, p, 100, "%") / 100;
4839								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.
4840									bs = bn + "%";
4841								}
4842
4843							} else if (esfx === "em" || esfx === "rem") {
4844								bn /= _convertToPixels(target, p, 1, esfx);
4845
4846							//otherwise convert to pixels.
4847							} else if (esfx !== "px") {
4848								en = _convertToPixels(target, p, en, esfx);
4849								esfx = "px"; //we don't use bsfx after this, so we don't need to set it to px too.
4850							}
4851							if (rel) if (en || en === 0) {
4852								es = (en + bn) + esfx; //the changes we made affect relative calculations, so adjust the end value here.
4853							}
4854						}
4855
4856						if (rel) {
4857							en += bn;
4858						}
4859
4860						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.
4861							pt = new CSSPropTween(style, p, bn, en - bn, pt, 0, p, (_autoRound !== false && (esfx === "px" || p === "zIndex")), 0, bs, es);
4862							pt.xs0 = esfx;
4863							//DEBUG: _log("tween "+p+" from "+pt.b+" ("+bn+esfx+") to "+pt.e+" with suffix: "+pt.xs0);
4864						} else if (style[p] === undefined || !es && (es + "" === "NaN" || es == null)) {
4865							_log("invalid " + p + " tween value: " + vars[p]);
4866						} else {
4867							pt = new CSSPropTween(style, p, en || bn || 0, 0, pt, -1, p, false, 0, bs, es);
4868							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.
4869							//DEBUG: _log("non-tweening value "+p+": "+pt.xs0);
4870						}
4871					}
4872				}
4873				if (plugin) if (pt && !pt.plugin) {
4874					pt.plugin = plugin;
4875				}
4876			}
4877			return pt;
4878		};
4879
4880
4881		//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.
4882		p.setRatio = function(v) {
4883			var pt = this._firstPT,
4884				min = 0.000001,
4885				val, str, i;
4886			//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).
4887			if (v === 1 && (this._tween._time === this._tween._duration || this._tween._time === 0)) {
4888				while (pt) {
4889					if (pt.type !== 2) {
4890						if (pt.r && pt.type !== -1) {
4891							val = Math.round(pt.s + pt.c);
4892							if (!pt.type) {
4893								pt.t[pt.p] = val + pt.xs0;
4894							} else if (pt.type === 1) { //complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)"
4895								i = pt.l;
4896								str = pt.xs0 + val + pt.xs1;
4897								for (i = 1; i < pt.l; i++) {
4898									str += pt["xn"+i] + pt["xs"+(i+1)];
4899								}
4900								pt.t[pt.p] = str;
4901							}
4902						} else {
4903							pt.t[pt.p] = pt.e;
4904						}
4905					} else {
4906						pt.setRatio(v);
4907					}
4908					pt = pt._next;
4909				}
4910
4911			} else if (v || !(this._tween._time === this._tween._duration || this._tween._time === 0) || this._tween._rawPrevTime === -0.000001) {
4912				while (pt) {
4913					val = pt.c * v + pt.s;
4914					if (pt.r) {
4915						val = Math.round(val);
4916					} else if (val < min) if (val > -min) {
4917						val = 0;
4918					}
4919					if (!pt.type) {
4920						pt.t[pt.p] = val + pt.xs0;
4921					} else if (pt.type === 1) { //complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)"
4922						i = pt.l;
4923						if (i === 2) {
4924							pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2;
4925						} else if (i === 3) {
4926							pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3;
4927						} else if (i === 4) {
4928							pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3 + pt.xn3 + pt.xs4;
4929						} else if (i === 5) {
4930							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;
4931						} else {
4932							str = pt.xs0 + val + pt.xs1;
4933							for (i = 1; i < pt.l; i++) {
4934								str += pt["xn"+i] + pt["xs"+(i+1)];
4935							}
4936							pt.t[pt.p] = str;
4937						}
4938
4939					} else if (pt.type === -1) { //non-tweening value
4940						pt.t[pt.p] = pt.xs0;
4941
4942					} else if (pt.setRatio) { //custom setRatio() for things like SpecialProps, external plugins, etc.
4943						pt.setRatio(v);
4944					}
4945					pt = pt._next;
4946				}
4947
4948			//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).
4949			} else {
4950				while (pt) {
4951					if (pt.type !== 2) {
4952						pt.t[pt.p] = pt.b;
4953					} else {
4954						pt.setRatio(v);
4955					}
4956					pt = pt._next;
4957				}
4958			}
4959		};
4960
4961		/**
4962		 * @private
4963		 * Forces rendering of the target's transforms (rotation, scale, etc.) whenever the CSSPlugin's setRatio() is called.
4964		 * Basically, this tells the CSSPlugin to create a CSSPropTween (type 2) after instantiation that runs last in the linked
4965		 * list and calls the appropriate (3D or 2D) rendering function. We separate this into its own method so that we can call
4966		 * it from other plugins like BezierPlugin if, for example, it needs to apply an autoRotation and this CSSPlugin
4967		 * doesn't have any transform-related properties of its own. You can call this method as many times as you
4968		 * want and it won't create duplicate CSSPropTweens.
4969		 *
4970		 * @param {boolean} threeD if true, it should apply 3D tweens (otherwise, just 2D ones are fine and typically faster)
4971		 */
4972		p._enableTransforms = function(threeD) {
4973			this._transform = this._transform || _getTransform(this._target, _cs, true); //ensures that the element has a _gsTransform property with the appropriate values.
4974			this._transformType = (!(this._transform.svg && _useSVGTransformAttr) && (threeD || this._transformType === 3)) ? 3 : 2;
4975		};
4976
4977		var lazySet = function(v) {
4978			this.t[this.p] = this.e;
4979			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.
4980		};
4981		/** @private Gives us a way to set a value on the first render (and only the first render). **/
4982		p._addLazySet = function(t, p, v) {
4983			var pt = this._firstPT = new CSSPropTween(t, p, 0, 0, this._firstPT, 2);
4984			pt.e = v;
4985			pt.setRatio = lazySet;
4986			pt.data = this;
4987		};
4988
4989		/** @private **/
4990		p._linkCSSP = function(pt, next, prev, remove) {
4991			if (pt) {
4992				if (next) {
4993					next._prev = pt;
4994				}
4995				if (pt._next) {
4996					pt._next._prev = pt._prev;
4997				}
4998				if (pt._prev) {
4999					pt._prev._next = pt._next;
5000				} else if (this._firstPT === pt) {
5001					this._firstPT = pt._next;
5002					remove = true; //just to prevent resetting this._firstPT 5 lines down in case pt._next is null. (optimized for speed)
5003				}
5004				if (prev) {
5005					prev._next = pt;
5006				} else if (!remove && this._firstPT === null) {
5007					this._firstPT = pt;
5008				}
5009				pt._next = next;
5010				pt._prev = prev;
5011			}
5012			return pt;
5013		};
5014
5015		//we need to make sure that if alpha or autoAlpha is killed, opacity is too. And autoAlpha affects the "visibility" property.
5016		p._kill = function(lookup) {
5017			var copy = lookup,
5018				pt, p, xfirst;
5019			if (lookup.autoAlpha || lookup.alpha) {
5020				copy = {};
5021				for (p in lookup) { //copy the lookup so that we're not changing the original which may be passed elsewhere.
5022					copy[p] = lookup[p];
5023				}
5024				copy.opacity = 1;
5025				if (copy.autoAlpha) {
5026					copy.visibility = 1;
5027				}
5028			}
5029			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".
5030				xfirst = pt.xfirst;
5031				if (xfirst && xfirst._prev) {
5032					this._linkCSSP(xfirst._prev, pt._next, xfirst._prev._prev); //break off the prev
5033				} else if (xfirst === this._firstPT) {
5034					this._firstPT = pt._next;
5035				}
5036				if (pt._next) {
5037					this._linkCSSP(pt._next, pt._next._next, xfirst._prev);
5038				}
5039				this._classNamePT = null;
5040			}
5041			return TweenPlugin.prototype._kill.call(this, copy);
5042		};
5043
5044
5045
5046		//used by cascadeTo() for gathering all the style properties of each child element into an array for c
5046omparison.
5047		var _getChildStyles = function(e, props, targets) {
5048				var children, i, child, type;
5049				if (e.slice) {
5050					i = e.length;
5051					while (--i > -1) {
5052						_getChildStyles(e[i], props, targets);
5053					}
5054					return;
5055				}
5056				children = e.childNodes;
5057				i = children.length;
5058				while (--i > -1) {
5059					child = children[i];
5060					type = child.type;
5061					if (child.style) {
5062						props.push(_getAllStyles(child));
5063						if (targets) {
5064							targets.push(child);
5065						}
5066					}
5067					if ((type === 1 || type === 9 || type === 11) && child.childNodes.length) {
5068						_getChildStyles(child, props, targets);
5069					}
5070				}
5071			};
5072
5073		/**
5074		 * Typically only useful for className tweens that may affect child elements, this method creates a TweenLite
5075		 * and then compares the style properties of all the target's child elements at the tween's start and end, and
5076		 * if any are different, it also creates tweens for those and returns an array containing ALL of the resulting
5077		 * tweens (so that you can easily add() them to a TimelineLite, for example). The reason this functionality is
5078		 * wrapped into a separate static method of CSSPlugin instead of being integrated into all regular className tweens
5079		 * is because it creates entirely new tweens that may have completely different targets than the original tween,
5080		 * so if they were all lumped into the original tween instance, it would be inconsistent with the rest of the API
5081		 * and it would create other problems. For example:
5082		 *  - 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)
5083		 *  - 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.
5084		 *  - 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.
5085		 *
5086		 * @param {Object} target object to be tweened
5087		 * @param {number} Duration in seconds (or frames for frames-based tweens)
5088		 * @param {Object} Object containing the end values, like {className:"newClass", ease:Linear.easeNone}
5089		 * @return {Array} An array of TweenLite instances
5090		 */
5091		CSSPlugin.cascadeTo = function(target, duration, vars) {
5092			var tween = TweenLite.to(target, duration, vars),
5093				results = [tween],
5094				b = [],
5095				e = [],
5096				targets = [],
5097				_reservedProps = TweenLite._internals.reservedProps,
5098				i, difs, p, from;
5099			target = tween._targets || tween.target;
5100			_getChildStyles(target, b, targets);
5101			tween.render(duration, true, true);
5102			_getChildStyles(target, e);
5103			tween.render(0, true, true);
5104			tween._enabled(true);
5105			i = targets.length;
5106			while (--i > -1) {
5107				difs = _cssDif(targets[i], b[i], e[i]);
5108				if (difs.firstMPT) {
5109					difs = difs.difs;
5110					for (p in vars) {
5111						if (_reservedProps[p]) {
5112							difs[p] = vars[p];
5113						}
5114					}
5115					from = {};
5116					for (p in difs) {
5117						from[p] = b[i][p];
5118					}
5119					results.push(TweenLite.fromTo(targets[i], duration, from, difs));
5120				}
5121			}
5122			return results;
5123		};
5124
5125		TweenPlugin.activate([CSSPlugin]);
5126		return CSSPlugin;
5127
5128	}, true);
5129
5130	
5131	
5132	
5133	
5134	
5135	
5136	
5137	
5138	
5139	
5140/*
5141 * ----------------------------------------------------------------
5142 * RoundPropsPlugin
5143 * ----------------------------------------------------------------
5144 */
5145	(function() {
5146
5147		var RoundPropsPlugin = _gsScope._gsDefine.plugin({
5148				propName: "roundProps",
5149				version: "1.5",
5150				priority: -1,
5151				API: 2,
5152
5153				//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
5154				init: function(target, value, tween) {
5155					this._tween = tween;
5156					return true;
5157				}
5158
5159			}),
5160			_roundLinkedList = function(node) {
5161				while (node) {
5162					if (!node.f && !node.blob) {
5163						node.r = 1;
5164					}
5165					node = node._next;
5166				}
5167			},
5168			p = RoundPropsPlugin.prototype;
5169
5170		p._onInitAllProps = function() {
5171			var tween = this._tween,
5172				rp = (tween.vars.roundProps.join) ? tween.vars.roundProps : tween.vars.roundProps.split(","),
5173				i = rp.length,
5174				lookup = {},
5175				rpt = tween._propLookup.roundProps,
5176				prop, pt, next;
5177			while (--i > -1) {
5178				lookup[rp[i]] = 1;
5179			}
5180			i = rp.length;
5181			while (--i > -1) {
5182				prop = rp[i];
5183				pt = tween._firstPT;
5184				while (pt) {
5185					next = pt._next; //record here, because it may get removed
5186					if (pt.pg) {
5187						pt.t._roundProps(lookup, true);
5188					} else if (pt.n === prop) {
5189						if (pt.f === 2 && pt.t) { //a blob (text containing multiple numeric values)
5190							_roundLinkedList(pt.t._firstPT);
5191						} else {
5192							this._add(pt.t, prop, pt.s, pt.c);
5193							//remove from linked list
5194							if (next) {
5195								next._prev = pt._prev;
5196							}
5197							if (pt._prev) {
5198								pt._prev._next = next;
5199							} else if (tween._firstPT === pt) {
5200								tween._firstPT = next;
5201							}
5202							pt._next = pt._prev = null;
5203							tween._propLookup[prop] = rpt;
5204						}
5205					}
5206					pt = next;
5207				}
5208			}
5209			return false;
5210		};
5211
5212		p._add = function(target, p, s, c) {
5213			this._addTween(target, p, s, s + c, p, true);
5214			this._overwriteProps.push(p);
5215		};
5216
5217	}());
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228/*
5229 * ----------------------------------------------------------------
5230 * AttrPlugin
5231 * ----------------------------------------------------------------
5232 */
5233
5234	(function() {
5235
5236		_gsScope._gsDefine.plugin({
5237			propName: "attr",
5238			API: 2,
5239			version: "0.5.0",
5240
5241			//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
5242			init: function(target, value, tween) {
5243				var p;
5244				if (typeof(target.setAttribute) !== "function") {
5245					return false;
5246				}
5247				for (p in value) {
5248					this._addTween(target, "setAttribute", target.getAttribute(p) + "", value[p] + "", p, false, p);
5249					this._overwriteProps.push(p);
5250				}
5251				return true;
5252			}
5253
5254		});
5255
5256	}());
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267/*
5268 * ----------------------------------------------------------------
5269 * DirectionalRotationPlugin
5270 * ----------------------------------------------------------------
5271 */
5272	_gsScope._gsDefine.plugin({
5273		propName: "directionalRotation",
5274		version: "0.2.1",
5275		API: 2,
5276
5277		//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
5278		init: function(target, value, tween) {
5279			if (typeof(value) !== "object") {
5280				value = {rotation:value};
5281			}
5282			this.finals = {};
5283			var cap = (value.useRadians === true) ? Math.PI * 2 : 360,
5284				min = 0.000001,
5285				p, v, start, end, dif, split;
5286			for (p in value) {
5287				if (p !== "useRadians") {
5288					split = (value[p] + "").split("_");
5289					v = split[0];
5290					start = parseFloat( (typeof(target[p]) !== "function") ? target[p] : target[ ((p.indexOf("set") || typeof(target["get" + p.substr(3)]) !== "function") ? p : "get" + p.substr(3)) ]() );
5291					end = this.finals[p] = (typeof(v) === "string" && v.charAt(1) === "=") ? start + parseInt(v.charAt(0) + "1", 10) * Number(v.substr(2)) : Number(v) || 0;
5292					dif = end - start;
5293					if (split.length) {
5294						v = split.join("_");
5295						if (v.indexOf("short") !== -1) {
5296							dif = dif % cap;
5297							if (dif !== dif % (cap / 2)) {
5298								dif = (dif < 0) ? dif + cap : dif - cap;
5299							}
5300						}
5301						if (v.indexOf("_cw") !== -1 && dif < 0) {
5302							dif = ((dif + cap * 9999999999) % cap) - ((dif / cap) | 0) * cap;
5303						} else if (v.indexOf("ccw") !== -1 && dif > 0) {
5304							dif = ((dif - cap * 9999999999) % cap) - ((dif / cap) | 0) * cap;
5305						}
5306					}
5307					if (dif > min || dif < -min) {
5308						this._addTween(target, p, start, start + dif, p);
5309						this._overwriteProps.push(p);
5310					}
5311				}
5312			}
5313			return true;
5314		},
5315
5316		//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.)
5317		set: function(ratio) {
5318			var pt;
5319			if (ratio !== 1) {
5320				this._super.setRatio.call(this, ratio);
5321			} else {
5322				pt = this._firstPT;
5323				while (pt) {
5324					if (pt.f) {
5325						pt.t[pt.p](this.finals[pt.p]);
5326					} else {
5327						pt.t[pt.p] = this.finals[pt.p];
5328					}
5329					pt = pt._next;
5330				}
5331			}
5332		}
5333
5334	})._autoCSS = true;
5335
5336
5337
5338
5339
5340
5341
5342	
5343	
5344	
5345	
5346/*
5347 * ----------------------------------------------------------------
5348 * EasePack
5349 * ----------------------------------------------------------------
5350 */
5351	_gsScope._gsDefine("easing.Back", ["easing.Ease"], function(Ease) {
5352		
5353		var w = (_gsScope.GreenSockGlobals || _gsScope),
5354			gs = w.com.greensock,
5355			_2PI = Math.PI * 2,
5356			_HALF_PI = Math.PI / 2,
5357			_class = gs._class,
5358			_create = function(n, f) {
5359				var C = _class("easing." + n, function(){}, true),
5360					p = C.prototype = new Ease();
5361				p.constructor = C;
5362				p.getRatio = f;
5363				return C;
5364			},
5365			_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.
5366			_wrap = function(name, EaseOut, EaseIn, EaseInOut, aliases) {
5367				var C = _class("easing."+name, {
5368					easeOut:new EaseOut(),
5369					easeIn:new EaseIn(),
5370					easeInOut:new EaseInOut()
5371				}, true);
5372				_easeReg(C, name);
5373				return C;
5374			},
5375			EasePoint = function(time, value, next) {
5376				this.t = time;
5377				this.v = value;
5378				if (next) {
5379					this.next = next;
5380					next.prev = this;
5381					this.c = next.v - value;
5382					this.gap = next.t - time;
5383				}
5384			},
5385
5386			//Back
5387			_createBack = function(n, f) {
5388				var C = _class("easing." + n, function(overshoot) {
5389						this._p1 = (overshoot || overshoot === 0) ? overshoot : 1.70158;
5390						this._p2 = this._p1 * 1.525;
5391					}, true),
5392					p = C.prototype = new Ease();
5393				p.constructor = C;
5394				p.getRatio = f;
5395				p.config = function(overshoot) {
5396					return new C(overshoot);
5397				};
5398				return C;
5399			},
5400
5401			Back = _wrap("Back",
5402				_createBack("BackOut", function(p) {
5403					return ((p = p - 1) * p * ((this._p1 + 1) * p + this._p1) + 1);
5404				}),
5405				_createBack("BackIn", function(p) {
5406					return p * p * ((this._p1 + 1) * p - this._p1);
5407				}),
5408				_createBack("BackInOut", function(p) {
5409					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);
5410				})
5411			),
5412
5413
5414			//SlowMo
5415			SlowMo = _class("easing.SlowMo", function(linearRatio, power, yoyoMode) {
5416				power = (power || power === 0) ? power : 0.7;
5417				if (linearRatio == null) {
5418					linearRatio = 0.7;
5419				} else if (linearRatio > 1) {
5420					linearRatio = 1;
5421				}
5422				this._p = (linearRatio !== 1) ? power : 0;
5423				this._p1 = (1 - linearRatio) / 2;
5424				this._p2 = linearRatio;
5425				this._p3 = this._p1 + this._p2;
5426				this._calcEnd = (yoyoMode === true);
5427			}, true),
5428			p = SlowMo.prototype = new Ease(),
5429			SteppedEase, RoughEase, _createElastic;
5430
5431		p.constructor = SlowMo;
5432		p.getRatio = function(p) {
5433			var r = p + (0.5 - p) * this._p;
5434			if (p < this._p1) {
5435				return this._calcEnd ? 1 - ((p = 1 - (p / this._p1)) * p) : r - ((p = 1 - (p / this._p1)) * p * p * p * r);
5436			} else if (p > this._p3) {
5437				return this._calcEnd ? 1 - (p = (p - this._p3) / this._p1) * p : r + ((p - r) * (p = (p - this._p3) / this._p1) * p * p * p);
5438			}
5439			return this._calcEnd ? 1 : r;
5440		};
5441		SlowMo.ease = new SlowMo(0.7, 0.7);
5442
5443		p.config = SlowMo.config = function(linearRatio, power, yoyoMode) {
5444			return new SlowMo(linearRatio, power, yoyoMode);
5445		};
5446
5447
5448		//SteppedEase
5449		SteppedEase = _class("easing.SteppedEase", function(steps) {
5450				steps = steps || 1;
5451				this._p1 = 1 / steps;
5452				this._p2 = steps + 1;
5453			}, true);
5454		p = SteppedEase.prototype = new Ease();
5455		p.constructor = SteppedEase;
5456		p.getRatio = function(p) {
5457			if (p < 0) {
5458				p = 0;
5459			} else if (p >= 1) {
5460				p = 0.999999999;
5461			}
5462			return ((this._p2 * p) >> 0) * this._p1;
5463		};
5464		p.config = SteppedEase.config = function(steps) {
5465			return new SteppedEase(steps);
5466		};
5467
5468
5469		//RoughEase
5470		RoughEase = _class("easing.RoughEase", function(vars) {
5471			vars = vars || {};
5472			var taper = vars.taper || "none",
5473				a = [],
5474				cnt = 0,
5475				points = (vars.points || 20) | 0,
5476				i = points,
5477				randomize = (vars.randomize !== false),
5478				clamp = (vars.clamp === true),
5479				template = (vars.template instanceof Ease) ? vars.template : null,
5480				strength = (typeof(vars.strength) === "number") ? vars.strength * 0.4 : 0.4,
5481				x, y, bump, invX, obj, pnt;
5482			while (--i > -1) {
5483				x = randomize ? Math.random() : (1 / points) * i;
5484				y = template ? template.getRatio(x) : x;
5485				if (taper === "none") {
5486					bump = strength;
5487				} else if (taper === "out") {
5488					invX = 1 - x;
5489					bump = invX * invX * strength;
5490				} else if (taper === "in") {
5491					bump = x * x * strength;
5492				} else if (x < 0.5) {  //"both" (start)
5493					invX = x * 2;
5494					bump = invX * invX * 0.5 * strength;
5495				} else {				//"both" (end)
5496					invX = (1 - x) * 2;
5497					bump = invX * invX * 0.5 * strength;
5498				}
5499				if (randomize) {
5500					y += (Math.random() * bump) - (bump * 0.5);
5501				} else if (i % 2) {
5502					y += bump * 0.5;
5503				} else {
5504					y -= bump * 0.5;
5505				}
5506				if (clamp) {
5507					if (y > 1) {
5508						y = 1;
5509					} else if (y < 0) {
5510						y = 0;
5511					}
5512				}
5513				a[cnt++] = {x:x, y:y};
5514			}
5515			a.sort(function(a, b) {
5516				return a.x - b.x;
5517			});
5518
5519			pnt = new EasePoint(1, 1, null);
5520			i = points;
5521			while (--i > -1) {
5522				obj = a[i];
5523				pnt = new EasePoint(obj.x, obj.y, pnt);
5524			}
5525
5526			this._prev = new EasePoint(0, 0, (pnt.t !== 0) ? pnt : pnt.next);
5527		}, true);
5528		p = RoughEase.prototype = new Ease();
5529		p.constructor = RoughEase;
5530		p.getRatio = function(p) {
5531			var pnt = this._prev;
5532			if (p > pnt.t) {
5533				while (pnt.next && p >= pnt.t) {
5534					pnt = pnt.next;
5535				}
5536				pnt = pnt.prev;
5537			} else {
5538				while (pnt.prev && p <= pnt.t) {
5539					pnt = pnt.prev;
5540				}
5541			}
5542			this._prev = pnt;
5543			return (pnt.v + ((p - pnt.t) / pnt.gap) * pnt.c);
5544		};
5545		p.config = function(vars) {
5546			return new RoughEase(vars);
5547		};
5548		RoughEase.ease = new RoughEase();
5549
5550
5551		//Bounce
5552		_wrap("Bounce",
5553			_create("BounceOut", function(p) {
5554				if (p < 1 / 2.75) {
5555					return 7.5625 * p * p;
5556				} else if (p < 2 / 2.75) {
5557					return 7.5625 * (p -= 1.5 / 2.75) * p + 0.75;
5558				} else if (p < 2.5 / 2.75) {
5559					return 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375;
5560				}
5561				return 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375;
5562			}),
5563			_create("BounceIn", function(p) {
5564				if ((p = 1 - p) < 1 / 2.75) {
5565					return 1 - (7.5625 * p * p);
5566				} else if (p < 2 / 2.75) {
5567					return 1 - (7.5625 * (p -= 1.5 / 2.75) * p + 0.75);
5568				} else if (p < 2.5 / 2.75) {
5569					return 1 - (7.5625 * (p -= 2.25 / 2.75) * p + 0.9375);
5570				}
5571				return 1 - (7.5625 * (p -= 2.625 / 2.75) * p + 0.984375);
5572			}),
5573			_create("BounceInOut", function(p) {
5574				var invert = (p < 0.5);
5575				if (invert) {
5576					p = 1 - (p * 2);
5577				} else {
5578					p = (p * 2) - 1;
5579				}
5580				if (p < 1 / 2.75) {
5581					p = 7.5625 * p * p;
5582				} else if (p < 2 / 2.75) {
5583					p = 7.5625 * (p -= 1.5 / 2.75) * p + 0.75;
5584				} else if (p < 2.5 / 2.75) {
5585					p = 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375;
5586				} else {
5587					p = 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375;
5588				}
5589				return invert ? (1 - p) * 0.5 : p * 0.5 + 0.5;
5590			})
5591		);
5592
5593
5594		//CIRC
5595		_wrap("Circ",
5596			_create("CircOut", function(p) {
5597				return Math.sqrt(1 - (p = p - 1) * p);
5598			}),
5599			_create("CircIn", function(p) {
5600				return -(Math.sqrt(1 - (p * p)) - 1);
5601			}),
5602			_create("CircInOut", function(p) {
5603				return ((p*=2) < 1) ? -0.5 * (Math.sqrt(1 - p * p) - 1) : 0.5 * (Math.sqrt(1 - (p -= 2) * p) + 1);
5604			})
5605		);
5606
5607
5608		//Elastic
5609		_createElastic = function(n, f, def) {
5610			var C = _class("easing." + n, function(amplitude, period) {
5611					this._p1 = (amplitude >= 1) ? amplitude : 1;
5611 //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.
5612					this._p2 = (period || def) / (amplitude < 1 ? amplitude : 1);
5613					this._p3 = this._p2 / _2PI * (Math.asin(1 / this._p1) || 0);
5614					this._p2 = _2PI / this._p2; //precalculate to optimize
5615				}, true),
5616				p = C.prototype = new Ease();
5617			p.constructor = C;
5618			p.getRatio = f;
5619			p.config = function(amplitude, period) {
5620				return new C(amplitude, period);
5621			};
5622			return C;
5623		};
5624		_wrap("Elastic",
5625			_createElastic("ElasticOut", function(p) {
5626				return this._p1 * Math.pow(2, -10 * p) * Math.sin( (p - this._p3) * this._p2 ) + 1;
5627			}, 0.3),
5628			_createElastic("ElasticIn", function(p) {
5629				return -(this._p1 * Math.pow(2, 10 * (p -= 1)) * Math.sin( (p - this._p3) * this._p2 ));
5630			}, 0.3),
5631			_createElastic("ElasticInOut", function(p) {
5632				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;
5633			}, 0.45)
5634		);
5635
5636
5637		//Expo
5638		_wrap("Expo",
5639			_create("ExpoOut", function(p) {
5640				return 1 - Math.pow(2, -10 * p);
5641			}),
5642			_create("ExpoIn", function(p) {
5643				return Math.pow(2, 10 * (p - 1)) - 0.001;
5644			}),
5645			_create("ExpoInOut", function(p) {
5646				return ((p *= 2) < 1) ? 0.5 * Math.pow(2, 10 * (p - 1)) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
5647			})
5648		);
5649
5650
5651		//Sine
5652		_wrap("Sine",
5653			_create("SineOut", function(p) {
5654				return Math.sin(p * _HALF_PI);
5655			}),
5656			_create("SineIn", function(p) {
5657				return -Math.cos(p * _HALF_PI) + 1;
5658			}),
5659			_create("SineInOut", function(p) {
5660				return -0.5 * (Math.cos(Math.PI * p) - 1);
5661			})
5662		);
5663
5664		_class("easing.EaseLookup", {
5665				find:function(s) {
5666					return Ease.map[s];
5667				}
5668			}, true);
5669
5670		//register the non-standard eases
5671		_easeReg(w.SlowMo, "SlowMo", "ease,");
5672		_easeReg(RoughEase, "RoughEase", "ease,");
5673		_easeReg(SteppedEase, "SteppedEase", "ease,");
5674
5675		return Back;
5676		
5677	}, true);
5678
5679
5680});
5681
5682if (_gsScope._gsDefine) { _gsScope._gsQueue.pop()(); } //necessary in case TweenLite was already loaded separately.
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694/*
5695 * ----------------------------------------------------------------
5696 * Base classes like TweenLite, SimpleTimeline, Ease, Ticker, etc.
5697 * ----------------------------------------------------------------
5698 */
5699(function(window, moduleName) {
5700
5701		"use strict";
5702		var _globals = window.GreenSockGlobals = window.GreenSockGlobals || window;
5703		if (_globals.TweenLite) {
5704			return; //in case the core set of classes is already loaded, don't instantiate twice.
5705		}
5706		var _namespace = function(ns) {
5707				var a = ns.split("."),
5708					p = _globals, i;
5709				for (i = 0; i < a.length; i++) {
5710					p[a[i]] = p = p[a[i]] || {};
5711				}
5712				return p;
5713			},
5714			gs = _namespace("com.greensock"),
5715			_tinyNum = 0.0000000001,
5716			_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()
5717				var b = [],
5718					l = a.length,
5719					i;
5720				for (i = 0; i !== l; b.push(a[i++])) {}
5721				return b;
5722			},
5723			_emptyFunc = function() {},
5724			_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)
5725				var toString = Object.prototype.toString,
5726					array = toString.call([]);
5727				return function(obj) {
5728					return obj != null && (obj instanceof Array || (typeof(obj) === "object" && !!obj.push && toString.call(obj) === array));
5729				};
5730			}()),
5731			a, i, p, _ticker, _tickerActive,
5732			_defLookup = {},
5733
5734			/**
5735			 * @constructor
5736			 * Defines a GreenSock class, optionally with an array of dependencies that must be instantiated first and passed into the definition.
5737			 * This allows users to load GreenSock JS files in any order even if they have interdependencies (like CSSPlugin extends TweenPlugin which is
5738			 * inside TweenLite.js, but if CSSPlugin is loaded first, it should wait to run its code until TweenLite.js loads and instantiates TweenPlugin
5739			 * and then pass TweenPlugin to CSSPlugin's definition). This is all done automatically and internally.
5740			 *
5741			 * Every definition will be added to a "com.greensock" global object (typically window, but if a window.GreenSockGlobals object is found,
5742			 * 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,
5743			 * it is ALSO referenced at window.TweenLite. However some classes aren't considered global, like the base com.greensock.core.Animation class, so
5744			 * those will only be at the package like window.com.greensock.core.Animation. Again, if you define a GreenSockGlobals object on the window, everything
5745			 * gets tucked neatly inside there instead of on the window directly. This allows you to do advanced things like load multiple versions of GreenSock
5746			 * 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
5747			 * sandbox the banner one like:
5748			 *
5749			 * <script>
5750			 *     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.
5751			 * </script>
5752			 * <script src="js/greensock/v1.7/TweenMax.js"></script>
5753			 * <script>
5754			 *     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(...)
5755			 * </script>
5756			 * <script src="js/greensock/v1.6/TweenMax.js"></script>
5757			 * <script>
5758			 *     gs.TweenLite.to(...); //would use v1.7
5759			 *     TweenLite.to(...); //would use v1.6
5760			 * </script>
5761			 *
5762			 * @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".
5763			 * @param {!Array.<string>} dependencies An array of dependencies (described as their namespaces minus "com.greensock." prefix). For example ["TweenLite","plugins.TweenPlugin","core.Animation"]
5764			 * @param {!function():Object} func The function that should be called and passed the resolved dependencies which will return the actual class for this definition.
5765			 * @param {boolean=} global If true, the class will be added to the global scope (typically window unless you define a window.GreenSockGlobals object)
5766			 */
5767			Definition = function(ns, dependencies, func, global) {
5768				this.sc = (_defLookup[ns]) ? _defLookup[ns].sc : []; //subclasses
5769				_defLookup[ns] = this;
5770				this.gsClass = null;
5771				this.func = func;
5772				var _classes = [];
5773				this.check = function(init) {
5774					var i = dependencies.length,
5775						missing = i,
5776						cur, a, n, cl, hasModule;
5777					while (--i > -1) {
5778						if ((cur = _defLookup[dependencies[i]] || new Definition(dependencies[i], [])).gsClass) {
5779							_classes[i] = cur.gsClass;
5780							missing--;
5781						} else if (init) {
5782							cur.sc.push(this);
5783						}
5784					}
5785					if (missing === 0 && func) {
5786						a = ("com.greensock." + ns).split(".");
5787						n = a.pop();
5788						cl = _namespace(a.join("."))[n] = this.gsClass = func.apply(func, _classes);
5789
5790						//exports to multiple environments
5791						if (global) {
5792							_globals[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.)
5793							hasModule = (typeof(module) !== "undefined" && module.exports);
5794							if (!hasModule && typeof(define) === "function" && define.amd){ //AMD
5795								define((window.GreenSockAMDPath ? window.GreenSockAMDPath + "/" : "") + ns.split(".").pop(), [], function() { return cl; });
5796							} else if (ns === moduleName && hasModule){ //node
5797								module.exports = cl;
5798							}
5799						}
5800						for (i = 0; i < this.sc.length; i++) {
5801							this.sc[i].check();
5802						}
5803					}
5804				};
5805				this.check(true);
5806			},
5807
5808			//used to create Definition instances (which basically registers a class that has dependencies).
5809			_gsDefine = window._gsDefine = function(ns, dependencies, func, global) {
5810				return new Definition(ns, dependencies, func, global);
5811			},
5812
5813			//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).
5814			_class = gs._class = function(ns, func, global) {
5815				func = func || function() {};
5816				_gsDefine(ns, [], function(){ return func; }, global);
5817				return func;
5818			};
5819
5820		_gsDefine.globals = _globals;
5821
5822
5823
5824/*
5825 * ----------------------------------------------------------------
5826 * Ease
5827 * ----------------------------------------------------------------
5828 */
5829		var _baseParams = [0, 0, 1, 1],
5830			_blankArray = [],
5831			Ease = _class("easing.Ease", function(func, extraParams, type, power) {
5832				this._func = func;
5833				this._type = type || 0;
5834				this._power = power || 0;
5835				this._params = extraParams ? _baseParams.concat(extraParams) : _baseParams;
5836			}, true),
5837			_easeMap = Ease.map = {},
5838			_easeReg = Ease.register = function(ease, names, types, create) {
5839				var na = names.split(","),
5840					i = na.length,
5841					ta = (types || "easeIn,easeOut,easeInOut").split(","),
5842					e, name, j, type;
5843				while (--i > -1) {
5844					name = na[i];
5845					e = create ? _class("easing."+name, null, true) : gs.easing[name] || {};
5846					j = ta.length;
5847					while (--j > -1) {
5848						type = ta[j];
5849						_easeMap[name + "." + type] = _easeMap[type + name] = e[type] = ease.getRatio ? ease : ease[type] || new ease();
5850					}
5851				}
5852			};
5853
5854		p = Ease.prototype;
5855		p._calcEnd = false;
5856		p.getRatio = function(p) {
5857			if (this._func) {
5858				this._params[0] = p;
5859				return this._func.apply(null, this._params);
5860			}
5861			var t = this._type,
5862				pw = this._power,
5863				r = (t === 1) ? 1 - p : (t === 2) ? p : (p < 0.5) ? p * 2 : (1 - p) * 2;
5864			if (pw === 1) {
5865				r *= r;
5866			} else if (pw === 2) {
5867				r *= r * r;
5868			} else if (pw === 3) {
5869				r *= r * r * r;
5870			} else if (pw === 4) {
5871				r *= r * r * r * r;
5872			}
5873			return (t === 1) ? 1 - r : (t === 2) ? r : (p < 0.5) ? r / 2 : 1 - (r / 2);
5874		};
5875
5876		//create all the standard eases like Linear, Quad, Cubic, Quart, Quint, Strong, Power0, Power1, Power2, Power3, and Power4 (each with easeIn, easeOut, and easeInOut)
5877		a = ["Linear","Quad","Cubic","Quart","Quint,Strong"];
5878		i = a.length;
5879		while (--i > -1) {
5880			p = a[i]+",Power"+i;
5881			_easeReg(new Ease(null,null,1,i), p, "easeOut", true);
5882			_easeReg(new Ease(null,null,2,i), p, "easeIn" + ((i === 0) ? ",easeNone" : ""));
5883			_easeReg(new Ease(null,null,3,i), p, "easeInOut");
5884		}
5885		_easeMap.linear = gs.easing.Linear.easeIn;
5886		_easeMap.swing = gs.easing.Quad.easeInOut; //for jQuery folks
5887
5888
5889/*
5890 * ----------------------------------------------------------------
5891 * EventDispatcher
5892 * ----------------------------------------------------------------
5893 */
5894		var EventDispatcher = _class("events.EventDispatcher", function(target) {
5895			this._listeners = {};
5896			this._eventTarget = target || this;
5897		});
5898		p = EventDispatcher.prototype;
5899
5900		p.addEventListener = function(type, callback, scope, useParam, priority) {
5901			priority = priority || 0;
5902			var list = this._listeners[type],
5903				index = 0,
5904				listener, i;
5905			if (list == null) {
5906				this._listeners[type] = list = [];
5907			}
5908			i = list.length;
5909			while (--i > -1) {
5910				listener = list[i];
5911				if (listener.c === callback && listener.s === scope) {
5912					list.splice(i, 1);
5913				} else if (index === 0 && listener.pr < priority) {
5914					index = i + 1;
5915				}
5916			}
5917			list.splice(index, 0, {c:callback, s:scope, up:useParam, pr:priority});
5918			if (this === _ticker && !_tickerActive) {
5919				_ticker.wake();
5920			}
5921		};
5922
5923		p.removeEventListener = function(type, callback) {
5924			var list = this._listeners[type], i;
5925			if (list) {
5926				i = list.length;
5927				while (--i > -1) {
5928					if (list[i].c === callback) {
5929						list.splice(i, 1);
5930						return;
5931					}
5932				}
5933			}
5934		};
5935
5936		p.dispatchEvent = function(type) {
5937			var list = this._listeners[type],
5938				i, t, listener;
5939			if (list) {
5940				i = list.length;
5941				t = this._eventTarget;
5942				while (--i > -1) {
5943					listener = list[i];
5944					if (listener) {
5945						if (listener.up) {
5946							listener.c.call(listener.s || t, {type:type, target:t});
5947						} else {
5948							listener.c.call(listener.s || t);
5949						}
5950					}
5951				}
5952			}
5953		};
5954
5955
5956/*
5957 * ----------------------------------------------------------------
5958 * Ticker
5959 * ----------------------------------------------------------------
5960 */
5961 		var _reqAnimFrame = window.requestAnimationFrame,
5962			_cancelAnimFrame = window.cancelAnimationFrame,
5963			_getTime = Date.now || function() {return new Date().getTime();},
5964			_lastUpdate = _getTime();
5965
5966		//now try to determine the requestAnimationFrame and cancelAnimationFrame functions and if none are found, we'll use a setTimeout()/clearTimeout() polyfill.
5967		a = ["ms","moz","webkit","o"];
5968		i = a.length;
5969		while (--i > -1 && !_reqAnimFrame) {
5970			_reqAnimFrame = window[a[i] + "RequestAnimationFrame"];
5971			_cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"];
5972		}
5973
5974		_class("Ticker", function(fps, useRAF) {
5975			var _self = this,
5976				_startTime = _getTime(),
5977				_useRAF = (useRAF !== false && _reqAnimFrame),
5978				_lagThreshold = 500,
5979				_adjustedLag = 33,
5980				_tickWord = "tick", //helps reduce gc burden
5981				_fps, _req, _id, _gap, _nextTime,
5982				_tick = function(manual) {
5983					var elapsed = _getTime() - _lastUpdate,
5984						overlap, dispatch;
5985					if (elapsed > _lagThreshold) {
5986						_startTime += elapsed - _adjustedLag;
5987					}
5988					_lastUpdate += elapsed;
5989					_self.time = (_lastUpdate - _startTime) / 1000;
5990					overlap = _self.time - _nextTime;
5991					if (!_fps || overlap > 0 || manual === true) {
5992						_self.frame++;
5993						_nextTime += overlap + (overlap >= _gap ? 0.004 : _gap - overlap);
5994						dispatch = true;
5995					}
5996					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.
5997						_id = _req(_tick);
5998					}
5999					if (dispatch) {
6000						_self.dispatchEvent(_tickWord);
6001					}
6002				};
6003
6004			EventDispatcher.call(_self);
6005			_self.time = _self.frame = 0;
6006			_self.tick = function() {
6007				_tick(true);
6008			};
6009
6010			_self.lagSmoothing = function(threshold, adjustedLag) {
6011				_lagThreshold = threshold || (1 / _tinyNum); //zero should be interpreted as basically unlimited
6012				_adjustedLag = Math.min(adjustedLag, _lagThreshold, 0);
6013			};
6014
6015			_self.sleep = function() {
6016				if (_id == null) {
6017					return;
6018				}
6019				if (!_useRAF || !_cancelAnimFrame) {
6020					clearTimeout(_id);
6021				} else {
6022					_cancelAnimFrame(_id);
6023				}
6024				_req = _emptyFunc;
6025				_id = null;
6026				if (_self === _ticker) {
6027					_tickerActive = false;
6028				}
6029			};
6030
6031			_self.wake = function() {
6032				if (_id !== null) {
6033					_self.sleep();
6034				} 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().
6035					_lastUpdate = _getTime() - _lagThreshold + 5;
6036				}
6037				_req = (_fps === 0) ? _emptyFunc : (!_useRAF || !_reqAnimFrame) ? function(f) { return setTimeout(f, ((_nextTime - _self.time) * 1000 + 1) | 0); } : _reqAnimFrame;
6038				if (_self === _ticker) {
6039					_tickerActive = true;
6040				}
6041				_tick(2);
6042			};
6043
6044			_self.fps = function(value) {
6045				if (!arguments.length) {
6046					return _fps;
6047				}
6048				_fps = value;
6049				_gap = 1 / (_fps || 60);
6050				_nextTime = this.time + _gap;
6051				_self.wake();
6052			};
6053
6054			_self.useRAF = function(value) {
6055				if (!arguments.length) {
6056					return _useRAF;
6057				}
6058				_self.sleep();
6059				_useRAF = value;
6060				_self.fps(_fps);
6061			};
6062			_self.fps(fps);
6063
6064			//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.
6065			setTimeout(function() {
6066				if (_useRAF && _self.frame < 5) {
6067					_self.useRAF(false);
6068				}
6069			}, 1500);
6070		});
6071
6072		p = gs.Ticker.prototype = new gs.events.EventDispatcher();
6073		p.constructor = gs.Ticker;
6074
6075
6076/*
6077 * ----------------------------------------------------------------
6078 * Animation
6079 * ----------------------------------------------------------------
6080 */
6081		var Animation = _class("core.Animation", function(duration, vars) {
6082				this.vars = vars = vars || {};
6083				this._duration = this._totalDuration = duration || 0;
6084				this._delay = Number(vars.delay) || 0;
6085				this._timeScale = 1;
6086				this._active = (vars.immediateRender === true);
6087				this.data = vars.data;
6088				this._reversed = (vars.reversed === true);
6089
6090				if (!_rootTimeline) {
6091					return;
6092				}
6093				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.
6094					_ticker.wake();
6095				}
6096
6097				var tl = this.vars.useFrames ? _rootFramesTimeline : _rootTimeline;
6098				tl.add(this, tl._time);
6099
6100				if (this.vars.paused) {
6101					this.paused(true);
6102				}
6103			});
6104
6105		_ticker = Animation.ticker = new gs.Ticker();
6106		p = Animation.prototype;
6107		p._dirty = p._gc = p._initted = p._paused = false;
6108		p._totalTime = p._time = 0;
6109		p._rawPrevTime = -1;
6110		p._next = p._last = p._onUpdate = p._timeline = p.timeline = null;
6111		p._paused = false;
6112
6113
6114		//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.
6115		var _checkTimeout = function() {
6116				if (_tickerActive && _getTime() - _lastUpdate > 2000) {
6117					_ticker.wake();
6118				}
6119				setTimeout(_checkTimeout, 2000);
6120			};
6121		_checkTimeout();
6122
6123
6124		p.play = function(from, suppressEvents) {
6125			if (from != null) {
6126				this.seek(from, suppressEvents);
6127			}
6128			return this.reversed(false).paused(false);
6129		};
6130
6131		p.pause = function(atTime, suppressEvents) {
6132			if (atTime != null) {
6133				this.seek(atTime, suppressEvents);
6134			}
6135			return this.paused(true);
6136		};
6137
6138		p.resume = function(from, suppressEvents) {
6139			if (from != null) {
6140				this.seek(from, suppressEvents);
6141			}
6142			return this.paused(false);
6143		};
6144
6145		p.seek = function(time, suppressEvents) {
6146			return this.totalTime(Number(time), suppressEvents !== false);
6147		};
6148
6149		p.restart = function(includeDelay, suppressEvents) {
6150			return this.reversed(false).paused(false).totalTime(includeDelay ? -this._delay : 0, (suppressEvents !== false), true);
6151		};
6152
6153		p.reverse = function(from, suppressEvents) {
6154			if (from != null) {
6155				this.seek((from || this.totalDuration()), suppressEvents);
6156			}
6157			return this.reversed(true).paused(false);
6158		};
6159
6160		p.render = function(time, suppressEvents, force) {
6161			//stub - we override this method in subclasses.
6162		};
6163
6164		p.invalidate = function() {
6165			this._time = this._totalTime = 0;
6166			this._initted = this._gc = false;
6167			this._rawPrevTime = -1;
6168			if (this._gc || !this.timeline) {
6169				this._enabled(true);
6170			}
6171			return this;
6172		};
6173
6174		p.isActive = function() {
6175			var tl = this._timeline, //the 2 root timelines won't have a _timeline; they're always active.
6176				startTime = this._startTime,
6177				rawTime;
6178			return (!tl || (!this._gc && !this._paused && tl.isActive() && (rawTime = tl.rawTime()) >= startTime && rawTime < startTime + this.totalDuration() / this._timeScale));
6179		};
6180
6181		p._enabled = function (enabled, ignoreTimeline) {
6182			if (!_tickerActive) {
6183				_ticker.wake();
6184			}
6185			this._gc = !enabled;
6186			this._active = this.isActive();
6187			if (ignoreTimeline !== true) {
6188				if (enabled && !this.timeline) {
6189					this._timeline.add(this, this._startTime - this._delay);
6190				} else if (!enabled && this.timeline) {
6191					this._timeline._remove(this, true);
6192				}
6193			}
6194			return false;
6195		};
6196
6197
6198		p._kill = function(vars, target) {
6199			return this._enabled(false, false);
6200		};
6201
6202		p.kill = function(vars, target) {
6203			this._kill(vars, target);
6204			return this;
6205		};
6206
6207		p._uncache = function(includeSelf) {
6208			var tween = includeSelf ? this : this.timeline;
6209			while (tween) {
6210				tween._dirty = true;
6211				tween = tween.timeline;
6212			}
6213			return this;
6214		};
6215
6216		p._swapSelfInParams = function(params) {
6217			var i = params.length,
6218				copy = params.concat();
6219			while (--i > -1) {
6220				if (params[i] === "{self}") {
6221					copy[i] = this;
6222				}
6223			}
6224			return copy;
6225		};
6226
6227		p._callback = function(type) {
6228			var v = this.vars;
6229			v[type].apply(v[type + "Scope"] || v.callbackScope || this, v[type + "Params"] || _blankArray);
6230		};
6231
6232//----Animation getters/setters --------------------------------------------------------
6233
6234		p.eventCallback = function(type, callback, params, scope) {
6235			if ((type || "").substr(0,2) === "on") {
6236				var v = this.vars;
6237				if (arguments.length === 1) {
6238					return v[type];
6239				}
6240				if (callback == null) {
6241					delete v[type];
6242				} else {
6243					v[type] = callback;
6244					v[type + "Params"] = (_isArray(params) && params.join("").indexOf("{self}") !== -1) ? this._swapSelfInParams(params) : params;
6245					v[type + "Scope"] = scope;
6246				}
6247				if (type === "onUpdate") {
6248					this._onUpdate = callback;
6249				}
6250			}
6251			return this;
6252		};
6253
6254		p.delay = function(value) {
6255			if (!arguments.length) {
6256				return this._delay;
6257			}
6258			if (this._timeline.smoothChildTiming) {
6259				this.startTime( this._startTime + value - this._delay );
6260			}
6261			this._delay = value;
6262			return this;
6263		};
6264
6265		p.duration = function(value) {
6266			if (!arguments.length) {
6267				this._dirty = false;
6268				return this._duration;
6269			}
6270			this._duration = this._totalDuration = value;
6271			this._uncache(true); //true in case it's a TweenMax or TimelineMax that has a repeat - we'll need to refresh the totalDuration.
6272			if (this._timeline.smoothChildTiming) if (this._time > 0) if (this._time < this._duration) if (value !== 0) {
6273				this.totalTime(this._totalTime * (value / this._duration), true);
6274			}
6275			return this;
6276		};
6277
6278		p.totalDuration = function(value) {
6279			this._dirty = false;
6280			return (!arguments.length) ? this._totalDuration : this.duration(value);
6281		};
6282
6283		p.time = function(value, suppressEvents) {
6284			if (!arguments.length) {
6285				return this._time;
6286			}
6287			if (this._dirty) {
6288				this.totalDuration();
6289			}
6290			return this.totalTime((value > this._duration) ? this._duration : value, suppressEvents);
6291		};
6292
6293		p.totalTime = function(time, suppressEvents, uncapped) {
6294			if (!_tickerActive) {
6295				_ticker.wake();
6296			}
6297			if (!arguments.length) {
6298				return this._totalTime;
6299			}
6300			if (this._timeline) {
6301				if (time < 0 && !uncapped) {
6302					time += this.totalDuration();
6303				}
6304				if (this._timeline.smoothChildTiming) {
6305					if (this._dirty) {
6306						this.totalDuration();
6307					}
6308					var totalDuration = this._totalDuration,
6309						tl = this._timeline;
6310					if (time > totalDuration && !uncapped) {
6311						time = totalDuration;
6312					}
6313					this._startTime = (this._paused ? this._pauseTime : tl._time) - ((!this._reversed ? time : totalDuration - time) / this._timeScale);
6314					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.
6315						this._uncache(false);
6316					}
6317					//in case any of the ancestor timelines had completed but should now be enabled, we should reset the
6317ir 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.
6318					if (tl._timeline) {
6319						while (tl._timeline) {
6320							if (tl._timeline._time !== (tl._startTime + tl._totalTime) / tl._timeScale) {
6321								tl.totalTime(tl._totalTime, true);
6322							}
6323							tl = tl._timeline;
6324						}
6325					}
6326				}
6327				if (this._gc) {
6328					this._enabled(true, false);
6329				}
6330				if (this._totalTime !== time || this._duration === 0) {
6331					if (_lazyTweens.length) {
6332						_lazyRender();
6333					}
6334					this.render(time, suppressEvents, false);
6335					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.
6336						_lazyRender();
6337					}
6338				}
6339			}
6340			return this;
6341		};
6342
6343		p.progress = p.totalProgress = function(value, suppressEvents) {
6344			var duration = this.duration();
6345			return (!arguments.length) ? (duration ? this._time / duration : this.ratio) : this.totalTime(duration * value, suppressEvents);
6346		};
6347
6348		p.startTime = function(value) {
6349			if (!arguments.length) {
6350				return this._startTime;
6351			}
6352			if (value !== this._startTime) {
6353				this._startTime = value;
6354				if (this.timeline) if (this.timeline._sortChildren) {
6355					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.
6356				}
6357			}
6358			return this;
6359		};
6360
6361		p.endTime = function(includeRepeats) {
6362			return this._startTime + ((includeRepeats != false) ? this.totalDuration() : this.duration()) / this._timeScale;
6363		};
6364
6365		p.timeScale = function(value) {
6366			if (!arguments.length) {
6367				return this._timeScale;
6368			}
6369			value = value || _tinyNum; //can't allow zero because it'll throw the math off
6370			if (this._timeline && this._timeline.smoothChildTiming) {
6371				var pauseTime = this._pauseTime,
6372					t = (pauseTime || pauseTime === 0) ? pauseTime : this._timeline.totalTime();
6373				this._startTime = t - ((t - this._startTime) * this._timeScale / value);
6374			}
6375			this._timeScale = value;
6376			return this._uncache(false);
6377		};
6378
6379		p.reversed = function(value) {
6380			if (!arguments.length) {
6381				return this._reversed;
6382			}
6383			if (value != this._reversed) {
6384				this._reversed = value;
6385				this.totalTime(((this._timeline && !this._timeline.smoothChildTiming) ? this.totalDuration() - this._totalTime : this._totalTime), true);
6386			}
6387			return this;
6388		};
6389
6390		p.paused = function(value) {
6391			if (!arguments.length) {
6392				return this._paused;
6393			}
6394			var tl = this._timeline,
6395				raw, elapsed;
6396			if (value != this._paused) if (tl) {
6397				if (!_tickerActive && !value) {
6398					_ticker.wake();
6399				}
6400				raw = tl.rawTime();
6401				elapsed = raw - this._pauseTime;
6402				if (!value && tl.smoothChildTiming) {
6403					this._startTime += elapsed;
6404					this._uncache(false);
6405				}
6406				this._pauseTime = value ? raw : null;
6407				this._paused = value;
6408				this._active = this.isActive();
6409				if (!value && elapsed !== 0 && this._initted && this.duration()) {
6410					raw = tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale;
6411					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.
6412				}
6413			}
6414			if (this._gc && !value) {
6415				this._enabled(true, false);
6416			}
6417			return this;
6418		};
6419
6420
6421/*
6422 * ----------------------------------------------------------------
6423 * SimpleTimeline
6424 * ----------------------------------------------------------------
6425 */
6426		var SimpleTimeline = _class("core.SimpleTimeline", function(vars) {
6427			Animation.call(this, 0, vars);
6428			this.autoRemoveChildren = this.smoothChildTiming = true;
6429		});
6430
6431		p = SimpleTimeline.prototype = new Animation();
6432		p.constructor = SimpleTimeline;
6433		p.kill()._gc = false;
6434		p._first = p._last = p._recent = null;
6435		p._sortChildren = false;
6436
6437		p.add = p.insert = function(child, position, align, stagger) {
6438			var prevTween, st;
6439			child._startTime = Number(position || 0) + child._delay;
6440			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).
6441				child._pauseTime = child._startTime + ((this.rawTime() - child._startTime) / child._timeScale);
6442			}
6443			if (child.timeline) {
6444				child.timeline._remove(child, true); //removes from existing timeline so that it can be properly added to this one.
6445			}
6446			child.timeline = child._timeline = this;
6447			if (child._gc) {
6448				child._enabled(true, true);
6449			}
6450			prevTween = this._last;
6451			if (this._sortChildren) {
6452				st = child._startTime;
6453				while (prevTween && prevTween._startTime > st) {
6454					prevTween = prevTween._prev;
6455				}
6456			}
6457			if (prevTween) {
6458				child._next = prevTween._next;
6459				prevTween._next = child;
6460			} else {
6461				child._next = this._first;
6462				this._first = child;
6463			}
6464			if (child._next) {
6465				child._next._prev = child;
6466			} else {
6467				this._last = child;
6468			}
6469			child._prev = prevTween;
6470			this._recent = child;
6471			if (this._timeline) {
6472				this._uncache(true);
6473			}
6474			return this;
6475		};
6476
6477		p._remove = function(tween, skipDisable) {
6478			if (tween.timeline === this) {
6479				if (!skipDisable) {
6480					tween._enabled(false, true);
6481				}
6482
6483				if (tween._prev) {
6484					tween._prev._next = tween._next;
6485				} else if (this._first === tween) {
6486					this._first = tween._next;
6487				}
6488				if (tween._next) {
6489					tween._next._prev = tween._prev;
6490				} else if (this._last === tween) {
6491					this._last = tween._prev;
6492				}
6493				tween._next = tween._prev = tween.timeline = null;
6494				if (tween === this._recent) {
6495					this._recent = this._last;
6496				}
6497
6498				if (this._timeline) {
6499					this._uncache(true);
6500				}
6501			}
6502			return this;
6503		};
6504
6505		p.render = function(time, suppressEvents, force) {
6506			var tween = this._first,
6507				next;
6508			this._totalTime = this._time = this._rawPrevTime = time;
6509			while (tween) {
6510				next = tween._next; //record it here because the value could change after rendering...
6511				if (tween._active || (time >= tween._startTime && !tween._paused)) {
6512					if (!tween._reversed) {
6513						tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
6514					} else {
6515						tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force);
6516					}
6517				}
6518				tween = next;
6519			}
6520		};
6521
6522		p.rawTime = function() {
6523			if (!_tickerActive) {
6524				_ticker.wake();
6525			}
6526			return this._totalTime;
6527		};
6528
6529/*
6530 * ----------------------------------------------------------------
6531 * TweenLite
6532 * ----------------------------------------------------------------
6533 */
6534		var TweenLite = _class("TweenLite", function(target, duration, vars) {
6535				Animation.call(this, duration, vars);
6536				this.render = TweenLite.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method)
6537
6538				if (target == null) {
6539					throw "Cannot tween a null target.";
6540				}
6541
6542				this.target = target = (typeof(target) !== "string") ? target : TweenLite.selector(target) || target;
6543
6544				var isSelector = (target.jquery || (target.length && target !== window && target[0] && (target[0] === window || (target[0].nodeType && target[0].style && !target.nodeType)))),
6545					overwrite = this.vars.overwrite,
6546					i, targ, targets;
6547
6548				this._overwrite = overwrite = (overwrite == null) ? _overwriteLookup[TweenLite.defaultOverwrite] : (typeof(overwrite) === "number") ? overwrite >> 0 : _overwriteLookup[overwrite];
6549
6550				if ((isSelector || target instanceof Array || (target.push && _isArray(target))) && typeof(target[0]) !== "number") {
6551					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()
6552					this._propLookup = [];
6553					this._siblings = [];
6554					for (i = 0; i < targets.length; i++) {
6555						targ = targets[i];
6556						if (!targ) {
6557							targets.splice(i--, 1);
6558							continue;
6559						} else if (typeof(targ) === "string") {
6560							targ = targets[i--] = TweenLite.selector(targ);
6560 //in case it's an array of strings
6561							if (typeof(targ) === "string") {
6562								targets.splice(i+1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case)
6563							}
6564							continue;
6565						} 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.
6566							targets.splice(i--, 1);
6567							this._targets = targets = targets.concat(_slice(targ));
6568							continue;
6569						}
6570						this._siblings[i] = _register(targ, this, false);
6571						if (overwrite === 1) if (this._siblings[i].length > 1) {
6572							_applyOverwrite(targ, this, null, 1, this._siblings[i]);
6573						}
6574					}
6575
6576				} else {
6577					this._propLookup = {};
6578					this._siblings = _register(target, this, false);
6579					if (overwrite === 1) if (this._siblings.length > 1) {
6580						_applyOverwrite(target, this, null, 1, this._siblings);
6581					}
6582				}
6583				if (this.vars.immediateRender || (duration === 0 && this._delay === 0 && this.vars.immediateRender !== false)) {
6584					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)
6585					this.render(-this._delay);
6586				}
6587			}, true),
6588			_isSelector = function(v) {
6589				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.
6590			},
6591			_autoCSS = function(vars, target) {
6592				var css = {},
6593					p;
6594				for (p in vars) {
6595					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.
6596						css[p] = vars[p];
6597						delete vars[p];
6598					}
6599				}
6600				vars.css = css;
6601			};
6602
6603		p = TweenLite.prototype = new Animation();
6604		p.constructor = TweenLite;
6605		p.kill()._gc = false;
6606
6607//----TweenLite defaults, overwrite management, and root updates ----------------------------------------------------
6608
6609		p.ratio = 0;
6610		p._firstPT = p._targets = p._overwrittenProps = p._startAt = null;
6611		p._notifyPluginsOfEnabled = p._lazy = false;
6612
6613		TweenLite.version = "1.18.0";
6614		TweenLite.defaultEase = p._ease = new Ease(null, null, 1, 1);
6615		TweenLite.defaultOverwrite = "auto";
6616		TweenLite.ticker = _ticker;
6617		TweenLite.autoSleep = 120;
6618		TweenLite.lagSmoothing = function(threshold, adjustedLag) {
6619			_ticker.lagSmoothing(threshold, adjustedLag);
6620		};
6621
6622		TweenLite.selector = window.$ || window.jQuery || function(e) {
6623			var selector = window.$ || window.jQuery;
6624			if (selector) {
6625				TweenLite.selector = selector;
6626				return selector(e);
6627			}
6628			return (typeof(document) === "undefined") ? e : (document.querySelectorAll ? document.querySelectorAll(e) : document.getElementById((e.charAt(0) === "#") ? e.substr(1) : e));
6629		};
6630
6631		var _lazyTweens = [],
6632			_lazyLookup = {},
6633			_numbersExp = /(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig,
6634			//_nonNumbersExp = /(?:([\-+](?!(\d|=)))|[^\d\-+=e]|(e(?![\-+][\d])))+/ig,
6635			_setRatio = function(v) {
6636				var pt = this._firstPT,
6637					min = 0.000001,
6638					val;
6639				while (pt) {
6640					val = !pt.blob ? pt.c * v + pt.s : v ? this.join("") : this.start;
6641					if (pt.r) {
6642						val = Math.round(val);
6643					} else if (val < min) if (val > -min) { //prevents issues with converting very small numbers to strings in the browser
6644						val = 0;
6645					}
6646					if (!pt.f) {
6647						pt.t[pt.p] = val;
6648					} else if (pt.fp) {
6649						pt.t[pt.p](pt.fp, val);
6650					} else {
6651						pt.t[pt.p](val);
6652					}
6653					pt = pt._next;
6654				}
6655			},
6656			//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("")).
6657			_blobDif = function(start, end, filter, pt) {
6658				var a = [start, end],
6659					charIndex = 0,
6660					s = "",
6661					color = 0,
6662					startNums, endNums, num, i, l, nonNumbers, currentNum;
6663				a.start = start;
6664				if (filter) {
6665					filter(a); //pass an array with the starting and ending values and let the filter do whatever it needs to the values.
6666					start = a[0];
6667					end = a[1];
6668				}
6669				a.length = 0;
6670				startNums = start.match(_numbersExp) || [];
6671				endNums = end.match(_numbersExp) || [];
6672				if (pt) {
6673					pt._next = null;
6674					pt.blob = 1;
6675					a._firstPT = pt; //apply last in the linked list (which means inserting it first)
6676				}
6677				l = endNums.length;
6678				for (i = 0; i < l; i++) {
6679					currentNum = endNums[i];
6680					nonNumbers = end.substr(charIndex, end.indexOf(currentNum, charIndex)-charIndex);
6681					s += (nonNumbers || !i) ? nonNumbers : ",";
6681 //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.
6682					charIndex += nonNumbers.length;
6683					if (color) { //sense rgba() values and round them.
6684						color = (color + 1) % 5;
6685					} else if (nonNumbers.substr(-5) === "rgba(") {
6686						color = 1;
6687					}
6688					if (currentNum === startNums[i] || startNums.length <= i) {
6689						s += currentNum;
6690					} else {
6691						if (s) {
6692							a.push(s);
6693							s = "";
6694						}
6695						num = parseFloat(startNums[i]);
6696						a.push(num);
6697						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, r:(color && color < 4)};
6698						//note: we don't set _prev because we'll never need to remove individual PropTweens from this list.
6699					}
6700					charIndex += currentNum.length;
6701				}
6702				s += end.substr(charIndex);
6703				if (s) {
6704					a.push(s);
6705				}
6706				a.setRatio = _setRatio;
6707				return a;
6708			},
6709			//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.
6710			_addPropTween = function(target, prop, start, end, overwriteProp, round, funcParam, stringFilter) {
6711				var s = (start === "get") ? target[prop] : start,
6712					type = typeof(target[prop]),
6713					isRelative = (typeof(end) === "string" && end.charAt(1) === "="),
6714					pt = {t:target, p:prop, s:s, f:(type === "function"), pg:0, n:overwriteProp || prop, r:round, pr:0, c:isRelative ? parseInt(end.charAt(0) + "1", 10) * parseFloat(end.substr(2)) : (parseFloat(end) - s) || 0},
6715					blob, getterName;
6716				if (type !== "number") {
6717					if (type === "function" && start === "get") {
6718						getterName = ((prop.indexOf("set") || typeof(target["get" + prop.substr(3)]) !== "function") ? prop : "get" + prop.substr(3));
6719						pt.s = s = funcParam ? target[getterName](funcParam) : target[getterName]();
6720					}
6721					if (typeof(s) === "string" && (funcParam || isNaN(s))) {
6722						//a blob (string that has multiple numbers in it)
6723						pt.fp = funcParam;
6724						blob = _blobDif(s, end, stringFilter || TweenLite.defaultStringFilter, pt);
6725						pt = {t:blob, p:"setRatio", s:0, c:1, f:2, pg:0, n:overwriteProp || prop, pr:0}; //"2" indicates it's a Blob property tween. Needed for RoundPropsPlugin for example.
6726					} else if (!isRelative) {
6727						pt.c = (parseFloat(end) - parseFloat(s)) || 0;
6728					}
6729				}
6730				if (pt.c) { //only add it to the linked list if there's a change.
6731					if ((pt._next = this._firstPT)) {
6732						pt._next._prev = pt;
6733					}
6734					this._firstPT = pt;
6735					return pt;
6736				}
6737			},
6738			_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.
6739			_plugins = TweenLite._plugins = {},
6740			_tweenLookup = _internals.tweenLookup = {},
6741			_tweenLookupNum = 0,
6742			_reservedProps = _internals.reservedProps = {ease:1, delay:1, overwrite:1, onComplete:1, onCompleteParams:1, onCompleteScope:1, useFrames:1, runBackwards:1, startAt:1, onUpdate: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},
6743			_overwriteLookup = {none:0, all:1, auto:2, concurrent:3, allOnStart:4, preexisting:5, "true":1, "false":0},
6744			_rootFramesTimeline = Animation._rootFramesTimeline = new SimpleTimeline(),
6745			_rootTimeline = Animation._rootTimeline = new SimpleTimeline(),
6746			_nextGCFrame = 30,
6747			_lazyRender = _internals.lazyRender = function() {
6748				var i = _lazyTweens.length,
6749					tween;
6750				_lazyLookup = {};
6751				while (--i > -1) {
6752					tween = _lazyTweens[i];
6753					if (tween && tween._lazy !== false) {
6754						tween.render(tween._lazy[0], tween._lazy[1], true);
6755						tween._lazy = false;
6756					}
6757				}
6758				_lazyTweens.length = 0;
6759			};
6760
6761		_rootTimeline._startTime = _ticker.time;
6762		_rootFramesTimeline._startTime = _ticker.frame;
6763		_rootTimeline._active = _rootFramesTimeline._active = true;
6764		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".
6765
6766		Animation._updateRoot = TweenLite.render = function() {
6767				var i, a, p;
6768				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.
6769					_lazyRender();
6770				}
6771				_rootTimeline.render((_ticker.time - _rootTimeline._startTime) * _rootTimeline._timeScale, false, false);
6772				_rootFramesTimeline.render((_ticker.frame - _rootFramesTimeline._startTime) * _rootFramesTimeline._timeScale, false, false);
6773				if (_lazyTweens.length) {
6774					_lazyRender();
6775				}
6776				if (_ticker.frame >= _nextGCFrame) { //dump garbage every 120 frames or whatever the user sets TweenLite.autoSleep to
6777					_nextGCFrame = _ticker.frame + (parseInt(TweenLite.autoSleep, 10) || 120);
6778					for (p in _tweenLookup) {
6779						a = _tweenLookup[p].tweens;
6780						i = a.length;
6781						while (--i > -1) {
6782							if (a[i]._gc) {
6783								a.splice(i, 1);
6784							}
6785						}
6786						if (a.length === 0) {
6787							delete _tweenLookup[p];
6788						}
6789					}
6790					//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
6791					p = _rootTimeline._first;
6792					if (!p || p._paused) if (TweenLite.autoSleep && !_rootFramesTimeline._first && _ticker._listeners.tick.length === 1) {
6793						while (p && p._paused) {
6794							p = p._next;
6795						}
6796						if (!p) {
6797							_ticker.sleep();
6798						}
6799					}
6800				}
6801			};
6802
6803		_ticker.addEventListener("tick", Animation._updateRoot);
6804
6805		var _register = function(target, tween, scrub) {
6806				var id = target._gsTweenID, a, i;
6807				if (!_tweenLookup[id || (target._gsTweenID = id = "t" + (_tweenLookupNum++))]) {
6808					_tweenLookup[id] = {target:target, tweens:[]};
6809				}
6810				if (tween) {
6811					a = _tweenLookup[id].tweens;
6812					a[(i = a.length)] = tween;
6813					if (scrub) {
6814						while (--i > -1) {
6815							if (a[i] === tween) {
6816								a.splice(i, 1);
6817							}
6818						}
6819					}
6820				}
6821				return _tweenLookup[id].tweens;
6822			},
6823			_onOverwrite = function(overwrittenTween, overwritingTween, target, killedProps) {
6824				var func = overwrittenTween.vars.onOverwrite, r1, r2;
6825				if (func) {
6826					r1 = func(overwrittenTween, overwritingTween, target, killedProps);
6827				}
6828				func = TweenLite.onOverwrite;
6829				if (func) {
6830					r2 = func(overwrittenTween, overwritingTween, target, killedProps);
6831				}
6832				return (r1 !== false && r2 !== false);
6833			},
6834			_applyOverwrite = function(target, tween, props, mode, siblings) {
6835				var i, changed, curTween, l;
6836				if (mode === 1 || mode >= 4) {
6837					l = siblings.length;
6838					for (i = 0; i < l; i++) {
6839						if ((curTween = siblings[i]) !== tween) {
6840							if (!curTween._gc) {
6841								if (curTween._kill(null, target, tween)) {
6842									changed = true;
6843								}
6844							}
6845						} else if (mode === 5) {
6846							break;
6847						}
6848					}
6849					return changed;
6850				}
6851				//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)
6852				var startTime = tween._startTime + _tinyNum,
6853					overlaps = [],
6854					oCount = 0,
6855					zeroDur = (tween._duration === 0),
6856					globalStart;
6857				i = siblings.length;
6858				while (--i > -1) {
6859					if ((curTween = siblings[i]) === tween || curTween._gc || curTween._paused) {
6860						//ignore
6861					} else if (curTween._timeline !== tween._timeline) {
6862						globalStart = globalStart || _checkOverlap(tween, 0, zeroDur);
6863						if (_checkOverlap(curTween, globalStart, zeroDur) === 0) {
6864							overlaps[oCount++] = curTween;
6865						}
6866					} else if (curTween._startTime <= startTime) if (curTween._startTime + curTween.totalDuration() / curTween._timeScale > startTime) if (!((zeroDur || !curTween._initted) && startTime - curTween._startTime <= 0.0000000002)) {
6867						overlaps[oCount++] = curTween;
6868					}
6869				}
6870
6871				i = oCount;
6872				while (--i > -1) {
6873					curTween = overlaps[i];
6874					if (mode === 2) if (curTween._kill(props, target, tween)) {
6875						changed = true;
6876					}
6877					if (mode !== 2 || (!curTween._firstPT && curTween._initted)) {
6878						if (mode !== 2 && !_onOverwrite(curTween, tween)) {
6879							continue;
6880						}
6881						if (curTween._enabled(false, false)) { //if all property tweens have been overwritten, kill the tween.
6882							changed = true;
6883						}
6884					}
6885				}
6886				return changed;
6887			},
6888			_checkOverlap = function(tween, reference, zeroDur) {
6889				var tl = tween._timeline,
6890					ts = tl._timeScale,
6891					t = tween._startTime;
6892				while (tl._timeline) {
6893					t += tl._startTime;
6894					ts *= tl._timeScale;
6895					if (tl._paused) {
6896						return -100;
6897					}
6898					tl = tl._timeline;
6899				}
6900				t /= ts;
6901				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;
6902			};
6903
6904
6905//---- TweenLite instance methods -----------------------------------------------------------------------------
6906
6907		p._init = function() {
6908			var v = this.vars,
6909				op = this._overwrittenProps,
6910				dur = this._duration,
6911				immediate = !!v.immediateRender,
6912				ease = v.ease,
6913				i, initPlugins, pt, p, startVars;
6914			if (v.startAt) {
6915				if (this._startAt) {
6916					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.
6917					this._startAt.kill();
6918				}
6919				startVars = {};
6920				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);
6921					startVars[p] = v.startAt[p];
6922				}
6923				startVars.overwrite = false;
6924				startVars.immediateRender = true;
6925				startVars.lazy = (immediate && v.lazy !== false);
6926				startVars.startAt = startVars.delay = null; //no nesting of startAt objects allowed (otherwise it could cause an infinite loop).
6927				this._startAt = TweenLite.to(this.target, 0, startVars);
6928				if (immediate) {
6929					if (this._time > 0) {
6930						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()).
6931					} else if (dur !== 0) {
6932						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.
6933					}
6934				}
6935			} else if (v.runBackwards && dur !== 0) {
6936				//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)
6937				if (this._startAt) {
6938					this._startAt.render(-1, true);
6939					this._startAt.kill();
6940					this._startAt = null;
6941				} else {
6942					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
6943						immediate = false;
6944					}
6945					pt = {};
6946					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.
6947						if (!_reservedProps[p] || p === "autoCSS") {
6948							pt[p] = v[p];
6949						}
6950					}
6951					pt.overwrite = 0;
6952					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.
6953					pt.lazy = (immediate && v.lazy !== false);
6954					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)
6955					this._startAt = TweenLite.to(this.target, 0, pt);
6956					if (!immediate) {
6957						this._startAt._init(); //ensures that the initial values are recorded
6958						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.
6959						if (this.vars.immediateRender) {
6960							this._startAt = null;
6961						}
6962					} else if (this._time === 0) {
6963						return;
6964					}
6965				}
6966			}
6967			this._ease = ease = (!ease) ? TweenLite.defaultEase : (ease instanceof Ease) ? ease : (typeof(ease) === "function") ? new Ease(ease, v.easeParams) : _easeMap[ease] || TweenLite.defaultEase;
6968			if (v.easeParams instanceof Array && ease.config) {
6969				this._ease = ease.config.apply(ease, v.easeParams);
6970			}
6971			this._easeType = this._ease._type;
6972			this._easePower = this._ease._power;
6973			this._firstPT = null;
6974
6975			if (this._targets) {
6976				i = this._targets.length;
6977				while (--i > -1) {
6978					if ( this._initProps( this._targets[i], (this._propLookup[i] = {}), this._siblings[i], (op ? op[i] : null)) ) {
6979						initPlugins = true;
6980					}
6981				}
6982			} else {
6983				initPlugins = this._initProps(this.target, this._propLookup, this._siblings, op);
6984			}
6985
6986			if (initPlugins) {
6987				TweenLite._onPluginEvent("_onInitAllProps", this); //reorders the array in order of priority. Uses a static TweenPlugin method in order to minimize file size in TweenLite
6988			}
6989			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.
6990				this._enabled(false, false);
6991			}
6992			if (v.runBackwards) {
6993				pt = this._firstPT;
6994				while (pt) {
6995					pt.s += pt.c;
6996					pt.c = -pt.c;
6997					pt = pt._next;
6998				}
6999			}
7000			this._onUpdate = v.onUpdate;
7001			this._initted = true;
7002		};
7003
7004		p._initProps = function(target, propLookup, siblings, overwrittenProps) {
7005			var p, i, initPlugins, plugin, pt, v;
7006			if (target == null) {
7007				return false;
7008			}
7009
7010			if (_lazyLookup[target._gsTweenID]) {
7011				_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)
7012			}
7013
7014			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.
7015				_autoCSS(this.vars, target);
7016			}
7017			for (p in this.vars) {
7018				v = this.vars[p];
7019				if (_reservedProps[p]) {
7020					if (v) if ((v instanceof Array) || (v.push && _isArray(v))) if (v.join("").indexOf("{self}") !== -1) {
7021						this.vars[p] = v = this._swapSelfInParams(v, this);
7022					}
7023
7024				} else if (_plugins[p] && (plugin = new _plugins[p]())._onInitTween(target, this.vars[p], this)) {
7025
7026					//t - target 		[object]
7027					//p - property 		[string]
7028					//s - start			[number]
7029					//c - change		[number]
7030					//f - isFunction	[boolean]
7031					//n - name			[string]
7032					//pg - isPlugin 	[boolean]
7033					//pr - priority		[number]
7034					this._firstPT = pt = {_next:this._firstPT, t:plugin, p:"setRatio", s:0, c:1, f:1, n:p, pg:1, pr:plugin._priority};
7035					i = plugin._overwriteProps.length;
7036					while (--i > -1) {
7037						propLookup[plugin._overwriteProps[i]] = this._firstPT;
7038					}
7039					if (plugin._priority || plugin._onInitAllProps) {
7040						initPlugins = true;
7041					}
7042					if (plugin._onDisable || plugin._onEnable) {
7043						this._notifyPluginsOfEnabled = true;
7044					}
7045					if (pt._next) {
7046						pt._next._prev = pt;
7047					}
7048
7049				} else {
7050					propLookup[p] = _addPropTween.call(this, target, p, "get", v, p, 0, null, this.vars.stringFilter);
7051				}
7052			}
7053
7054			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)
7055				return this._initProps(target, propLookup, siblings, overwrittenProps);
7056			}
7057			if (this._overwrite > 1) if (this._firstPT) if (siblings.length > 1) if (_applyOverwrite(target, this, propLookup, this._overwrite, siblings)) {
7058				this._kill(propLookup, target);
7059				return this._initProps(target, propLookup, siblings, overwrittenProps);
7060			}
7061			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.
7062				_lazyLookup[target._gsTweenID] = true;
7063			}
7064			return initPlugins;
7065		};
7066
7067		p.render = function(time, suppressEvents, force) {
7068			var prevTime = this._time,
7069				duration = this._duration,
7070				prevRawPrevTime = this._rawPrevTime,
7071				isComplete, callback, pt, rawPrevTime;
7072			if (time >= duration) {
7073				this._totalTime = this._time = duration;
7074				this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1;
7075				if (!this._reversed ) {
7076					isComplete = true;
7077					callback = "onComplete";
7078					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.
7079				}
7080				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.
7081					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
7081ding 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.
7082						time = 0;
7083					}
7084					if (time === 0 || prevRawPrevTime < 0 || (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.
7085						force = true;
7086						if (prevRawPrevTime > _tinyNum) {
7087							callback = "onReverseComplete";
7088						}
7089					}
7090					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.
7091				}
7092
7093			} else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0.
7094				this._totalTime = this._time = 0;
7095				this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
7096				if (prevTime !== 0 || (duration === 0 && prevRawPrevTime > 0)) {
7097					callback = "onReverseComplete";
7098					isComplete = this._reversed;
7099				}
7100				if (time < 0) {
7101					this._active = false;
7102					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.
7103						if (prevRawPrevTime >= 0 && !(prevRawPrevTime === _tinyNum && this.data === "isPause")) {
7104							force = true;
7105						}
7106						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.
7107					}
7108				}
7109				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.
7110					force = true;
7111				}
7112			} else {
7113				this._totalTime = this._time = time;
7114
7115				if (this._easeType) {
7116					var r = time / duration, type = this._easeType, pow = this._easePower;
7117					if (type === 1 || (type === 3 && r >= 0.5)) {
7118						r = 1 - r;
7119					}
7120					if (type === 3) {
7121						r *= 2;
7122					}
7123					if (pow === 1) {
7124						r *= r;
7125					} else if (pow === 2) {
7126						r *= r * r;
7127					} else if (pow === 3) {
7128						r *= r * r * r;
7129					} else if (pow === 4) {
7130						r *= r * r * r * r;
7131					}
7132
7133					if (type === 1) {
7134						this.ratio = 1 - r;
7135					} else if (type === 2) {
7136						this.ratio = r;
7137					} else if (time / duration < 0.5) {
7138						this.ratio = r / 2;
7139					} else {
7140						this.ratio = 1 - (r / 2);
7141					}
7142
7143				} else {
7144					this.ratio = this._ease.getRatio(time / duration);
7145				}
7146			}
7147
7148			if (this._time === prevTime && !force) {
7149				return;
7150			} else if (!this._initted) {
7151				this._init();
7152				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
7152writing 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.
7153					return;
7154				} else if (!force && this._firstPT && ((this.vars.lazy !== false && this._duration) || (this.vars.lazy && !this._duration))) {
7155					this._time = this._totalTime = prevTime;
7156					this._rawPrevTime = prevRawPrevTime;
7157					_lazyTweens.push(this);
7158					this._lazy = [time, suppressEvents];
7159					return;
7160				}
7161				//_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.
7162				if (this._time && !isComplete) {
7163					this.ratio = this._ease.getRatio(this._time / duration);
7164				} else if (isComplete && this._ease._calcEnd) {
7165					this.ratio = this._ease.getRatio((this._time === 0) ? 0 : 1);
7166				}
7167			}
7168			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.
7169				this._lazy = false;
7170			}
7171			if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) {
7172				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.
7173			}
7174			if (prevTime === 0) {
7175				if (this._startAt) {
7176					if (time >= 0) {
7177						this._startAt.render(time, suppressEvents, force);
7178					} else if (!callback) {
7179						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.
7180					}
7181				}
7182				if (this.vars.onStart) if (this._time !== 0 || duration === 0) if (!suppressEvents) {
7183					this._callback("onStart");
7184				}
7185			}
7186			pt = this._firstPT;
7187			while (pt) {
7188				if (pt.f) {
7189					pt.t[pt.p](pt.c * this.ratio + pt.s);
7190				} else {
7191					pt.t[pt.p] = pt.c * this.ratio + pt.s;
7192				}
7193				pt = pt._next;
7194			}
7195
7196			if (this._onUpdate) {
7197				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.
7198					this._startAt.render(time, suppressEvents, 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.
7199				}
7200				if (!suppressEvents) if (this._time !== prevTime || isComplete) {
7201					this._callback("onUpdate");
7202				}
7203			}
7204			if (callback) if (!this._gc || force) { //check _gc because there's a chance that kill() could be called in an onUpdate
7205				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.
7206					this._startAt.render(time, suppressEvents, force);
7207				}
7208				if (isComplete) {
7209					if (this._timeline.autoRemoveChildren) {
7210						this._enabled(false, false);
7211					}
7212					this._active = false;
7213				}
7214				if (!suppressEvents && this.vars[callback]) {
7215					this._callback(callback);
7216				}
7217				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.
7218					this._rawPrevTime = 0;
7219				}
7220			}
7221		};
7222
7223		p._kill = function(vars, target, overwritingTween) {
7224			if (vars === "all") {
7225				vars = null;
7226			}
7227			if (vars == null) if (target == null || target === this.target) {
7228				this._lazy = false;
7229				return this._enabled(false, false);
7230			}
7231			target = (typeof(target) !== "string") ? (target || this._targets || this.target) : TweenLite.selector(target) || target;
7232			var simultaneousOverwrite = (overwritingTween && this._time && overwritingTween._startTime === this._startTime && this._timeline === overwritingTween._timeline),
7233				i, overwrittenProps, p, pt, propLookup, changed, killProps, record, killed;
7234			if ((_isArray(target) || _isSelector(target)) && typeof(target[0]) !== "number") {
7235				i = target.length;
7236				while (--i > -1) {
7237					if (this._kill(vars, target[i], overwritingTween)) {
7238						changed = true;
7239					}
7240				}
7241			} else {
7242				if (this._targets) {
7243					i = this._targets.length;
7244					while (--i > -1) {
7245						if (target === this._targets[i]) {
7246							propLookup = this._propLookup[i] || {};
7247							this._overwrittenProps = this._overwrittenProps || [];
7248							overwrittenProps = this._overwrittenProps[i] = vars ? this._overwrittenProps[i] || {} : "all";
7249							break;
7250						}
7251					}
7252				} else if (target !== this.target) {
7253					return false;
7254				} else {
7255					propLookup = this._propLookup;
7256					overwrittenProps = this._overwrittenProps = vars ? this._overwrittenProps || {} : "all";
7257				}
7258
7259				if (propLookup) {
7260					killProps = vars || propLookup;
7261					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)
7262					if (overwritingTween && (TweenLite.onOverwrite || this.vars.onOverwrite)) {
7263						for (p in killProps) {
7264							if (propLookup[p]) {
7265								if (!killed) {
7266									killed = [];
7267								}
7268								killed.push(p);
7269							}
7270						}
7271						if ((killed || !vars) && !_onOverwrite(this, overwritingTween, target, killed)) { //if the onOverwrite returned false, that means the user wants to override the overwriting (cancel it).
7272							return false;
7273						}
7274					}
7275
7276					for (p in killProps) {
7277						if ((pt = propLookup[p])) {
7278							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.
7279								if (pt.f) {
7280									pt.t[pt.p](pt.s);
7281								} else {
7282									pt.t[pt.p] = pt.s;
7283								}
7284								changed = true;
7285							}
7286							if (pt.pg && pt.t._kill(killProps)) {
7287								changed = true; //some plugins need to be notified so they can perform cleanup tasks first
7288							}
7289							if (!pt.pg || pt.t._overwriteProps.length === 0) {
7290								if (pt._prev) {
7291									pt._prev._next = pt._next;
7292								} else if (pt === this._firstPT) {
7293									this._firstPT = pt._next;
7294								}
7295								if (pt._next) {
7296									pt._next._prev = pt._prev;
7297								}
7298								pt._next = pt._prev = null;
7299							}
7300							delete propLookup[p];
7301						}
7302						if (record) {
7303							overwrittenProps[p] = 1;
7304						}
7305					}
7306					if (!this._firstPT && this._initted) { //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.
7307						this._enabled(false, false);
7308					}
7309				}
7310			}
7311			return changed;
7312		};
7313
7314		p.invalidate = function() {
7315			if (this._notifyPluginsOfEnabled) {
7316				TweenLite._onPluginEvent("_onDisable", this);
7317			}
7318			this._firstPT = this._overwrittenProps = this._startAt = this._onUpdate = null;
7319			this._notifyPluginsOfEnabled = this._active = this._lazy = false;
7320			this._propLookup = (this._targets) ? {} : [];
7321			Animation.prototype.invalidate.call(this);
7322			if (this.vars.immediateRender) {
7323				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)
7324				this.render(-this._delay);
7325			}
7326			return this;
7327		};
7328
7329		p._enabled = function(enabled, ignoreTimeline) {
7330			if (!_tickerActive) {
7331				_ticker.wake();
7332			}
7333			if (enabled && this._gc) {
7334				var targets = this._targets,
7335					i;
7336				if (targets) {
7337					i = targets.length;
7338					while (--i > -1) {
7339						this._siblings[i] = _register(targets[i], this, true);
7340					}
7341				} else {
7342					this._siblings = _register(this.target, this, true);
7343				}
7344			}
7345			Animation.prototype._enabled.call(this, enabled, ignoreTimeline);
7346			if (this._notifyPluginsOfEnabled) if (this._firstPT) {
7347				return TweenLite._onPluginEvent((enabled ? "_onEnable" : "_onDisable"), this);
7348			}
7349			return false;
7350		};
7351
7352
7353//----TweenLite static methods -----------------------------------------------------
7354
7355		TweenLite.to = function(target, duration, vars) {
7356			return new TweenLite(target, duration, vars);
7357		};
7358
7359		TweenLite.from = function(target, duration, vars) {
7360			vars.runBackwards = true;
7361			vars.immediateRender = (vars.immediateRender != false);
7362			return new TweenLite(target, duration, vars);
7363		};
7364
7365		TweenLite.fromTo = function(target, duration, fromVars, toVars) {
7366			toVars.startAt = fromVars;
7367			toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false);
7368			return new TweenLite(target, duration, toVars);
7369		};
7370
7371		TweenLite.delayedCall = function(delay, callback, params, scope, useFrames) {
7372			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});
7373		};
7374
7375		TweenLite.set = function(target, vars) {
7376			return new TweenLite(target, 0, vars);
7377		};
7378
7379		TweenLite.getTweensOf = function(target, onlyActive) {
7380			if (target == null) { return []; }
7381			target = (typeof(target) !== "string") ? target : TweenLite.selector(target) || target;
7382			var i, a, j, t;
7383			if ((_isArray(target) || _isSelector(target)) && typeof(target[0]) !== "number") {
7384				i = target.length;
7385				a = [];
7386				while (--i > -1) {
7387					a = a.concat(TweenLite.getTweensOf(target[i], onlyActive));
7388				}
7389				i = a.length;
7390				//now get rid of any duplicates (tweens of arrays of objects could cause duplicates)
7391				while (--i > -1) {
7392					t = a[i];
7393					j = i;
7394					while (--j > -1) {
7395						if (t === a[j]) {
7396							a.splice(i, 1);
7397						}
7398					}
7399				}
7400			} else {
7401				a = _register(target).concat();
7402				i = a.length;
7403				while (--i > -1) {
7404					if (a[i]._gc || (onlyActive && !a[i].isActive())) {
7405						a.splice(i, 1);
7406					}
7407				}
7408			}
7409			return a;
7410		};
7411
7412		TweenLite.killTweensOf = TweenLite.killDelayedCallsTo = function(target, onlyActive, vars) {
7413			if (typeof(onlyActive) === "object") {
7414				vars = onlyActive; //for backwards compatibility (before "onlyActive" parameter was inserted)
7415				onlyActive = false;
7416			}
7417			var a = TweenLite.getTweensOf(target, onlyActive),
7418				i = a.length;
7419			while (--i > -1) {
7420				a[i]._kill(vars, target);
7421			}
7422		};
7423
7424
7425
7426/*
7427 * ----------------------------------------------------------------
7428 * 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)
7429 * ----------------------------------------------------------------
7430 */
7431		var TweenPlugin = _class("plugins.TweenPlugin", function(props, priority) {
7432					this._overwriteProps = (props || "").split(",");
7433					this._propName = this._overwriteProps[0];
7434					this._priority = priority || 0;
7435					this._super = TweenPlugin.prototype;
7436				}, true);
7437
7438		p = TweenPlugin.prototype;
7439		TweenPlugin.version = "1.18.0";
7440		TweenPlugin.API = 2;
7441		p._firstPT = null;
7442		p._addTween = _addPropTween;
7443		p.setRatio = _setRatio;
7444
7445		p._kill = function(lookup) {
7446			var a = this._overwriteProps,
7447				pt = this._firstPT,
7448				i;
7449			if (lookup[this._propName] != null) {
7450				this._overwriteProps = [];
7451			} else {
7452				i = a.length;
7453				while (--i > -1) {
7454					if (lookup[a[i]] != null) {
7455						a.splice(i, 1);
7456					}
7457				}
7458			}
7459			while (pt) {
7460				if (lookup[pt.n] != null) {
7461					if (pt._next) {
7462						pt._next._prev = pt._prev;
7463					}
7464					if (pt._prev) {
7465						pt._prev._next = pt._next;
7466						pt._prev = null;
7467					} else if (this._firstPT === pt) {
7468						this._firstPT = pt._next;
7469					}
7470				}
7471				pt = pt._next;
7472			}
7473			return false;
7474		};
7475
7476		p._roundProps = function(lookup, value) {
7477			var pt = this._firstPT;
7478			while (pt) {
7479				if (lookup[this._propName] || (pt.n != null && lookup[ pt.n.split(this._propName + "_").join("") ])) { //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.
7480					pt.r = value;
7481				}
7482				pt = pt._next;
7483			}
7484		};
7485
7486		TweenLite._onPluginEvent = function(type, tween) {
7487			var pt = tween._firstPT,
7488				changed, pt2, first, last, next;
7489			if (type === "_onInitAllProps") {
7490				//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.
7491				while (pt) {
7492					next = pt._next;
7493					pt2 = first;
7494					while (pt2 && pt2.pr > pt.pr) {
7495						pt2 = pt2._next;
7496					}
7497					if ((pt._prev = pt2 ? pt2._prev : last)) {
7498						pt._prev._next = pt;
7499					} else {
7500						first = pt;
7501					}
7502					if ((pt._next = pt2)) {
7503						pt2._prev = pt;
7504					} else {
7505						last = pt;
7506					}
7507					pt = next;
7508				}
7509				pt = tween._firstPT = first;
7510			}
7511			while (pt) {
7512				if (pt.pg) if (typeof(pt.t[type]) === "function") if (pt.t[type]()) {
7513					changed = true;
7514				}
7515				pt = pt._next;
7516			}
7517			return changed;
7518		};
7519
7520		TweenPlugin.activate = function(plugins) {
7521			var i = plugins.length;
7522			while (--i > -1) {
7523				if (plugins[i].API === TweenPlugin.API) {
7524					_plugins[(new plugins[i]())._propName] = plugins[i];
7525				}
7526			}
7527			return true;
7528		};
7529
7530		//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.
7531		_gsDefine.plugin = function(config) {
7532			if (!config || !config.propName || !config.init || !config.API) { throw "illegal plugin definition."; }
7533			var propName = config.propName,
7534				priority = config.priority || 0,
7535				overwriteProps = config.overwriteProps,
7536				map = {init:"_onInitTween", set:"setRatio", kill:"_kill", round:"_roundProps", initAll:"_onInitAllProps"},
7537				Plugin = _class("plugins." + propName.charAt(0).toUpperCase() + propName.substr(1) + "Plugin",
7538					function() {
7539						TweenPlugin.call(this, propName, priority);
7540						this._overwriteProps = overwriteProps || [];
7541					}, (config.global === true)),
7542				p = Plugin.prototype = new TweenPlugin(propName),
7543				prop;
7544			p.constructor = Plugin;
7545			Plugin.API = config.API;
7546			for (prop in map) {
7547				if (typeof(config[prop]) === "function") {
7548					p[map[prop]] = config[prop];
7549				}
7550			}
7551			Plugin.version = config.version;
7552			TweenPlugin.activate([Plugin]);
7553			return Plugin;
7554		};
7555
7556
7557		//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.
7558		a = window._gsQueue;
7559		if (a) {
7560			for (i = 0; i < a.length; i++) {
7561				a[i]();
7562			}
7563			for (p in _defLookup) {
7564				if (!_defLookup[p].func) {
7565					window.console.log("GSAP encountered missing dependency: com.greensock." + p);
7566				}
7567			}
7568		}
7569
7570		_tickerActive = false; //ensures that the first official animation forces a ticker.tick() to update the time when it is instantiated
7571
7572})((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.