text: 
  //////////////////////////////////////////////////////////////////////////////////
  //		uniforms tween							//
  //////////////////////////////////////////////////////////////////////////////////
  
  // TODO for each uniforms, does a tween function, do a total delay
  THREEx.UniformsTween	= function(uniforms, tweenFns){
  	// add EventDispatcher in this object
  	THREE.EventDispatcher.prototype.apply(this)
  	
  	var srcUniforms	= THREE.UniformsUtils.clone(uniforms)
  	var dstUniforms	= THREE.UniformsUtils.clone(uniforms)
  	this.dstUniforms= dstUniforms
  	
  	this.needsUpdate= true	
  	this.tweenDelay	= 2
  
  	var time	= null
  	this.update	= function(delta, now){
  		if( this.needsUpdate ){
  			time		= this.tweenDelay
  			srcUniforms	= THREE.UniformsUtils.clone(uniforms)	
  			this.needsUpdate= false		
  		}
  		
  		// if no tweening is in progress, return now
  		if( time === null )	return
  		// descrease the time remaining to tween
  		time	-= delta
  		// if tweening is going on after decrease, update value
  		if( time > 0 ){
  			var amount	= (this.tweenDelay-time) / this.tweenDelay
  			lerpUniforms(amount)
  		}else{
  			// if tweening just stopped, init to dstUniforms
  			lerpUniforms(1.0)
  			// make tweening as over
  			time	= null
  			// dispatch an event
  			this.dispatchEvent({ type: 'completed' })
  		}
  	}
  	this.copy	= function(){
  		this.value	= THREE.UniformsUtils.clone(uniforms)
  	}
  	
  	this.clone	= function(){
  		return THREE.UniformsUtils.clone(uniforms)
  	}
  	/**
  	 * lerp functions between 2 uniforms
  	 * @param  {Number} amount      the mixin amount between the 2
  	 */
  	function lerpUniforms(amount){
  		// go thru each uniforms
  		// - srcUniforms and dstUniforms are assumed to have the same value
  		Object.keys(tweenFns).forEach(function(uniformKey){
  			var srcUniform	= srcUniforms[uniformKey]
  			var dstUniform	= dstUniforms[uniformKey]
  			var tweenFn	= tweenFns[uniformKey]
  			// compute the lerp depending on the type	
  			if( srcUniform.type === 'f' ){
  				var value	= lerpFloat(srcUniform.value, dstUniform.value, tweenFn(amount))
  // console.log('lerp src', uniformKey, amount, value)
  				uniforms[uniformKey].value	= value
  				// console.log('lerp src', uniformKey, amount, value)
  			}else{
  				console.assert('unhandled type of uniform', srcUniform.type)
  			}
  		})
  		return
  		//////////////////////////////////////////////////////////////////////////////////
  		//		lerp functions for types of uniforms				//
  		//////////////////////////////////////////////////////////////////////////////////
  		
  		function lerpFloat(srcValue, dstValue, amount){
  			return srcValue + (dstValue-srcValue)*amount
  		}
  	}
  }
  
  
  //////////////////////////////////////////////////////////////////////////////////
  //		comment								//
  //////////////////////////////////////////////////////////////////////////////////
  
  
  /**
   * From tween.js
   */
  THREEx.UniformsTween.Easing = {
  
  	Linear: {
  
  		None: function ( k ) {
  
  			return k;
  
  		}
  
  	},
  
  	Quadratic: {
  
  		In: function ( k ) {
  
  			return k * k;
  
  		},
  
  		Out: function ( k ) {
  
  			return k * ( 2 - k );
  
  		},
  
  		InOut: function ( k ) {
  
  			if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
  			return - 0.5 * ( --k * ( k - 2 ) - 1 );
  
  		}
  
  	},
  
  	Cubic: {
  
  		In: function ( k ) {
  
  			return k * k * k;
  
  		},
  
  		Out: function ( k ) {
  
  			return --k * k * k + 1;
  
  		},
  
  		InOut: function ( k ) {
  
  			if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k;
  			return 0.5 * ( ( k -= 2 ) * k * k + 2 );
  
  		}
  
  	},
  
  	Quartic: {
  
  		In: function ( k ) {
  
  			return k * k * k * k;
  
  		},
  
  		Out: function ( k ) {
  
  			return 1 - ( --k * k * k * k );
  
  		},
  
  		InOut: function ( k ) {
  
  			if ( ( k *= 2 ) < 1) return 0.5 * k * k * k * k;
  			return - 0.5 * ( ( k -= 2 ) * k * k * k - 2 );
  
  		}
  
  	},
  
  	Quintic: {
  
  		In: function ( k ) {
  
  			return k * k * k * k * k;
  
  		},
  
  		Out: function ( k ) {
  
  			return --k * k * k * k * k + 1;
  
  		},
  
  		InOut: function ( k ) {
  
  			if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k * k * k;
  			return 0.5 * ( ( k -= 2 ) * k * k * k * k + 2 );
  
  		}
  
  	},
  
  	Sinusoidal: {
  
  		In: function ( k ) {
  
  			return 1 - Math.cos( k * Math.PI / 2 );
  
  		},
  
  		Out: function ( k ) {
  
  			return Math.sin( k * Math.PI / 2 );
  
  		},
  
  		InOut: function ( k ) {
  
  			return 0.5 * ( 1 - Math.cos( Math.PI * k ) );
  
  		}
  
  	},
  
  	Exponential: {
  
  		In: function ( k ) {
  
  			return k === 0 ? 0 : Math.pow( 1024, k - 1 );
  
  		},
  
  		Out: function ( k ) {
  
  			return k === 1 ? 1 : 1 - Math.pow( 2, - 10 * k );
  
  		},
  
  		InOut: function ( k ) {
  
  			if ( k === 0 ) return 0;
  			if ( k === 1 ) return 1;
  			if ( ( k *= 2 ) < 1 ) return 0.5 * Math.pow( 1024, k - 1 );
  			return 0.5 * ( - Math.pow( 2, - 10 * ( k - 1 ) ) + 2 );
  
  		}
  
  	},
  
  	Circular: {
  
  		In: function ( k ) {
  
  			return 1 - Math.sqrt( 1 - k * k );
  
  		},
  
  		Out: function ( k ) {
  
  			return Math.sqrt( 1 - ( --k * k ) );
  
  		},
  
  		InOut: function ( k ) {
  
  			if ( ( k *= 2 ) < 1) return - 0.5 * ( Math.sqrt( 1 - k * k) - 1);
  			return 0.5 * ( Math.sqrt( 1 - ( k -= 2) * k) + 1);
  
  		}
  
  	},
  
  	Elastic: {
  
  		In: function ( k ) {
  
  			var s, a = 0.1, p = 0.4;
  			if ( k === 0 ) return 0;
  			if ( k === 1 ) return 1;
  			if ( !a || a < 1 ) { a = 1; s = p / 4; }
  			else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI );
  			return - ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
  
  		},
  
  		Out: function ( k ) {
  
  			var s, a = 0.1, p = 0.4;
  			if ( k === 0 ) return 0;
  			if ( k === 1 ) return 1;
  			if ( !a || a < 1 ) { a = 1; s = p / 4; }
  			else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI );
  			return ( a * Math.pow( 2, - 10 * k) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) + 1 );
  
  		},
  
  		InOut: function ( k ) {
  
  			var s, a = 0.1, p = 0.4;
  			if ( k === 0 ) return 0;
  			if ( k === 1 ) return 1;
  			if ( !a || a < 1 ) { a = 1; s = p / 4; }
  			else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI );
  			if ( ( k *= 2 ) < 1 ) return - 0.5 * ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
  			return a * Math.pow( 2, -10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) * 0.5 + 1;
  
  		}
  
  	},
  
  	Back: {
  
  		In: function ( k ) {
  
  			var s = 1.70158;
  			return k * k * ( ( s + 1 ) * k - s );
  
  		},
  
  		Out: function ( k ) {
  
  			var s = 1.70158;
  			return --k * k * ( ( s + 1 ) * k + s ) + 1;
  
  		},
  
  		InOut: function ( k ) {
  
  			var s = 1.70158 * 1.525;
  			if ( ( k *= 2 ) < 1 ) return 0.5 * ( k * k * ( ( s + 1 ) * k - s ) );
  			return 0.5 * ( ( k -= 2 ) * k * ( ( s + 1 ) * k + s ) + 2 );
  
  		}
  
  	},
  
  	Bounce: {
  
  		In: function ( k ) {
  
  			return 1 - TWEEN.Easing.Bounce.Out( 1 - k );
  
  		},
  
  		Out: function ( k ) {
  
  			if ( k < ( 1 / 2.75 ) ) {
  
  				return 7.5625 * k * k;
  
  			} else if ( k < ( 2 / 2.75 ) ) {
  
  				return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
  
  			} else if ( k < ( 2.5 / 2.75 ) ) {
  
  				return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
  
  			} else {
  
  				return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
  
  			}
  
  		},
  
  		InOut: function ( k ) {
  
  			if ( k < 0.5 ) return TWEEN.Easing.Bounce.In( k * 2 ) * 0.5;
  			return TWEEN.Easing.Bounce.Out( k * 2 - 1 ) * 0.5 + 0.5;
  
  		}
  
  	}
  
  };
  
  
  
  
  