1 /**
  2  * The MIT License (MIT)
  3  *
  4  * Copyright (c) 2016 DeNA Co., Ltd.
  5  *
  6  * Permission is hereby granted, free of charge, to any person obtaining a copy
  7  * of this software and associated documentation files (the "Software"), to deal
  8  * in the Software without restriction, including without limitation the rights
  9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10  * copies of the Software, and to permit persons to whom the Software is
 11  * furnished to do so, subject to the following conditions:
 12  *
 13  * The above copyright notice and this permission notice shall be included in
 14  * all copies or substantial portions of the Software.
 15  *
 16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 22  * SOFTWARE.
 23  */
 24 
 25 /// <reference path="base.js"/>
 26 /// <reference path="event_dispatcher.js"/>
 27 /// <reference path="tween_object.js"/>
 28 /// <reference path="tick_listener.js"/>
 29 /// <reference path="tick_event.js"/>
 30 /// <reference path="ticker.js"/>
 31 /// <reference path="tween_target.js"/>
 32 /// <reference path="uid.js"/>
 33 /// <reference path="ease.js"/>
 34 /// <reference path="counter.js"/>
 35 
 36 /**
 37  * A class that implements a tween.
 38  * @param {createjs.TweenTarget} target
 39  * @extends {createjs.EventDispatcher}
 40  * @implements {createjs.TweenObject}
 41  * @implements {createjs.TickListener}
 42  * @implements {createjs.TweenTarget.Property.Listener}
 43  * @constructor
 44  */
 45 createjs.Tween = function(target) {
 46   createjs.EventDispatcher.call(this);
 47 
 48   if (createjs.DEBUG) {
 49     /**
 50      * An ID for this tween.
 51      * @type {number}
 52      */
 53     this.id = createjs.Tween.id_++;
 54   }
 55 
 56   /**
 57    * The target object of this tween.
 58    * @type {createjs.TweenTarget}
 59    * @private
 60    */
 61   this.target_ = target;
 62 
 63   if (createjs.DEBUG) {
 64     ++createjs.Counter.totalTweens;
 65   }
 66 };
 67 createjs.inherits('Tween', createjs.Tween, createjs.EventDispatcher);
 68 
 69 if (createjs.DEBUG) {
 70   /**
 71    * IDs assigned to tweens.
 72    * @type {number}
 73    */
 74   createjs.Tween.id_ = 0;
 75 }
 76 
 77 /**
 78  * Whether the tween loops when it reaches the end.
 79  * @type {boolean}
 80  */
 81 createjs.Tween.prototype.loop_ = false;
 82 
 83 /**
 84  * Whether this tween is paused now.
 85  * @type {boolean}
 86  * @private
 87  */
 88 createjs.Tween.prototype.ended_ = false;
 89 
 90 /**
 91  * The total duration of this tween in milliseconds (or ticks).
 92  * @type {number}
 93  * @private
 94  */
 95 createjs.Tween.prototype.duration_ = 0;
 96 
 97 /**
 98  * The current normalized position of the tween.
 99  * @type {number}
100  * @private
101  */
102 createjs.Tween.prototype.position_ = 0;
103 
104 /**
105  * The previous position of the tween. This property is used for running
106  * actions.
107  * @type {number}
108  * @private
109  */
110 createjs.Tween.prototype.previous_ = -1;
111 
112 /**
113  * Whether this tween is changing its position.
114  * @type {boolean}
115  * @private
116  */
117 createjs.Tween.prototype.seek_ = false;
118 
119 /**
120  * The index to the current step.
121  * @type {number}
122  * @private
123  */
124 createjs.Tween.prototype.step_ = 1;
125 
126 /**
127  * The index to the current action.
128  * @type {number}
129  * @private
130  */
131 createjs.Tween.prototype.action_ = 0;
132 
133 /**
134  * Whether this tween is paused now.
135  * @type {boolean}
136  * @private
137  */
138 createjs.Tween.prototype.paused_ = false;
139 
140 /**
141  * @type {boolean}
142  * @private
143  */
144 createjs.Tween.prototype.useTicks_ = false;
145 
146 /**
147  * The list of steps added by an application.
148  * @type {Array.<createjs.Tween.Step>}
149  * @private
150  */
151 createjs.Tween.prototype.steps_ = null;
152 
153 /**
154  * The list of actions added by an application.
155  * @type {Array.<createjs.Tween.Action>}
156  * @private
157  */
158 createjs.Tween.prototype.actions_ = null;
159 
160 /**
161  * A list of tween commands to be compiled.
162  * @type {Array.<createjs.Tween.Command>}
163  * @private
164  */
165 createjs.Tween.prototype.commands_ = null;
166 
167 /**
168  * The target object of this tween.
169  * @type {createjs.TweenTarget}
170  * @private
171  */
172 createjs.Tween.prototype.proxy_ = null;
173 
174 /**
175  * A list of targets to be added by a state tween.
176  * @type {Array.<createjs.TweenTarget>}
177  * @private
178  */
179 createjs.Tween.prototype.targets_ = null;
180 
181 /**
182  * The last time when this tween has been updated in milliseconds. (0 represents
183  * this tween is being updated for the first time.)
184  * @type {number}
185  * @private
186  */
187 createjs.Tween.prototype.lastTime_ = 0;
188 
189 /**
190  * Whether this tween is updating its state.
191  * @type {boolean}
192  * @private
193  */
194 createjs.Tween.prototype.updating_ = false;
195 
196 /**
197  * Whether this tween is in the single-frame mode.
198  * @type {boolean}
199  * @private
200  */
201 createjs.Tween.prototype.single_ = false;
202 
203 /**
204  * Whether this tween is registered to its target object or the global ticker.
205  * @type {boolean}
206  * @private
207  */
208 createjs.Tween.prototype.registered_ = false;
209 
210 /**
211  * The total time of compiled commands.
212  * @type {number}
213  * @private
214  */
215 createjs.Tween.prototype.time_ = 0;
216 
217 /**
218  * An inner class that represents an animation step of a tween.
219  * @param {number} time
220  * @param {number} duration
221  * @param {Array.<createjs.TweenTarget.Property>} properties
222  * @param {createjs.Ease.Delegate} ease
223  * @param {boolean} hasNumber
224  * @constructor
225  */
226 createjs.Tween.Step = function(time, duration, properties, ease, hasNumber) {
227   /**
228    * The start time of this step.
229    * @type {number}
230    * @private
231    */
232   this.time_ = time;
233 
234   /**
235    * The multiplier that converts a step position [0,duration) to an
236    * interpolation ratio [0,1).
237    * @const {number}
238    * @private
239    */
240   this.scale_ = 1 / duration;
241 
242   /**
243    * A list of properties changed by this step.
244    * @const {Array.<createjs.TweenTarget.Property>}
245    */
246   this.properties_ = properties;
247 
248   /**
249    * An interpolation function.
250    * @const {createjs.Ease.Delegate}
251    * @private
252    */
253   this.ease_ = ease;
254 
255   /**
256    * Whether this step has number properties.
257    * @const {boolean}
258    * @private
259    */
260   this.hasNumber_ = hasNumber;
261 };
262 
263 /**
264  * An inner class that represents an action of a tween, a JavaScript function
265  * called when a tween reached to the time specified by an application.
266  * @param {number} time
267  * @param {Function} fn
268  * @param {Array} parameters
269  * @param {Object} scope
270  * @constructor
271  */
272 createjs.Tween.Action = function(time, fn, parameters, scope) {
273   /// <param type="number" name="time"/>
274   /// <param type="Function" name="fn"/>
275   /// <param type="Array" name="parameters"/>
276   /// <param type="Object" name="scope"/>
277 
278   /**
279    * @type {number}
280    * @private
281    */
282   this.time_ = time;
283 
284   /**
285    * @const {Function}
286    * @private
287    */
288   this.fn_ = fn;
289 
290   /**
291    * @const {*}
292    * @private
293    */
294   this.param0_ = parameters[0];
295 
296   /**
297    * @const {*}
298    * @private
299    */
300   this.param1_ = parameters[1];
301 
302   /**
303    * @const {*}
304    * @private
305    */
306   this.param2_ = parameters[2];
307 
308   /**
309    * @const {Object}
310    * @private
311    */
312   this.scope_ = scope;
313 };
314 
315 /**
316  * Executes this action.
317  * @private
318  */
319 createjs.Tween.Action.prototype.execute_ = function() {
320   this.fn_.call(this.scope_, this.param0_, this.param1_, this.param2_);
321 };
322 
323 /**
324  * An inner interface used by the createjs.Tween class to execute an animation
325  * command.
326  * @interface
327  */
328 createjs.Tween.Command = function() {};
329 
330 /**
331  * Adds target objects changed by this command to the specified array.
332  * @param {Object.<string,createjs.TweenTarget.Property>} properties
333  * @param {Object.<string,createjs.TweenTarget.Setter>} setters
334  */
335 createjs.Tween.Command.prototype.getProperties =
336     function(properties, setters) {};
337 
338 /**
339  * Adds target objects changed by this command to the specified array.
340  * @param {number} time
341  * @param {Array.<createjs.TweenTarget>} targets
342  * @return {number}
343  */
344 createjs.Tween.Command.prototype.getTargets = function(time, targets) {};
345 
346 /**
347  * Compiles this command.
348  * @param {number} time
349  * @param {createjs.TweenTarget} target
350  * @param {Array.<createjs.TweenTarget>} targets
351  * @param {Object.<string,createjs.TweenTarget.Property>} current
352  * @param {Array.<createjs.Tween.Step>} steps
353  * @return {number}
354  */
355 createjs.Tween.Command.prototype.compile =
356     function(time, target, targets, current, steps) {};
357 
358 /**
359  * An inner class used by the createjs.Tween class to halt an animation.
360  * @param {number} duration
361  * @implements {createjs.Tween.Command}
362  * @constructor
363  */
364 createjs.Tween.Wait = function(duration) {
365   /**
366    * The duration of this command.
367    * @const {number}
368    * @private
369    */
370   this.duration_ = duration;
371 };
372 
373 /** @override */
374 createjs.Tween.Wait.prototype.getProperties = function(properties, setters) {
375 };
376 
377 /** @override */
378 createjs.Tween.Wait.prototype.getTargets = function(time, targets) {
379   /// <param type="number" name="time"/>
380   /// <param type="Array" elementType="createjs.TweenTarget" name="targets"/>
381   /// <returns type="number"/>
382   return this.duration_;
383 };
384 
385 /** @override */
386 createjs.Tween.Wait.prototype.compile =
387     function(time, target, targets, current, steps) {
388   /// <param type="number" name="time"/>
389   /// <param type="createjs.TweenTarget" name="target"/>
390   /// <param type="Array" elementType="createjs.TweenTarget" name="targets"/>
391   /// <param type="Object" name="current"/>
392   /// <param type="Array" elementType="createjs.Tween.Step" name="steps"/>
393   /// <returns type="number"/>
394   var clone = [];
395   for (var key in current) {
396     // CRATLSPRT-47: this wait command increases the tween position by the
397     // specified duration, i.e. its end value is (the current position) + (its
398     // duration).
399     var property;
400     if (key == 'startPosition') {
401       property = current[key].clone(target, targets, time + this.duration_);
402     } else {
403       property = current[key].clone(target, targets);
404     }
405     clone.push(property);
406   }
407   steps.push(new createjs.Tween.Step(
408       time, this.duration_, clone, null, false));
409   return this.duration_;
410 };
411 
412 /**
413  * An inner class used by the createjs.Tween class to move a display object
414  * along the specified quadratic-Bezier paths.
415  * @param {Array.<number>} path
416  * @param {number} start
417  * @param {number} end
418  * @param {boolean} orientation
419  * @param {Object} properties
420  * @param {number} duration
421  * @param {createjs.Ease.Delegate} ease
422  * @implements {createjs.Tween.Command}
423  * @constructor
424  */
425 createjs.Tween.Guide =
426     function(path, start, end, orientation, properties, duration, ease) {
427   /**
428    * An array of points.
429    * @const {Array.<number>}
430    * @private
431    */
432   this.path_ = path;
433 
434   /**
435    * The start position.
436    * @const {number}
437    * @private
438    */
439   this.start_ = start || 0;
440 
441   /**
442    * The end position.
443    * @const {number}
444    * @private
445    */
446   this.end_ = (end == null) ? 1 : end;
447 
448   /**
449    * The orientation.
450    * @const {number}
451    * @private
452    */
453   this.orientation_ = createjs.Tween.Guide.getOrientation_(orientation);
454 
455   /**
456    * The set of properties to be changed by this command.
457    * @const {Object}
458    * @private
459    */
460   this.properties_ = properties;
461 
462   /**
463    * The duration of this command.
464    * @const {number}
465    * @private
466    */
467   this.duration_ = duration;
468 
469   /**
470    * The current position in this command.
471    * @type {number}
472    * @private
473    */
474   this.position_ = 0;
475 
476   /**
477    * The interpolation function.
478    * @const {createjs.Ease.Delegate}
479    * @private
480    */
481   this.ease_ = ease;
482 };
483 
484 /**
485  * Returns a number representing the orientation.
486  * @param {string|boolean} orientation
487  * @return {number}
488  * @private
489  */
490 createjs.Tween.Guide.getOrientation_ = function(orientation) {
491   if (!orientation) {
492     return createjs.TweenTarget.Orientation.NONE;
493   } else if (orientation == 'auto') {
494     return createjs.TweenTarget.Orientation.AUTO;
495   } else if (orientation == 'cw') {
496     return createjs.TweenTarget.Orientation.CLOCKWISE;
497   } else if (orientation == 'ccw') {
498     return createjs.TweenTarget.Orientation.COUNTERCLOCKWISE;
499   } else {
500     return createjs.TweenTarget.Orientation.FIXED;
501   }
502 };
503 
504 /**
505  * Adds an animation step.
506  * @param {number} time
507  * @param {createjs.TweenTarget.NumberProperty} x
508  * @param {createjs.TweenTarget.NumberProperty} y
509  * @param {createjs.TweenTarget.NumberProperty} rotation
510  * @param {number} index
511  * @param {number} t0
512  * @param {number} t1
513  * @param {number} unit
514  * @param {number} offset
515  * @param {Object.<string,createjs.TweenTarget.Property>} current
516  * @param {Array.<createjs.Tween.Step>} steps
517  * @return {number}
518  * @private
519  */
520 createjs.Tween.Guide.prototype.addStep_ = function(
521     time, x, y, rotation, index, t0, t1, unit, offset, current, steps) {
522   /// <param type="number" name="time"/>
523   /// <param type="createjs.TweenTarget.NumberProperty" name="x"/>
524   /// <param type="createjs.TweenTarget.NumberProperty" name="y"/>
525   /// <param type="createjs.TweenTarget.NumberProperty" name="rotation"/>
526   /// <param type="number" name="index"/>
527   /// <param type="number" name="t0"/>
528   /// <param type="number" name="t1"/>
529   /// <param type="number" name="unit"/>
530   /// <param type="number" name="offset"/>
531   /// <param type="Object" name="current"/>
532   /// <param type="Array" elementType="createjs.Tween.Step" name="steps"/>
533   /// <returns type="number"/>
534   var size = t1 - t0;
535   var duration = unit * size;
536   var clone = [];
537   if (duration == 1) {
538     // Games may use a path property to specify the position of a target object
539     // frame by frame. In this case, this code adds NumberProperty objects
540     // instead of adding a PathProperty object to use linear interpolation.
541     clone.push(
542         createjs.TweenTarget.NumberProperty.clone(x, this.path_[index + 4]),
543         createjs.TweenTarget.NumberProperty.clone(y, this.path_[index + 5]));
544   } else {
545     clone.push(createjs.TweenTarget.PathProperty.get(
546         x, y, this.path_, index, t0, size));
547     if (this.orientation_) {
548       clone.push(createjs.TweenTarget.RotationProperty.get(
549           rotation, this.path_, index, t0, size, this.orientation_, offset));
550     }
551   }
552   var r0 = this.position_ / this.duration_;
553   this.position_ += duration;
554   var r1 = this.position_ / this.duration_;
555   for (var key in current) {
556     if (key != 'x' && key != 'y') {
557       if (this.orientation_ && key == 'rotation') {
558         continue;
559       }
560       var start = current[key];
561       var property = start.interpolate(this.properties_[key], r0, r1);
562       clone.push(property);
563     }
564   }
565   steps.push(new createjs.Tween.Step(time, duration, clone, this.ease_, true));
566   return duration;
567 };
568 
569 /**
570  * Updates the current properties.
571  * @param {Object.<string,createjs.TweenTarget.Property>} current
572  * @param {createjs.TweenTarget.Property} x
573  * @param {createjs.TweenTarget.Property} y
574  * @param {number} index
575  * @param {number} t
576  * @param {createjs.TweenTarget} target
577  * @private
578  */
579 createjs.Tween.Guide.prototype.update_ =
580     function(current, x, y, index, t, target) {
581   /// <param type="Object" name="current"/>
582   /// <param type="createjs.TweenTarget.Property name="x"/>
583   /// <param type="createjs.TweenTarget.Property name="y"/>
584   /// <param type="number name="index"/>
585   /// <param type="number name="t"/>
586   /// <param type="createjs.TweenTarget name="target"/>
587   var path = this.path_;
588   var endX = path[index + 4];
589   var endY = path[index + 5];
590   if (t < 1) {
591     var t_ = 1 - t;
592     var t0 = t_ * t_;
593     var t1 = 2 * t_ * t;
594     var t2 = t * t;
595     endX = t0 * path[index] + t1 * path[index + 2] + t2 * endX;
596     endY = t0 * path[index + 1] + t1 * path[index + 3] + t2 * endY;
597   }
598   current['x'] = x.clone(target, null, endX);
599   current['y'] = y.clone(target, null, endY);
600   for (var key in this.properties_) {
601     if (key != 'guide') {
602       current[key] = current[key].clone(target, null, this.properties_[key]);
603     }
604   }
605 };
606 
607 /** @override */
608 createjs.Tween.Guide.prototype.getProperties = function(current, setters) {
609   /// <param type="Object" name="properties"/>
610   /// <param type="Object" name="setters"/>
611   var KEYS = ['x', 'y', 'rotation'];
612   var length = this.orientation_ ? 3 : 2;
613   for (var i = 0; i < length; ++i) {
614     var key = KEYS[i];
615     if (!current[key]) {
616       current[key] = createjs.TweenTarget.Property.get(setters[key]);
617     }
618   }
619   for (var key in this.properties_) {
620     if (key != 'guide') {
621       var setter = setters[key];
622       if (setter && !current[key]) {
623         current[key] = createjs.TweenTarget.Property.get(setter);
624       }
625     }
626   }
627 };
628 
629 /** @override */
630 createjs.Tween.Guide.prototype.getTargets = function(time, targets) {
631   /// <param type="number" name="time"/>
632   /// <param type="Array" elementType="createjs.TweenTarget" name="targets"/>
633   /// <returns type="number"/>
634   return this.duration_;
635 };
636 
637 /** @override */
638 createjs.Tween.Guide.prototype.compile =
639     function(time, target, targets, current, steps) {
640   /// <param type="number" name="time"/>
641   /// <param type="createjs.TweenTarget" name="target"/>
642   /// <param type="Array" elementType="createjs.TweenTarget" name="targets"/>
643   /// <param type="Object" name="current"/>
644   /// <param type="Array" elementType="createjs.Tween.Step" name="steps"/>
645   /// <returns type="number"/>
646   var length = this.path_.length;
647   var segments = (length - 2) >> 2;
648   var start = this.start_ * segments;
649   var end = this.end_ * segments;
650   var unit = this.duration_ / (end - start);
651   var x = /** @type {createjs.TweenTarget.NumberProperty} */ (current['x']);
652   var y = /** @type {createjs.TweenTarget.NumberProperty} */ (current['y']);
653   var rotation =
654       /** @type {createjs.TweenTarget.NumberProperty} */ (current['rotation']);
655   createjs.assert(x instanceof createjs.TweenTarget.NumberProperty);
656   createjs.assert(y instanceof createjs.TweenTarget.NumberProperty);
657 
658   // Split the path of this guide into multiple Bezier curves and create a step
659   // for each curve, e.g. a guide property consisting of two Bezier curves is
660   // split into two guide properties each of which consists of one Bezier curve
661   // as listed below.
662   //   'duration': 100, 'guide': { 'path': [0, 0, 50, 0, 50, 50, 0, 50, 0, 0] }
663   //   -> 'duration': 50, 'guide': { 'path': [0, 0, 50, 0, 50, 50] },
664   //      'duration': 50, 'guide': { 'path': [50, 50, 0, 50, 0, 0] },
665   // This code also splits the duration value according to the length of each
666   // curve.
667   if (end >= start) {
668     var offset = createjs.TweenTarget.RotationProperty.getOffset(this.path_, 0);
669     for (var i = 6; i <= length && 0 <= end; i += 4, --start, --end) {
670       if (1 <= start) {
671         continue;
672       }
673       var t0 = createjs.max(0, start);
674       var t1 = createjs.min(1, end);
675       time += this.addStep_(
676           time, x, y, rotation, i - 6, t0, t1, unit, offset, current, steps);
677     }
678     length -= 6;
679     ++end;
680   } else {
681     var offset = createjs.TweenTarget.RotationProperty.getOffset(
682         this.path_, length - 6);
683     start -= segments;
684     end -= segments;
685     for (var i = length - 6; i >= 0 && end < 0; i -= 4) {
686       ++start;
687       ++end;
688       if (start <= 0) {
689         continue;
690       }
691       var t0 = createjs.min(1, start);
692       var t1 = createjs.max(0, end);
693       time += this.addStep_(
694           time, x, y, rotation, i, t0, t1, unit, offset, current, steps);
695     }
696     length = 0;
697   }
698   // Calculate the last position of this tween and update the current property.
699   this.update_(current, x, y, length, end, target);
700   return this.duration_;
701 };
702 
703 /**
704  * An inner class used by the createjs.Tween class to move an animation.
705  * @param {Object} properties
706  * @param {number} duration
707  * @param {createjs.Ease.Delegate} ease
708  * @implements {createjs.Tween.Command}
709  * @constructor
710  */
711 createjs.Tween.To = function(properties, duration, ease) {
712   /**
713    * The set of properties to be changed by this command.
714    * @const {Object}
715    * @private
716    */
717   this.properties_ = properties;
718 
719   /**
720    * The duration of this command.
721    * @const {number}
722    * @private
723    */
724   this.duration_ = duration;
725 
726   /**
727    * The interpolation function.
728    * @const {createjs.Ease.Delegate}
729    * @private
730    */
731   this.ease_ = ease;
732 };
733 
734 /** @override */
735 createjs.Tween.To.prototype.getProperties = function(current, setters) {
736   /// <param type="Object" name="current"/>
737   /// <param type="Object" name="setters"/>
738   for (var key in this.properties_) {
739     var setter = setters[key];
740     if (setter && !current[key]) {
741       var property = createjs.TweenTarget.Property.get(setter);
742       if (property){
743         current[key] = property;
744       }
745     }
746   }
747 };
748 
749 /** @override */
750 createjs.Tween.To.prototype.getTargets = function(time, targets) {
751   /// <param type="number" name="time"/>
752   /// <param type="Array" elementType="createjs.TweenTarget" name="targets"/>
753   /// <returns type="number"/>
754   return this.duration_;
755 };
756 
757 /** @override */
758 createjs.Tween.To.prototype.compile =
759     function(time, target, targets, current, steps) {
760   /// <param type="number" name="time"/>
761   /// <param type="createjs.TweenTarget" name="target"/>
762   /// <param type="Array" elementType="createjs.TweenTarget" name="targets"/>
763   /// <param type="Object" name="current"/>
764   /// <param type="Array" elementType="createjs.Tween.Step" name="steps"/>
765   /// <returns type="number"/>
766 
767   // Create a set of properties to be set in this step.
768   var clone = [];
769   var hasNumber = 0;
770   for (var key in current) {
771     var start = current[key];
772     var property = start.clone(target, null, this.properties_[key]);
773     clone.push(property);
774     hasNumber |= property.isNumber();
775     current[key] = property;
776   }
777   if (this.duration_) {
778     steps.push(new createjs.Tween.Step(
779         time, this.duration_, clone, this.ease_, !!hasNumber));
780   }
781   return this.duration_;
782 };
783 
784 /**
785  * An inner class used by the createjs.Tween class to add display objects or to
786  * remove them.
787  * @param {Array.<Object>} end
788  * @param {number} duration
789  * @implements {createjs.Tween.Command}
790  * @constructor
791  */
792 createjs.Tween.State = function(end, duration) {
793   /**
794    * The list of states to be changed by this command. Each state is an Object
795    * consisting of two properties as listed in the following table.
796    *   +-----+------------------------------------------------------+
797    *   | key |                         value                        |
798    *   +-----+----------------------------------------+-------------+
799    *   |     | type                                   | description |
800    *   +-----+----------------------------------------+-------------+
801    *   | 't' | createjs.TweenTarget                   | target      |
802    *   | 'p' | Object,<string,boolean|number|string>  | properties  |
803    *   +-----+----------------------------------------+-------------+
804    * @const {Array.<Object>}
805    * @private
806    */
807   this.end_ = end;
808 
809   /**
810    * The duration of this command.
811    * @const {number}
812    * @private
813    */
814   this.duration_ = duration;
815 };
816 
817 /**
818  * Adds the specified target to the specified array if the array does not have
819  * the target.
820  * @param {number} time
821  * @param {Array.<createjs.TweenTarget>} targets
822  * @param {createjs.TweenTarget} target
823  * @private
824  */
825 createjs.Tween.State.prototype.addTarget_ = function(time, targets, target) {
826   /// <param type="number" name="time"/>
827   /// <param type="Array" elementType="createjs.TweenTarget" name="targets"/>
828   /// <param type="createjs.TweenTarget" name="target"/>
829   for (var i = 0; i < targets.length; ++i) {
830     if (targets[i] === target) {
831       return;
832     }
833   }
834   target.setOff(!!time);
835   targets.push(target);
836 };
837 
838 /** @override */
839 createjs.Tween.State.prototype.getProperties = function(properties, setters) {
840   createjs.notReached();
841 };
842 
843 /** @override */
844 createjs.Tween.State.prototype.getTargets = function(time, targets) {
845   /// <param type="number" name="time"/>
846   /// <param type="Array" elementType="createjs.TweenTarget" name="targets"/>
847   /// <returns type="number"/>
848   for (var i = 0; i < this.end_.length; ++i) {
849     this.addTarget_(time, targets, this.end_[i]['t']);
850   }
851   return this.duration_;
852 };
853 
854 /** @override */
855 createjs.Tween.State.prototype.compile =
856     function(time, target, targets, current, steps) {
857   /// <param type="number" name="time"/>
858   /// <param type="createjs.TweenTarget" name="target"/>
859   /// <param type="Array" elementType="createjs.TweenTarget" name="targets"/>
860   /// <param type="Object" name="current"/>
861   /// <param type="Array" elementType="createjs.Tween.Step" name="steps"/>
862   /// <returns type="number"/>
863   createjs.assert(!!targets);
864 
865   var key = 'state';
866   var start = current[key];
867   if (!start) {
868     start = createjs.TweenTarget.StateProperty.get(targets);
869   }
870   var property = start.clone(null, targets, this.end_);
871   current[key] = property;
872   if (this.duration_) {
873     steps.push(new createjs.Tween.Step(
874         time, this.duration_, [property], null, false));
875   }
876   return this.duration_;
877 };
878 
879 /**
880  * Returns a new createjs.Tween instance. This is a factory method for
881  * createjs.Tween objects.
882  * @param {createjs.TweenTarget} target
883  * @param {Object=} opt_properties
884  * @param {Object=} opt_pluginData
885  * @param {boolean=} opt_override
886  * @return {createjs.Tween}
887  * @const
888  */
889 createjs.Tween.get =
890     function(target, opt_properties, opt_pluginData, opt_override) {
891   // Reset the target if it does not implement the createjs.TweenTarget
892   // interface.
893   if (target && !target.registerTween) {
894     target = null;
895   }
896   if (!!opt_override) {
897     if (target) {
898       target.resetTweens();
899     }
900   }
901   var tween = new createjs.Tween(target);
902   if (opt_properties) {
903     tween.loop_ = !!opt_properties['loop'];
904     tween.paused_ = !!opt_properties['paused'];
905     tween.useTicks_ = !!opt_properties['useTicks'];
906   }
907   if (!tween.paused_) {
908     tween.register_(target);
909   }
910   return tween;
911 };
912 
913 /**
914  * Compiles tween commands and creates steps.
915  * @private
916  */
917 createjs.Tween.prototype.compileCommands_ = function() {
918   if (!this.commands_) {
919     return;
920   }
921   if (!this.steps_) {
922     this.steps_ = [];
923   }
924   var current = {};
925   var length = this.commands_.length;
926   if (this.target_) {
927     // Retrieve the values of all properties used by this tween.
928     var setters = this.target_.getSetters();
929     for (var i = 0; i < length; ++i) {
930       this.commands_[i].getProperties(current, setters);
931     }
932   }
933   for (var i = 0; i < length; ++i) {
934     this.time_ += this.commands_[i].compile(
935         this.time_, this.target_, this.targets_, current, this.steps_);
936   }
937   this.commands_ = null;
938 };
939 
940 /**
941  * Registers this tween to the target object.
942  * @param {createjs.TweenTarget} target
943  * @private
944  */
945 createjs.Tween.prototype.register_ = function(target) {
946   this.registered_ = true;
947   // A time-based tween uses this registration time as its start time, i.e. the
948   // first updateTween() call uses time elapsed since registration.
949   this.lastTime_ = createjs.Ticker.getRunTime();
950   if (target) {
951     target.registerTween(this);
952   } else {
953     createjs.Ticker.addListener('tick', this);
954   }
955 };
956 
957 /**
958  * Unregisters this tween from the target object.
959  * @param {createjs.TweenTarget} target
960  * @private
961  */
962 createjs.Tween.prototype.unregister_ = function(target) {
963   this.registered_ = false;
964   this.lastTime_ = 0;
965   if (target) {
966     target.unregisterTween(this);
967   } else {
968     createjs.Ticker.removeListener('tick', this);
969   }
970 };
971 
972 /**
973  * Sets properties of the specified DisplayObject object. This method is added
974  * to an action queue when an applications calls the set() method.
975  * @param {Object} properties
976  * @param {createjs.TweenTarget} target
977  * @private
978  */
979 createjs.Tween.prototype.setProperties_ = function(properties, target) {
980   /// <param type="Object" name="properties"/>
981   /// <param type="createjs.TweenTarget" name="target"/>
982   var values = createjs.TweenTarget.ValueProperty.get(properties);
983   for (var i = 0; i < values.length; ++i) {
984     values[i].setValue(target);
985   }
986 };
987 
988 /**
989  * Retrieves the animation step.
990  * @param {number} position
991  * @return {createjs.Tween.Step}
992  * @private
993  */
994 createjs.Tween.prototype.getStep_ = function(position) {
995   /// <param type="number" name="position"/>
996   /// <returns type="createjs.Tween.Step"/>
997   var i = createjs.max(this.step_, 0);
998   var length = this.steps_.length;
999   for (; i < length; ++i) {
1000     if (this.steps_[i].time_ > position) {
1001       break;
1002     }
1003   }
1004   --i;
1005   this.step_ = i;
1006   return this.steps_[i];
1007 };
1008 
1009 /**
1010  * Updates the animation.
1011  * @param {number} position
1012  * @param {boolean} seek
1013  * @return {number}
1014  * @private
1015  */
1016 createjs.Tween.prototype.updateAnimation_ = function(position, seek) {
1017   /// <param type="number" name="position"/>
1018   /// <param type="boolean" name="seek"/>
1019   /// <returns type="number"/>
1020   if (createjs.DEBUG) {
1021     ++createjs.Counter.runningTweens;
1022   }
1023   this.compileCommands_();
1024   if (position >= this.duration_) {
1025     if (!this.loop_ || !this.duration_) {
1026       position = this.duration_;
1027       this.ended_ = true;
1028     } else {
1029       position %= this.duration_;
1030       this.step_ = 1;
1031     }
1032   }
1033   // This tween is playing now. Retrieve the animation being played now and
1034   // update the state of its target. (This code does not need to compare with
1035   // |step[1].time_| because it represents the beginning of this animation,
1036   // i.e. |step[0].time_| is always 0.)
1037   if (!this.steps_) {
1038     return position;
1039   }
1040   var index = this.step_;
1041   var step = this.getStep_(position);
1042   if (!step) {
1043     return position;
1044   }
1045   var stepPosition = position - step.time_;
1046   var stepRatio = stepPosition * step.scale_;
1047   var updated = seek || stepRatio == 0 || stepRatio == 1;
1048   if (!step.hasNumber_ && index == this.step_) {
1049     if (!updated) {
1050       return position;
1051     }
1052   }
1053   if (createjs.DEBUG) {
1054     ++createjs.Counter.updatedTweens;
1055   }
1056   var ratio = step.ease_ ? step.ease_.interpolate(stepRatio) : stepRatio;
1057   // It is slow for a tween to change the positions of movie clips. To avoid it,
1058   // a tween sets the position of movie clips only when it needs to, i.e.:
1059   // * when a game has changed the position of this tween,
1060   // * when this tween is at the beginning of a step, or;
1061   // * when this tween is at the end of a step.
1062   if (!updated) {
1063     stepRatio = -1;
1064   }
1065   for (var i = 0; i < step.properties_.length; ++i) {
1066     step.properties_[i].setValue(
1067         this.target_, this.proxy_, ratio, this, stepRatio, this.targets_);
1068   }
1069   return position;
1070 };
1071 
1072 /**
1073  * Run actions in the specified range.
1074  * @param {number} start
1075  * @param {number} end
1076  * @private
1077  */
1078 createjs.Tween.prototype.runActions_ = function(start, end) {
1079   /// <param type="number" name="position"/>
1080   if (!this.actions_) {
1081     return;
1082   }
1083   var length = this.actions_.length;
1084   // This tween uses a monotonic timer, i.e. an end time is always greater
1085   // than a start time.
1086   createjs.assert(start <= end);
1087   // Run actions in the period (start, end].
1088   for (var i = this.action_; i < length; ++i) {
1089     var action = this.actions_[i];
1090     if (end < action.time_) {
1091       break;
1092     }
1093     if (start < action.time_ && action.time_ <= end) {
1094       this.action_ = i;
1095       action.execute_();
1096     }
1097   }
1098   // Run actions in the period [0, end % this.duration_] when this animation
1099   // has been rewound.
1100   if (this.loop_ && end > this.duration_) {
1101     this.action_ = 0;
1102     if (!this.useTicks_) {
1103       end %= this.duration_;
1104       for (var i = 0; i < length; ++i) {
1105         var action = this.actions_[i];
1106         if (end < action.time_) {
1107           break;
1108         }
1109         if (0 <= action.time_ && action.time_ <= end) {
1110           this.action_ = i;
1111           action.execute_();
1112         }
1113       }
1114     }
1115   }
1116 };
1117 
1118 /**
1119  * Removes all existing tweens from a target.
1120  * @param {createjs.TweenTarget} target
1121  * @const
1122  */
1123 createjs.Tween.removeTweens = function(target) {
1124   target.resetTweens();
1125 };
1126 
1127 /**
1128  * Removes all existing Tweens.
1129  * @const
1130  */
1131 createjs.Tween.removeAllTweens = function() {
1132   createjs.notImplemented();
1133 };
1134 
1135 /**
1136  * Returns whether there are any active Tweens attached to the specified target
1137  * or returns whether there are any registered Tweens.
1138  * @param {createjs.TweenTarget=} opt_target
1139  * @return {boolean}
1140  * @const
1141  */
1142 createjs.Tween.hasActiveTweens = function(opt_target) {
1143   if (opt_target) {
1144     return opt_target.hasTweens();
1145   }
1146   createjs.notImplemented();
1147   return true;
1148 };
1149 
1150 /**
1151  * Installs a plug-in.
1152  * @param {Object} plugin
1153  * @param {Array} properties
1154  * @const
1155  */
1156 createjs.Tween.installPlugin = function(plugin, properties) {
1157   createjs.notImplemented();
1158 };
1159 
1160 /**
1161  * Returns the target object of this tween.
1162  * @return {createjs.TweenTarget}
1163  * @const
1164  */
1165 createjs.Tween.prototype.getTarget = function() {
1166   /// <returns type="createjs.TweenTarget"/>
1167   return this.target_;
1168 };
1169 
1170 /**
1171  * Returns the duration (or total play time) of this tween.
1172  * @return {number}
1173  * @const
1174  */
1175 createjs.Tween.prototype.getDuration = function() {
1176   /// <returns type="number"/>
1177   return this.duration_;
1178 };
1179 
1180 /**
1181  * Retrieves the current play offset of this tween.
1182  * @return {number}
1183  * @const
1184  */
1185 createjs.Tween.prototype.getPosition = function() {
1186   /// <returns type="number"/>
1187   return this.position_;
1188 };
1189 
1190 /**
1191  * Pauses or plays this tween.
1192  * @param {boolean} value
1193  * @return {createjs.TweenObject}
1194  * @const
1195  */
1196 createjs.Tween.prototype.setPaused = function(value) {
1197   /// <param type="boolean" name="value"/>
1198   /// <returns type="createjs.TweenObject"/>
1199   var paused = !!value;
1200   var time = createjs.Ticker.getRunTime();
1201   if (paused) {
1202     this.stopTween(time);
1203   } else {
1204     this.playTween(time);
1205   }
1206   return this;
1207 };
1208 
1209 /**
1210  * Queues a wait (essentially an empty tween).
1211  * @param {number} duration
1212  * @param {boolean=} opt_passive
1213  * @return {createjs.Tween}
1214  * @const
1215  */
1216 createjs.Tween.prototype.wait = function(duration, opt_passive) {
1217   /// <param type="number" name="duration"/>
1218   /// <param type="boolean" optional="true" name="opt_passive"/>
1219   /// <returns type="createjs.Tween"/>
1220   if (duration == null || createjs.isNaN(duration) || duration <= 0) {
1221     return this;
1222   }
1223   if (!this.commands_) {
1224     this.commands_ = [];
1225   }
1226   this.commands_.push(new createjs.Tween.Wait(duration));
1227   this.duration_ += duration;
1228   return this;
1229 };
1230 
1231 /**
1232  * Queues a tween from the current values to the target properties.
1233  * @param {Object} properties
1234  * @param {number} duration
1235  * @param {createjs.Ease.Delegate=} opt_ease
1236  * @return {createjs.Tween}
1237  * @const
1238  */
1239 createjs.Tween.prototype.to = function(properties, duration, opt_ease) {
1240   /// <param type="Object" name="properties"/>
1241   /// <param type="number" name="duration"/>
1242   /// <param type="createjs.Ease.Delegate" optional="true" name="opt_ease"/>
1243   /// <returns type="createjs.Tween"/>
1244   if (duration == null || createjs.isNaN(duration) || duration < 0) {
1245     duration = 0;
1246   }
1247   if (!this.commands_) {
1248     this.commands_ = [];
1249   }
1250   if (this.target_) {
1251     var guide = properties['guide'];
1252     var ease = opt_ease || null;
1253     if (ease === createjs.Ease.linear) {
1254       ease = null;
1255     }
1256     if (guide) {
1257       this.commands_.push(new createjs.Tween.Guide(guide['path'],
1258                                                    guide['start'],
1259                                                    guide['end'],
1260                                                    guide['orient'],
1261                                                    properties,
1262                                                    duration,
1263                                                    ease));
1264     } else {
1265       this.commands_.push(
1266           new createjs.Tween.To(properties, duration, ease));
1267     }
1268   } else {
1269     var end = /** @type {Array.<Object>} */ (properties['state']);
1270     this.commands_.push(new createjs.Tween.State(end, duration));
1271   }
1272   this.duration_ += duration;
1273   return this;
1274 };
1275 
1276 /**
1277  * Queues an action to call the specified function.
1278  * @param {Function} callback
1279  * @param {Array=} opt_params
1280  * @param {Object=} opt_scope
1281  * @return {createjs.Tween}
1282  * @const
1283  */
1284 createjs.Tween.prototype.call = function(callback, opt_params, opt_scope) {
1285   /// <param type="Function" name="callback"/>
1286   /// <param type="Array" optional="true" name="opt_params"/>
1287   /// <param type="Object optional="true" name="opt_scope"/>
1288   /// <returns type="createjs.Tween"/>
1289   if (!this.actions_) {
1290     this.actions_ = [];
1291   }
1292   var scope = opt_scope || this.target_;
1293   var params = opt_params || [];
1294   this.actions_.push(
1295       new createjs.Tween.Action(this.duration_, callback, params, scope));
1296   return this;
1297 };
1298 
1299 /**
1300  * Queues an action to set the specified properties on the specified target.
1301  * @param {Object} properties
1302  * @param {createjs.TweenTarget=} opt_target
1303  * @return {createjs.Tween}
1304  * @const
1305  */
1306 createjs.Tween.prototype.set = function(properties, opt_target) {
1307   /// <param type="Object" name="properties"/>
1308   /// <param type="createjs.TweenTarget" optional="true" name="opt_target"/>
1309   /// <returns type="createjs.Tween"/>
1310   return this;
1311 };
1312 
1313 /**
1314  * Queues an action to to play (unpause) the specified tween.
1315  * @param {createjs.Tween} tween
1316  * @return {createjs.Tween}
1317  * @const
1318  */
1319 createjs.Tween.prototype.play = function(tween) {
1320   /// <param type="createjs.Tween" name="tween"/>
1321   /// <returns type="createjs.Tween"/>
1322   if (!tween) {
1323     tween = this;
1324   }
1325   return this.call(tween.setPaused, [false], tween);
1326 };
1327 
1328 /**
1329  * Queues an action to to pause the specified tween.
1330  * @param {createjs.Tween} tween
1331  * @return {createjs.Tween}
1332  * @const
1333  */
1334 createjs.Tween.prototype.pause = function(tween) {
1335   /// <param type="createjs.Tween" name="tween"/>
1336   /// <returns type="createjs.Tween"/>
1337   if (!tween) {
1338     tween = this;
1339   }
1340   return this.call(tween.setPaused, [true], tween);
1341 };
1342 
1343 /** @override */
1344 createjs.Tween.prototype.updateTween = function(time, flag, next) {
1345   /// <param type="number" name="time"/>
1346   /// <param type="number" name="flag"/>
1347   /// <param type="number" name="next"/>
1348   /// <returns type="number"/>
1349   // Set the position of this tween when another tween has changed the
1350   // position of this tween. Update the target properties of this tween and
1351   // exit this method without advancing its position only when both tweens
1352   // belong to one movie clip. This tween updates the target properties and
1353   // advances its position otherwise.
1354   if (next >= 0) {
1355     this.action_ = 0;
1356     if (this.position_ != next) {
1357       var update = flag & createjs.TweenObject.Flag.UPDATE;
1358       this.setPosition(next, update);
1359       if (update) {
1360         return this.position_;
1361       }
1362     }
1363   }
1364   if (time == this.lastTime_ || this.paused_ || this.single_ || this.ended_) {
1365     if (!this.seek_) {
1366       this.lastTime_ = time;
1367       return this.position_;
1368     }
1369   }
1370   this.updating_ = true;
1371   var position = this.position_;
1372   var previous = this.updateAnimation_(position, this.seek_);
1373   this.seek_ = false;
1374   this.position_ = -1;
1375   flag &= createjs.TweenObject.Flag.PLAY_MODE;
1376   if (flag != createjs.TweenTarget.PlayMode.SYNCHED) {
1377     this.runActions_(this.previous_, position);
1378   }
1379   this.updating_ = false;
1380   if (this.position_ < 0) {
1381     // Calculates the next position.
1382     this.previous_ = previous;
1383     var delta =
1384         this.useTicks_ ? createjs.Ticker.getFrames() : time - this.lastTime_;
1385     this.position_ = previous + delta;
1386   }
1387   this.lastTime_ = time;
1388   return this.previous_;
1389 };
1390 
1391 /** @override */
1392 createjs.Tween.prototype.playTween = function(time) {
1393   /// <param type="number" name="time"/>
1394   if (this.paused_) {
1395     if (!this.registered_) {
1396       this.register_(this.target_);
1397     }
1398     this.lastTime_ = time;
1399     this.paused_ = false;
1400   }
1401 };
1402 
1403 /** @override */
1404 createjs.Tween.prototype.stopTween = function(time) {
1405   /// <param type="number" name="time"/>
1406   if (!this.paused_) {
1407     var target = this.target_ || this.proxy_;
1408     this.lastTime_ = time;
1409     this.paused_ = true;
1410   }
1411 };
1412 
1413 /** @override */
1414 createjs.Tween.prototype.setProxy = function(proxy, targets) {
1415   /// <param type="createjs.TweenTarget" name="proxy"/>
1416   /// <param type="Array" elementType="createjs.TweenTarget" name="targets"/>
1417   /// <returns type="number"/>
1418   if (!proxy || this.target_ !== proxy) {
1419     createjs.assert(!this.proxy_);
1420     this.unregister_(this.target_);
1421     if (this.target_) {
1422       targets.unshift(this.target_);
1423     } else {
1424       var time = 0;
1425       this.targets_ = [];
1426       if (this.commands_) {
1427         for (var i = 0; i < this.commands_.length; ++i) {
1428           time += this.commands_[i].getTargets(time, this.targets_);
1429         }
1430         if (this.targets_.length) {
1431           targets.unshift.apply(targets, this.targets_);
1432         }
1433       }
1434     }
1435     if (proxy) {
1436       this.register_(proxy);
1437       this.proxy_ = proxy;
1438       if (this.target_) {
1439         var target = this.target_;
1440         if (target.getPlayMode() == createjs.TweenTarget.PlayMode.SYNCHED) {
1441           proxy.synchronize(this.target_, true);
1442         }
1443       } else {
1444         for (var i = 0; i < this.targets_.length; ++i) {
1445           var target = this.targets_[i];
1446           if (target.getPlayMode() == createjs.TweenTarget.PlayMode.SYNCHED) {
1447             proxy.synchronize(target, true);
1448           }
1449         }
1450       }
1451     }
1452     this.compileCommands_();
1453     // When this tween has a proxy, the proxy runs the tween on behalf of its
1454     // target and this tween does not have to register itself to its target any
1455     // longer. This method marks this tween as registered to prevent this tween
1456     // from re-registering itself.
1457     this.registered_ = true;
1458   }
1459   this.useTicks_ = true;
1460   // Write the time-stamp of this tween to synchronize the time-stamps of all
1461   // tweens added to a movie clip. (When this tween may be created by an action,
1462   // it must be updated in this rendering cycle. To force updating this tween in
1463   // this rendering cycle, this tween should have a time-stamp less than the
1464   // current one.)
1465   this.lastTime_ = createjs.Ticker.getRunTime() - 1;
1466   return this.duration_;
1467 };
1468 
1469 /** @override */
1470 createjs.Tween.prototype.setPosition = function(position, mode) {
1471   /// <param type="number" name="position"/>
1472   /// <param type="number" name="mode"/>
1473   // A MovieClip object calls this method with a negative position to reset this
1474   // tween.
1475   this.step_ = 1;
1476   this.action_ = 0;
1477   this.ended_ = false;
1478   if (mode) {
1479     if (!this.useTicks_) {
1480       return;
1481     }
1482     if (this.previous_ != position) {
1483       // Update the target properties only when this method is called from the
1484       // MovieClip.prototype.goto_() method.
1485       this.updateAnimation_(position, true);
1486     }
1487   }
1488   this.previous_ = position - 1;
1489   this.position_ = position;
1490   this.seek_ = true;
1491 };
1492 
1493 /** @override */
1494 createjs.Tween.prototype.setProperties = function(loop, position, single) {
1495   /// <param type="boolean" name="loop"/>
1496   /// <param type="number" name="position"/>
1497   /// <param type="boolean" name="single"/>
1498   this.loop_ = loop;
1499   this.single_ = single;
1500   if (single) {
1501     this.seek_ = true;
1502   }
1503 };
1504 
1505 /** @override */
1506 createjs.Tween.prototype.isEnded = function() {
1507   return this.ended_;
1508 };
1509 
1510 /** @override */
1511 createjs.Tween.prototype.handleTick = function(time) {
1512   createjs.assert(!this.target_);
1513   this.updateTween(time, createjs.TweenTarget.PlayMode.INDEPENDENT, -1);
1514   if (this.ended_) {
1515     createjs.Ticker.removeListener('tick', this, false);
1516   }
1517 };
1518 
1519 /** @override */
1520 createjs.Tween.prototype.handleLoopChanged = function(value) {
1521   // This method is called when another tween is changing the 'loop' property of
1522   // the target object of this tween, which is a createjs.MovieClip object.
1523   // Synchronize the loop property of this tween with the one of the target.
1524   this.loop_ = value;
1525 };
1526 
1527 // Add getters for applications to access internal variables.
1528 Object.defineProperties(createjs.Tween.prototype, {
1529   'target': {
1530     get: createjs.Tween.prototype.getTarget
1531   },
1532   'duration': {
1533     get: createjs.Tween.prototype.getDuration
1534   },
1535   'position': {
1536     get: createjs.Tween.prototype.getPosition
1537   }
1538 });
1539 
1540 // Export the createjs.Tween object to the global namespace.
1541 createjs.exportObject('createjs.Tween', createjs.Tween, {
1542   // createjs.Tween methods.
1543   'setPaused': createjs.Tween.prototype.setPaused,
1544   'wait': createjs.Tween.prototype.wait,
1545   'to': createjs.Tween.prototype.to,
1546   'call': createjs.Tween.prototype.call,
1547   'set': createjs.Tween.prototype.set,
1548   'play': createjs.Tween.prototype.play,
1549   'pause': createjs.Tween.prototype.pause,
1550   'setPosition': createjs.Tween.prototype.setPosition,
1551   'w': createjs.Tween.prototype.wait,
1552   't': createjs.Tween.prototype.to,
1553   'c': createjs.Tween.prototype.call,
1554   's': createjs.Tween.prototype.set
1555 }, {
1556   'get': createjs.Tween.get,
1557   'removeTweens': createjs.Tween.removeTweens,
1558   'removeAllTweens': createjs.Tween.removeAllTweens,
1559   'hasActiveTweens': createjs.Tween.hasActiveTweens,
1560   'installPlugin': createjs.Tween.installPlugin
1561 });
1562 
1563 // Export the createjs.Tween object to the global namespace.
1564 createjs.MotionGuidePlugin =
1565     createjs.exportStatic('createjs.MotionGuidePlugin', {
1566   'install': function() {}
1567 });
1568