From 11cad28fc6b4d6dbf8741c28902634816dfae038 Mon Sep 17 00:00:00 2001 From: hyperandroid Date: Thu, 23 Feb 2012 17:07:03 +0100 Subject: [PATCH] 02/23/2012 *0.3 Build 208* -------------------------- * Added to CAAT.Scene the following methods: + findActorAtPosition(CAAT.Point) : custom actor find procedure. This is overriden to attend at the priority input lists. + enableInputList(number) : number of priority lists to set for this scene. A priority list is a list of actors to which are suitable to receive input first. If no actor on the priority lists are under the cursor, the whole scene graph is traversed instead. + addActorToInputList( actor, index, position ) : add an actor to a given priority list at certain position. + emptyInputList( index ) : remove all elements from a list. + removeActorFromInputList( actor, index ) : remove an actor from a list, or if no index list is supplied remove the actor from every list in which appears. * Fixed Actor.setImageTransformation( CAAT.SpriteImage.prototype.TR_TILE ) which didn't honor actor position and offset to appropriately place the tiling image. Also the performance sink when using this flag with huge actors's been fixed. --- build/caat-box2d-min.js | 6 +- build/caat-box2d.js | 6 +- build/caat-css-min.js | 93 +- build/caat-css.js | 23 +- build/caat-min.js | 107 +- build/caat.js | 142 +- changelog | 16 + .../demos/demo-resources/img/hoppy.png | Bin 0 -> 54100 bytes .../demo-resources/img/numerospuntos.png | Bin 0 -> 12074 bytes .../demos/demo4/coordinates_org.html | 19 +- ...Users_ibon_js_CAAT_src_math_bezier.js.html | 916 ++--- ...Users_ibon_js_CAAT_src_model_actor.js.html | 2426 ++++++------ .../_Users_ibon_js_CAAT_src_path_path.js.html | 3254 +++++++++-------- ...rs_ibon_js_CAAT_src_path_pathactor.js.html | 182 +- src/model/actor.js | 3 +- src/model/conpoundimage.js | 15 +- src/model/director.js | 2 +- src/model/scene.js | 116 + 18 files changed, 3857 insertions(+), 3469 deletions(-) create mode 100644 documentation/demos/demo-resources/img/hoppy.png create mode 100644 documentation/demos/demo-resources/img/numerospuntos.png diff --git a/build/caat-box2d-min.js b/build/caat-box2d-min.js index 5c5beffc..d71cbe0d 100644 --- a/build/caat-box2d-min.js +++ b/build/caat-box2d-min.js @@ -22,11 +22,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Version: 0.3 build: 180 +Version: 0.3 build: 208 Created on: -DATE: 2012-02-20 -TIME: 23:55:10 +DATE: 2012-02-23 +TIME: 17:03:41 */ diff --git a/build/caat-box2d.js b/build/caat-box2d.js index 223d7b2c..c5636b38 100644 --- a/build/caat-box2d.js +++ b/build/caat-box2d.js @@ -21,11 +21,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Version: 0.3 build: 181 +Version: 0.3 build: 209 Created on: -DATE: 2012-02-20 -TIME: 23:55:34 +DATE: 2012-02-23 +TIME: 17:04:10 */ diff --git a/build/caat-css-min.js b/build/caat-css-min.js index 9e0be9de..d703b8f9 100644 --- a/build/caat-css-min.js +++ b/build/caat-css-min.js @@ -22,11 +22,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Version: 0.3 build: 180 +Version: 0.3 build: 208 Created on: -DATE: 2012-02-20 -TIME: 23:55:10 +DATE: 2012-02-23 +TIME: 17:03:41 */ @@ -191,38 +191,39 @@ d.drawElements(d.TRIANGLES,3*b,d.UNSIGNED_SHORT,0)},glFlush:function(){this.coor render:function(a){this.time+=a;this.animate(this,a);CAAT.DEBUG&&this.resetStats();var b=this.childrenList.length,c,d,e,f=this.ctx;if(this.glEnabled){this.gl.clear(this.gl.COLOR_BUFFER_BIT|this.gl.DEPTH_BUFFER_BIT);for(c=this.uvIndex=this.coordsIndex=0;c0&&CAAT.DEBUG&&CAAT.DEBUG_DIRTYRECTS){f.beginPath();this.nDirtyRects=0;d=this.cDirtyRects;for(c=0;c=this.dirtyRects.length)for(b=0;b<32;b++)this.dirtyRects.push(new CAAT.Rectangle);b=this.dirtyRects[this.dirtyRectsIndex];b.x=a.x;b.y=a.y;b.x1=a.x1;b.y1=a.y1;b.width=a.width;b.height=a.height;this.cDirtyRects.push(b)}},renderToContext:function(a,b){if(b.isInAnimationFrame(this.time)){a.globalAlpha=1;a.globalCompositeOperation="source-over";a.clearRect(0,0,this.width,this.height);a.setTransform(1,0,0,0,1,0);var c=this.ctx,d=this.crc; -this.ctx=this.crc=a;a.save();var e=this.worldModelViewMatrix;this.worldModelViewMatrix=new CAAT.Matrix;this.wdirty=true;b.animate(this,b.time);if(b.onRenderStart)b.onRenderStart(b.time);b.paintActor(this,b.time);if(b.onRenderEnd)b.onRenderEnd(b.time);this.worldModelViewMatrix=e;a.restore();this.ctx=c;this.crc=d}},addScene:function(a){a.setBounds(0,0,this.width,this.height);this.scenes.push(a);a.setEaseListener(this);null===this.currentScene&&this.setScene(0)},getNumScenes:function(){return this.scenes.length}, -easeInOut:function(a,b,c,d,e,f,g,h,i,j){if(a!==this.getCurrentSceneIndex()){a=this.scenes[a];d=this.scenes[d];if(!this.glEnabled&&!navigator.browser==="iOS")this.worldModelViewMatrix.transformRenderingContext(this.transitionScene.ctx),this.renderToContext(this.transitionScene.ctx,d),d=this.transitionScene;a.setExpired(false);d.setExpired(false);a.mouseEnabled=false;d.mouseEnabled=false;a.resetTransform();d.resetTransform();a.setLocation(0,0);d.setLocation(0,0);a.alpha=1;d.alpha=1;b===CAAT.Scene.prototype.EASE_ROTATION? -a.easeRotationIn(g,h,c,i):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,g,h,c,i):a.easeTranslationIn(g,h,c,i);e===CAAT.Scene.prototype.EASE_ROTATION?d.easeRotationOut(g,h,f,j):e===CAAT.Scene.prototype.EASE_SCALE?d.easeScaleOut(0,g,h,f,j):d.easeTranslationOut(g,h,f,j);this.childrenList=[];this.addChild(d);this.addChild(a)}},easeInOutRandom:function(a,b,c,d){var e=Math.random(),f=Math.random(),g;e<0.33?(e=CAAT.Scene.prototype.EASE_ROTATION,g=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)): -e<0.66?(e=CAAT.Scene.prototype.EASE_SCALE,g=(new CAAT.Interpolator).createElasticOutInterpolator(1.1,0.4)):(e=CAAT.Scene.prototype.EASE_TRANSLATE,g=(new CAAT.Interpolator).createBounceOutInterpolator());var h;f<0.33?(f=CAAT.Scene.prototype.EASE_ROTATION,h=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):f<0.66?(f=CAAT.Scene.prototype.EASE_SCALE,h=(new CAAT.Interpolator).createExponentialOutInterpolator(4)):(f=CAAT.Scene.prototype.EASE_TRANSLATE,h=(new CAAT.Interpolator).createBounceOutInterpolator()); -this.easeInOut(a,e,Math.random()*8.99>>0,b,f,Math.random()*8.99>>0,c,d,g,h)},easeIn:function(a,b,c,d,e,f){a=this.scenes[a];b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(c,d,e,f):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,c,d,e,f):a.easeTranslationIn(c,d,e,f);this.childrenList=[];this.addChild(a);a.resetTransform();a.setLocation(0,0);a.alpha=1;a.mouseEnabled=false;a.setExpired(false)},setScene:function(a){a=this.scenes[a];this.childrenList=[];this.addChild(a);this.currentScene=a; -a.setExpired(false);a.mouseEnabled=true;a.resetTransform();a.setLocation(0,0);a.alpha=1;a.activated()},switchToScene:function(a,b,c,d){var e=this.getSceneIndex(this.currentScene);d?this.easeInOutRandom(a,e,b,c):this.setScene(a)},switchToPrevScene:function(a,b,c){var d=this.getSceneIndex(this.currentScene);this.getNumScenes()<=1||d===0||(c?this.easeInOutRandom(d-1,d,a,b):this.setScene(d-1))},switchToNextScene:function(a,b,c){var d=this.getSceneIndex(this.currentScene);this.getNumScenes()<=1||d===this.getNumScenes()- -1||(c?this.easeInOutRandom(d+1,d,a,b):this.setScene(d+1))},mouseEnter:function(){},mouseExit:function(){},mouseMove:function(){},mouseDown:function(){},mouseUp:function(){},mouseDrag:function(){},easeEnd:function(a,b){b?(this.currentScene=a,this.currentScene.activated()):a.setExpired(true);a.mouseEnabled=true;a.emptyBehaviorList()},getSceneIndex:function(a){for(var b=0;b500&&(b=500);if(this.onRenderStart)this.onRenderStart(b);this.render(b);this.debugInfo&&this.debugInfo(this.statistics);this.timeline=a;if(this.onRenderEnd)this.onRenderEnd(b)},endLoop:function(){},setClear:function(a){this.clear=a;if(this.clear===CAAT.Director.CLEAR_DIRTY_RECTS)this.dirtyRectsEnabled= -true;return this},getAudioManager:function(){return this.audioManager},cumulateOffset:function(a,b,c){var d=c+"Left";c+="Top";for(var e=0,f=0,g;navigator.browser!=="iOS"&&a&&a.style;)if(g=a.currentStyle?a.currentStyle.position:(g=(a.ownerDocument.defaultView||a.ownerDocument.parentWindow).getComputedStyle(a,null))?g.getPropertyValue("position"):null,/^(fixed)$/.test(g))break;else e+=a[d],f+=a[c],a=a[b];return{x:e,y:f,style:g}},getOffset:function(a){var b=this.cumulateOffset(a,"offsetParent","offset"); -return b.style==="fixed"?(a=this.cumulateOffset(a,a.parentNode?"parentNode":"parentElement","scroll"),{x:b.x+a.x,y:b.y+a.y}):{x:b.x,y:b.y}},getCanvasCoord:function(a,b){var c=0,d=0;if(!b)b=window.event;if(b.pageX||b.pageY)c=b.pageX,d=b.pageY;else if(b.clientX||b.clientY)c=b.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,d=b.clientY+document.body.scrollTop+document.documentElement.scrollTop;var e=this.getOffset(b.target);c-=e.x;d-=e.y;d=new CAAT.Point(c,d);this.modelViewMatrixI= -this.modelViewMatrix.getInverse();this.modelViewMatrixI.transformCoord(d);c=d.x;d=d.y;a.set(c,d);this.screenMousePoint.set(c,d)},__mouseDownHandler:function(a){if(this.dragging&&this.lastSelectedActor)this.__mouseUpHandler(a);else{this.getCanvasCoord(this.mousePoint,a);this.isMouseDown=true;var b=this.findActorAtPosition(this.mousePoint);if(null!==b){var c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0));b.mouseDown((new CAAT.MouseEvent).init(c.x,c.y,a,b,new CAAT.Point(this.screenMousePoint.x, -this.screenMousePoint.y)))}this.lastSelectedActor=b}},__mouseUpHandler:function(a){this.isMouseDown=false;this.getCanvasCoord(this.mousePoint,a);var b=null,c=this.lastSelectedActor;null!==c&&(b=c.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),c.actionPerformed&&c.contains(b.x,b.y)&&c.actionPerformed(a),c.mouseUp((new CAAT.MouseEvent).init(b.x,b.y,a,c,this.screenMousePoint,this.currentScene.time)));!this.dragging&&null!==c&&c.contains(b.x,b.y)&&c.mouseClick((new CAAT.MouseEvent).init(b.x, -b.y,a,c,this.screenMousePoint,this.currentScene.time));this.in_=this.dragging=false},__mouseMoveHandler:function(a){this.getCanvasCoord(this.mousePoint,a);var b,c;if(this.isMouseDown&&null!==this.lastSelectedActor){b=this.lastSelectedActor;c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0));this.dragging=true;var d=b.x,e=b.y;b.mouseDrag((new CAAT.MouseEvent).init(c.x,c.y,a,b,new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y),this.currentScene.time));this.prevMousePoint.x= -c.x;this.prevMousePoint.y=c.y;if(d===b.x&&e===b.y){d=b.contains(c.x,c.y);if(this.in_&&!d)b.mouseExit((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)),this.in_=false;if(!this.in_&&d)b.mouseEnter((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)),this.in_=true}}else this.in_=true,b=this.findActorAtPosition(this.mousePoint),b!==this.lastSelectedActor&&(null!==this.lastSelectedActor&&(c=this.lastSelectedActor.viewToModel(new CAAT.Point(this.screenMousePoint.x, -this.screenMousePoint.y,0)),this.lastSelectedActor.mouseExit((new CAAT.MouseEvent).init(c.x,c.y,a,this.lastSelectedActor,this.screenMousePoint,this.currentScene.time))),null!==b&&(c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),b.mouseEnter((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)))),c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),null!==b&&b.mouseMove((new CAAT.MouseEvent).init(c.x,c.y, -a,b,this.screenMousePoint,this.currentScene.time)),this.lastSelectedActor=b},__mouseOutHandler:function(a){if(null!==this.lastSelectedActor){this.getCanvasCoord(this.mousePoint,a);var b=new CAAT.Point(this.mousePoint.x,this.mousePoint.y,0);this.lastSelectedActor.viewToModel(b);a=(new CAAT.MouseEvent).init(b.x,b.y,a,this.lastSelectedActor,this.screenMousePoint,this.currentScene.time);this.lastSelectedActor.mouseExit(a);this.lastSelectedActor.mouseOut(a);if(!this.dragging)this.lastSelectedActor=null}else this.in_= -this.isMouseDown=false},__mouseOverHandler:function(a){var b,c;this.getCanvasCoord(this.mousePoint,a);null==this.lastSelectedActor?(b=this.findActorAtPosition(this.mousePoint),null!==b&&(c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),a=(new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time),b.mouseOver(a),b.mouseEnter(a)),this.lastSelectedActor=b):(b=this.lastSelectedActor,c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y, -0)),a=(new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time),b.mouseOver(a),b.mouseEnter(a))},__mouseDBLClickHandler:function(a){this.getCanvasCoord(this.mousePoint,a);null!==this.lastSelectedActor&&this.lastSelectedActor.mouseDblClick((new CAAT.MouseEvent).init(this.mousePoint.x,this.mousePoint.y,a,this.lastSelectedActor,this.screenMousePoint,this.currentScene.time))},__touchStartHandler:function(a){a.preventDefault();a=a.targetTouches[0];this.__mouseDownHandler(a)}, -__touchEndHandler:function(a){a.preventDefault();a=a.changedTouches[0];this.__mouseUpHandler(a)},__touchMoveHandler:function(a){a.preventDefault();if(!this.gesturing)for(var b=0;b0&&CAAT.DEBUG&&CAAT.DEBUG_DIRTYRECTS){f.beginPath();this.nDirtyRects=0;d=this.cDirtyRects;for(c=0;c=this.dirtyRects.length)for(b=0;b<32;b++)this.dirtyRects.push(new CAAT.Rectangle);b=this.dirtyRects[this.dirtyRectsIndex];b.x=a.x;b.y=a.y;b.x1=a.x1;b.y1=a.y1;b.width=a.width;b.height=a.height;this.cDirtyRects.push(b)}},renderToContext:function(a,b){if(b.isInAnimationFrame(this.time)){a.globalAlpha=1;a.globalCompositeOperation="source-over";a.clearRect(0, +0,this.width,this.height);a.setTransform(1,0,0,0,1,0);var c=this.ctx,d=this.crc;this.ctx=this.crc=a;a.save();var e=this.worldModelViewMatrix;this.worldModelViewMatrix=new CAAT.Matrix;this.wdirty=true;b.animate(this,b.time);if(b.onRenderStart)b.onRenderStart(b.time);b.paintActor(this,b.time);if(b.onRenderEnd)b.onRenderEnd(b.time);this.worldModelViewMatrix=e;a.restore();this.ctx=c;this.crc=d}},addScene:function(a){a.setBounds(0,0,this.width,this.height);this.scenes.push(a);a.setEaseListener(this);null=== +this.currentScene&&this.setScene(0)},getNumScenes:function(){return this.scenes.length},easeInOut:function(a,b,c,d,e,f,g,h,i,j){if(a!==this.getCurrentSceneIndex()){a=this.scenes[a];d=this.scenes[d];if(!this.glEnabled&&!navigator.browser==="iOS")this.worldModelViewMatrix.transformRenderingContext(this.transitionScene.ctx),this.renderToContext(this.transitionScene.ctx,d),d=this.transitionScene;a.setExpired(false);d.setExpired(false);a.mouseEnabled=false;d.mouseEnabled=false;a.resetTransform();d.resetTransform(); +a.setLocation(0,0);d.setLocation(0,0);a.alpha=1;d.alpha=1;b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(g,h,c,i):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,g,h,c,i):a.easeTranslationIn(g,h,c,i);e===CAAT.Scene.prototype.EASE_ROTATION?d.easeRotationOut(g,h,f,j):e===CAAT.Scene.prototype.EASE_SCALE?d.easeScaleOut(0,g,h,f,j):d.easeTranslationOut(g,h,f,j);this.childrenList=[];this.addChild(d);this.addChild(a)}},easeInOutRandom:function(a,b,c,d){var e=Math.random(),f=Math.random(),g;e< +0.33?(e=CAAT.Scene.prototype.EASE_ROTATION,g=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):e<0.66?(e=CAAT.Scene.prototype.EASE_SCALE,g=(new CAAT.Interpolator).createElasticOutInterpolator(1.1,0.4)):(e=CAAT.Scene.prototype.EASE_TRANSLATE,g=(new CAAT.Interpolator).createBounceOutInterpolator());var h;f<0.33?(f=CAAT.Scene.prototype.EASE_ROTATION,h=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):f<0.66?(f=CAAT.Scene.prototype.EASE_SCALE,h=(new CAAT.Interpolator).createExponentialOutInterpolator(4)): +(f=CAAT.Scene.prototype.EASE_TRANSLATE,h=(new CAAT.Interpolator).createBounceOutInterpolator());this.easeInOut(a,e,Math.random()*8.99>>0,b,f,Math.random()*8.99>>0,c,d,g,h)},easeIn:function(a,b,c,d,e,f){a=this.scenes[a];b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(c,d,e,f):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,c,d,e,f):a.easeTranslationIn(c,d,e,f);this.childrenList=[];this.addChild(a);a.resetTransform();a.setLocation(0,0);a.alpha=1;a.mouseEnabled=false;a.setExpired(false)}, +setScene:function(a){a=this.scenes[a];this.childrenList=[];this.addChild(a);this.currentScene=a;a.setExpired(false);a.mouseEnabled=true;a.resetTransform();a.setLocation(0,0);a.alpha=1;a.activated()},switchToScene:function(a,b,c,d){var e=this.getSceneIndex(this.currentScene);d?this.easeInOutRandom(a,e,b,c):this.setScene(a)},switchToPrevScene:function(a,b,c){var d=this.getSceneIndex(this.currentScene);this.getNumScenes()<=1||d===0||(c?this.easeInOutRandom(d-1,d,a,b):this.setScene(d-1))},switchToNextScene:function(a, +b,c){var d=this.getSceneIndex(this.currentScene);this.getNumScenes()<=1||d===this.getNumScenes()-1||(c?this.easeInOutRandom(d+1,d,a,b):this.setScene(d+1))},mouseEnter:function(){},mouseExit:function(){},mouseMove:function(){},mouseDown:function(){},mouseUp:function(){},mouseDrag:function(){},easeEnd:function(a,b){b?(this.currentScene=a,this.currentScene.activated()):a.setExpired(true);a.mouseEnabled=true;a.emptyBehaviorList()},getSceneIndex:function(a){for(var b=0;b500&&(b=500);if(this.onRenderStart)this.onRenderStart(b);this.render(b);this.debugInfo&&this.debugInfo(this.statistics);this.timeline=a;if(this.onRenderEnd)this.onRenderEnd(b)}, +endLoop:function(){},setClear:function(a){this.clear=a;if(this.clear===CAAT.Director.CLEAR_DIRTY_RECTS)this.dirtyRectsEnabled=true;return this},getAudioManager:function(){return this.audioManager},cumulateOffset:function(a,b,c){var d=c+"Left";c+="Top";for(var e=0,f=0,g;navigator.browser!=="iOS"&&a&&a.style;)if(g=a.currentStyle?a.currentStyle.position:(g=(a.ownerDocument.defaultView||a.ownerDocument.parentWindow).getComputedStyle(a,null))?g.getPropertyValue("position"):null,/^(fixed)$/.test(g))break; +else e+=a[d],f+=a[c],a=a[b];return{x:e,y:f,style:g}},getOffset:function(a){var b=this.cumulateOffset(a,"offsetParent","offset");return b.style==="fixed"?(a=this.cumulateOffset(a,a.parentNode?"parentNode":"parentElement","scroll"),{x:b.x+a.x,y:b.y+a.y}):{x:b.x,y:b.y}},getCanvasCoord:function(a,b){var c=0,d=0;if(!b)b=window.event;if(b.pageX||b.pageY)c=b.pageX,d=b.pageY;else if(b.clientX||b.clientY)c=b.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,d=b.clientY+document.body.scrollTop+ +document.documentElement.scrollTop;var e=this.getOffset(b.target);c-=e.x;d-=e.y;d=new CAAT.Point(c,d);this.modelViewMatrixI.transformCoord(d);c=d.x;d=d.y;a.set(c,d);this.screenMousePoint.set(c,d)},__mouseDownHandler:function(a){if(this.dragging&&this.lastSelectedActor)this.__mouseUpHandler(a);else{this.getCanvasCoord(this.mousePoint,a);this.isMouseDown=true;var b=this.findActorAtPosition(this.mousePoint);if(null!==b){var c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y, +0));b.mouseDown((new CAAT.MouseEvent).init(c.x,c.y,a,b,new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y)))}this.lastSelectedActor=b}},__mouseUpHandler:function(a){this.isMouseDown=false;this.getCanvasCoord(this.mousePoint,a);var b=null,c=this.lastSelectedActor;null!==c&&(b=c.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),c.actionPerformed&&c.contains(b.x,b.y)&&c.actionPerformed(a),c.mouseUp((new CAAT.MouseEvent).init(b.x,b.y,a,c,this.screenMousePoint, +this.currentScene.time)));!this.dragging&&null!==c&&c.contains(b.x,b.y)&&c.mouseClick((new CAAT.MouseEvent).init(b.x,b.y,a,c,this.screenMousePoint,this.currentScene.time));this.in_=this.dragging=false},__mouseMoveHandler:function(a){this.getCanvasCoord(this.mousePoint,a);var b,c;if(this.isMouseDown&&null!==this.lastSelectedActor){b=this.lastSelectedActor;c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0));this.dragging=true;var d=b.x,e=b.y;b.mouseDrag((new CAAT.MouseEvent).init(c.x, +c.y,a,b,new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y),this.currentScene.time));this.prevMousePoint.x=c.x;this.prevMousePoint.y=c.y;if(d===b.x&&e===b.y){d=b.contains(c.x,c.y);if(this.in_&&!d)b.mouseExit((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)),this.in_=false;if(!this.in_&&d)b.mouseEnter((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)),this.in_=true}}else this.in_=true,b=this.findActorAtPosition(this.mousePoint), +b!==this.lastSelectedActor&&(null!==this.lastSelectedActor&&(c=this.lastSelectedActor.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),this.lastSelectedActor.mouseExit((new CAAT.MouseEvent).init(c.x,c.y,a,this.lastSelectedActor,this.screenMousePoint,this.currentScene.time))),null!==b&&(c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),b.mouseEnter((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)))), +c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),null!==b&&b.mouseMove((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)),this.lastSelectedActor=b},__mouseOutHandler:function(a){if(null!==this.lastSelectedActor){this.getCanvasCoord(this.mousePoint,a);var b=new CAAT.Point(this.mousePoint.x,this.mousePoint.y,0);this.lastSelectedActor.viewToModel(b);a=(new CAAT.MouseEvent).init(b.x,b.y,a,this.lastSelectedActor,this.screenMousePoint, +this.currentScene.time);this.lastSelectedActor.mouseExit(a);this.lastSelectedActor.mouseOut(a);if(!this.dragging)this.lastSelectedActor=null}else this.in_=this.isMouseDown=false},__mouseOverHandler:function(a){var b,c;this.getCanvasCoord(this.mousePoint,a);null==this.lastSelectedActor?(b=this.findActorAtPosition(this.mousePoint),null!==b&&(c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),a=(new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time), +b.mouseOver(a),b.mouseEnter(a)),this.lastSelectedActor=b):(b=this.lastSelectedActor,c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),a=(new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time),b.mouseOver(a),b.mouseEnter(a))},__mouseDBLClickHandler:function(a){this.getCanvasCoord(this.mousePoint,a);null!==this.lastSelectedActor&&this.lastSelectedActor.mouseDblClick((new CAAT.MouseEvent).init(this.mousePoint.x,this.mousePoint.y,a,this.lastSelectedActor, +this.screenMousePoint,this.currentScene.time))},__touchStartHandler:function(a){a.preventDefault();a=a.targetTouches[0];this.__mouseDownHandler(a)},__touchEndHandler:function(a){a.preventDefault();a=a.changedTouches[0];this.__mouseUpHandler(a)},__touchMoveHandler:function(a){a.preventDefault();if(!this.gesturing)for(var b=0;b>0)*e;var k=i+(d/h>>0)*f,m=g+e,n=k+f;g=(new CAAT.SpriteImageHelper(g,k,m-g,n-k,j.width,j.height)).setGL(g/j.width,k/j.height,m/j.width,n/j.height);this.mapInfo[d]=g}}else for(d=0;d0&&(g-=e);var h=this.offsetY%f;h>0&&(h-=f);var e=((this.ownerActor.width-g)/e>>0)+1,f=((this.ownerActor.height-h)/f>>0)+1,i,j;for(i=0;i>0,d+h+i* -b.height>>0,b.width,b.height)},paintInvertedH:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate((c|0)+b.width,d|0);a.scale(-1,1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintInvertedV:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate(c|0,d+b.height|0);a.scale(1,-1);a.drawImage(this.image,b.x,b.y,b.width, -b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintInvertedHV:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate(c|0,d+b.height|0);a.scale(1,-1);a.translate(b.width,0);a.scale(-1,1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintN:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a.ctx.drawImage(this.image, -b.x,b.y,b.width,b.height,this.offsetX+c>>0,this.offsetY+d>>0,b.width,b.height);return this},paintScaled:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a.ctx.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX+c>>0,this.offsetY+d>>0,this.ownerActor.width,this.ownerActor.height);return this},getCurrentSpriteImageCSSPosition:function(){var a=this.mapInfo[this.spriteIndex];return"-"+(a.x-this.offsetX)+"px -"+(a.y-this.offsetY)+"px "+(this.transformation===this.TR_TILE? -"":"no-repeat")},getNumImages:function(){return this.rows*this.columns},setUV:function(a,b){var c=this.image;if(c.__texturePage){var d=b,e=this.mapInfo[this.spriteIndex],f=e.u,g=e.v,h=e.u1,e=e.v1;if(this.offsetX||this.offsetY)f=c.__texturePage,g=-this.offsetY/f.height,h=(this.ownerActor.width-this.offsetX)/f.width,e=(this.ownerActor.height-this.offsetY)/f.height,f=-this.offsetX/f.width+c.__u,g+=c.__v,h+=c.__u,e+=c.__v;c.inverted?(a[d++]=h,a[d++]=g,a[d++]=h,a[d++]=e,a[d++]=f,a[d++]=e,a[d++]=f,a[d++]= -g):(a[d++]=f,a[d++]=g,a[d++]=h,a[d++]=g,a[d++]=h,a[d++]=e,a[d++]=f,a[d++]=e)}},setChangeFPS:function(a){this.changeFPS=a;return this},setSpriteTransformation:function(a){this.transformation=a;switch(a){case this.TR_FLIP_HORIZONTAL:this.paint=this.paintInvertedH;break;case this.TR_FLIP_VERTICAL:this.paint=this.paintInvertedV;break;case this.TR_FLIP_ALL:this.paint=this.paintInvertedHV;break;case this.TR_FIXED_TO_SIZE:this.paint=this.paintScaled;break;case this.TR_TILE:this.paint=this.paintTiled;break; -default:this.paint=this.paintN}return this},setAnimationImageIndex:function(a){this.animationImageIndex=a;this.spriteIndex=a[0];return this},setSpriteIndex:function(a){this.spriteIndex=a;return this},setSpriteIndexAtTime:function(a){if(this.animationImageIndex.length>1)this.prevAnimationTime===-1?(this.prevAnimationTime=a,this.spriteIndex=0):(a-=this.prevAnimationTime,a/=this.changeFPS,a%=this.animationImageIndex.length,this.spriteIndex=this.animationImageIndex[Math.floor(a)])},getMapInfo:function(a){return this.mapInfo[a]}, -initializeFromMap:function(a,b){this.initialize(a,1,1);var c,d,e=0;for(c in b)d=b[c],d=new CAAT.SpriteImageHelper(d.x,d.y,d.width,d.height,a.width,a.height),this.mapInfo[c]=d,e||this.setAnimationImageIndex([c]),e++;return this},initializeAsGlyphDesigner:function(a,b){this.initialize(a,1,1);var c,d,e=0;for(c in b){var f=b[c];d=new CAAT.SpriteImageHelper(f.x,f.y,f.width,f.height,a.width,a.height);d.xoffset=typeof f.xoffset==="undefined"?0:f.xoffset;d.yoffset=typeof f.yoffset==="undefined"?0:f.yoffset; -d.xadvance=typeof f.xadvance==="undefined"?f.width:f.xadvance;this.mapInfo[c]=d;e||this.setAnimationImageIndex([c]);e++}return this},initializeAsFontMap:function(a,b){this.initialize(a,1,1);for(var c,d=0,e=0;e>0,f=0;fa&&(a=c)}return this.fontHeight=a},drawString:function(a,b,c,d){for(var e,f,g=b.split(""),b=0;b=this.duration?(this.remove=true,this.callback_timeout&&this.callback_timeout(a,b,this)):this.callback_tick&&this.callback_tick(a, +g=new CAAT.SpriteImageHelper(e,f,this.singleWidth,this.singleHeight,a.width,a.height),this.mapInfo[d]=g;return this},paintTiled:function(a,b){this.setSpriteIndexAtTime(b);var c=this.mapInfo[this.spriteIndex],d=new CAAT.Rectangle;this.ownerActor.AABB.intersect(a.AABB,d);var e=this.getWidth(),f=this.getHeight(),g=(this.offsetX-this.ownerActor.x)%e;g>0&&(g-=e);var h=(this.offsetY-this.ownerActor.y)%f;h>0&&(h-=f);var e=((d.width-g)/e>>0)+1,f=((d.height-h)/f>>0)+1,i,j,k=a.ctx;for(i=0;i>0,d.y-this.ownerActor.y+h+i*c.height>>0,c.width,c.height)},paintInvertedH:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate((c|0)+b.width,d|0);a.scale(-1,1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintInvertedV:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex]; +a=a.ctx;a.save();a.translate(c|0,d+b.height|0);a.scale(1,-1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintInvertedHV:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate(c|0,d+b.height|0);a.scale(1,-1);a.translate(b.width,0);a.scale(-1,1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this}, +paintN:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a.ctx.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX+c>>0,this.offsetY+d>>0,b.width,b.height);return this},paintScaled:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a.ctx.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX+c>>0,this.offsetY+d>>0,this.ownerActor.width,this.ownerActor.height);return this},getCurrentSpriteImageCSSPosition:function(){var a=this.mapInfo[this.spriteIndex]; +return"-"+(a.x-this.offsetX)+"px -"+(a.y-this.offsetY)+"px "+(this.transformation===this.TR_TILE?"":"no-repeat")},getNumImages:function(){return this.rows*this.columns},setUV:function(a,b){var c=this.image;if(c.__texturePage){var d=b,e=this.mapInfo[this.spriteIndex],f=e.u,g=e.v,h=e.u1,e=e.v1;if(this.offsetX||this.offsetY)f=c.__texturePage,g=-this.offsetY/f.height,h=(this.ownerActor.width-this.offsetX)/f.width,e=(this.ownerActor.height-this.offsetY)/f.height,f=-this.offsetX/f.width+c.__u,g+=c.__v, +h+=c.__u,e+=c.__v;c.inverted?(a[d++]=h,a[d++]=g,a[d++]=h,a[d++]=e,a[d++]=f,a[d++]=e,a[d++]=f,a[d++]=g):(a[d++]=f,a[d++]=g,a[d++]=h,a[d++]=g,a[d++]=h,a[d++]=e,a[d++]=f,a[d++]=e)}},setChangeFPS:function(a){this.changeFPS=a;return this},setSpriteTransformation:function(a){this.transformation=a;switch(a){case this.TR_FLIP_HORIZONTAL:this.paint=this.paintInvertedH;break;case this.TR_FLIP_VERTICAL:this.paint=this.paintInvertedV;break;case this.TR_FLIP_ALL:this.paint=this.paintInvertedHV;break;case this.TR_FIXED_TO_SIZE:this.paint= +this.paintScaled;break;case this.TR_TILE:this.paint=this.paintTiled;break;default:this.paint=this.paintN}return this},setAnimationImageIndex:function(a){this.animationImageIndex=a;this.spriteIndex=a[0];return this},setSpriteIndex:function(a){this.spriteIndex=a;return this},setSpriteIndexAtTime:function(a){if(this.animationImageIndex.length>1)this.prevAnimationTime===-1?(this.prevAnimationTime=a,this.spriteIndex=0):(a-=this.prevAnimationTime,a/=this.changeFPS,a%=this.animationImageIndex.length,this.spriteIndex= +this.animationImageIndex[Math.floor(a)])},getMapInfo:function(a){return this.mapInfo[a]},initializeFromMap:function(a,b){this.initialize(a,1,1);var c,d,e=0;for(c in b)d=b[c],d=new CAAT.SpriteImageHelper(d.x,d.y,d.width,d.height,a.width,a.height),this.mapInfo[c]=d,e||this.setAnimationImageIndex([c]),e++;return this},initializeAsGlyphDesigner:function(a,b){this.initialize(a,1,1);var c,d,e=0;for(c in b){var f=b[c];d=new CAAT.SpriteImageHelper(f.x,f.y,f.width,f.height,a.width,a.height);d.xoffset=typeof f.xoffset=== +"undefined"?0:f.xoffset;d.yoffset=typeof f.yoffset==="undefined"?0:f.yoffset;d.xadvance=typeof f.xadvance==="undefined"?f.width:f.xadvance;this.mapInfo[c]=d;e||this.setAnimationImageIndex([c]);e++}return this},initializeAsFontMap:function(a,b){this.initialize(a,1,1);for(var c,d=0,e=0;e>0,f=0;fa&&(a=c)}return this.fontHeight=a},drawString:function(a,b,c,d){for(var e, +f,g=b.split(""),b=0;b=this.duration?(this.remove=true,this.callback_timeout&&this.callback_timeout(a,b,this)):this.callback_tick&&this.callback_tick(a, b,this);return this},reset:function(a){this.remove=false;this.startTime=a;this.scene.ensureTimerTask(this);return this},cancel:function(){this.remove=true;null!=this.callback_cancel&&this.callback_cancel(this.scene.time,this.scene.time-this.startTime,this);return this}}})();(function(){CAAT.Scene=function(){CAAT.Scene.superclass.constructor.call(this);this.timerList=[];this.style("overflow","hidden");return this};CAAT.Scene.prototype={easeContainerBehaviour:null,easeContainerBehaviourListener:null,easeIn:false,EASE_ROTATION:1,EASE_SCALE:2,EASE_TRANSLATE:3,timerList:null,timerSequence:0,paused:false,isPaused:function(){return this.paused},setPaused:function(a){this.paused=a},checkTimers:function(a){for(var b=this.timerList.length-1;b>=0;)this.timerList[b].remove||this.timerList[b].checkTask(a), b--},ensureTimerTask:function(a){this.hasTimer(a)||this.timerList.push(a);return this},hasTimer:function(a){for(var b=this.timerList.length-1;b>=0;){if(this.timerList[b]===a)return true;b--}return false},createTimer:function(a,b,c,d,e){a=(new CAAT.TimerTask).create(a,b,c,d,e);a.taskId=this.timerSequence++;a.sceneTime=this.time;a.scene=this;this.timerList.push(a);return a},removeExpiredTimers:function(){var a;for(a=0;a 0 ) { xoff= xoff-w; } - var yoff= this.offsetY % h; + var yoff= (this.offsetY-this.ownerActor.y) % h; if ( yoff> 0 ) { yoff= yoff-h; } - var nw= (((this.ownerActor.width-xoff)/w)>>0)+1; - var nh= (((this.ownerActor.height-yoff)/h)>>0)+1; + var nw= (((r.width-xoff)/w)>>0)+1; + var nh= (((r.height-yoff)/h)>>0)+1; var i,j; var ctx= director.ctx; for( i=0; i>0, (y+yoff+i*el.height)>>0, + (r.x-this.ownerActor.x+xoff+j*el.width)>>0, (r.y-this.ownerActor.y+yoff+i*el.height)>>0, el.width, el.height); } } diff --git a/build/caat-min.js b/build/caat-min.js index b6faa76c..feee58fb 100644 --- a/build/caat-min.js +++ b/build/caat-min.js @@ -22,11 +22,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Version: 0.3 build: 180 +Version: 0.3 build: 208 Created on: -DATE: 2012-02-20 -TIME: 23:55:10 +DATE: 2012-02-23 +TIME: 17:03:41 */ @@ -143,11 +143,11 @@ a;this.dirty=true;return this},setRotationAnchored:function(a,b,c){this.rotation b){this.tAnchorX=a;this.tAnchorY=b;return this},setPositionAnchored:function(a,b,c,d){this.setLocation(a,b);this.tAnchorX=c;this.tAnchorY=d;return this},isInAnimationFrame:function(a){if(this.expired)return false;if(this.duration===Number.MAX_VALUE)return this.start_time<=a;return a>=this.start_time+this.duration?(this.expired||this.setExpired(a),false):this.start_time<=a&&a=0&&b>=0&&a0&&CAAT.DEBUG&&CAAT.DEBUG_DIRTYRECTS){f.beginPath();this.nDirtyRects=0;d=this.cDirtyRects;for(c=0;c=this.dirtyRects.length)for(b=0;b<32;b++)this.dirtyRects.push(new CAAT.Rectangle);b=this.dirtyRects[this.dirtyRectsIndex];b.x=a.x;b.y=a.y;b.x1=a.x1;b.y1=a.y1;b.width=a.width;b.height=a.height;this.cDirtyRects.push(b)}},renderToContext:function(a,b){if(b.isInAnimationFrame(this.time)){a.globalAlpha=1;a.globalCompositeOperation="source-over";a.clearRect(0,0,this.width,this.height);a.setTransform(1,0,0,0,1,0);var c=this.ctx,d=this.crc; -this.ctx=this.crc=a;a.save();var e=this.worldModelViewMatrix;this.worldModelViewMatrix=new CAAT.Matrix;this.wdirty=true;b.animate(this,b.time);if(b.onRenderStart)b.onRenderStart(b.time);b.paintActor(this,b.time);if(b.onRenderEnd)b.onRenderEnd(b.time);this.worldModelViewMatrix=e;a.restore();this.ctx=c;this.crc=d}},addScene:function(a){a.setBounds(0,0,this.width,this.height);this.scenes.push(a);a.setEaseListener(this);null===this.currentScene&&this.setScene(0)},getNumScenes:function(){return this.scenes.length}, -easeInOut:function(a,b,c,d,e,f,g,h,i,j){if(a!==this.getCurrentSceneIndex()){a=this.scenes[a];d=this.scenes[d];if(!this.glEnabled&&!navigator.browser==="iOS")this.worldModelViewMatrix.transformRenderingContext(this.transitionScene.ctx),this.renderToContext(this.transitionScene.ctx,d),d=this.transitionScene;a.setExpired(false);d.setExpired(false);a.mouseEnabled=false;d.mouseEnabled=false;a.resetTransform();d.resetTransform();a.setLocation(0,0);d.setLocation(0,0);a.alpha=1;d.alpha=1;b===CAAT.Scene.prototype.EASE_ROTATION? -a.easeRotationIn(g,h,c,i):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,g,h,c,i):a.easeTranslationIn(g,h,c,i);e===CAAT.Scene.prototype.EASE_ROTATION?d.easeRotationOut(g,h,f,j):e===CAAT.Scene.prototype.EASE_SCALE?d.easeScaleOut(0,g,h,f,j):d.easeTranslationOut(g,h,f,j);this.childrenList=[];this.addChild(d);this.addChild(a)}},easeInOutRandom:function(a,b,c,d){var e=Math.random(),f=Math.random(),g;e<0.33?(e=CAAT.Scene.prototype.EASE_ROTATION,g=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)): -e<0.66?(e=CAAT.Scene.prototype.EASE_SCALE,g=(new CAAT.Interpolator).createElasticOutInterpolator(1.1,0.4)):(e=CAAT.Scene.prototype.EASE_TRANSLATE,g=(new CAAT.Interpolator).createBounceOutInterpolator());var h;f<0.33?(f=CAAT.Scene.prototype.EASE_ROTATION,h=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):f<0.66?(f=CAAT.Scene.prototype.EASE_SCALE,h=(new CAAT.Interpolator).createExponentialOutInterpolator(4)):(f=CAAT.Scene.prototype.EASE_TRANSLATE,h=(new CAAT.Interpolator).createBounceOutInterpolator()); -this.easeInOut(a,e,Math.random()*8.99>>0,b,f,Math.random()*8.99>>0,c,d,g,h)},easeIn:function(a,b,c,d,e,f){a=this.scenes[a];b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(c,d,e,f):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,c,d,e,f):a.easeTranslationIn(c,d,e,f);this.childrenList=[];this.addChild(a);a.resetTransform();a.setLocation(0,0);a.alpha=1;a.mouseEnabled=false;a.setExpired(false)},setScene:function(a){a=this.scenes[a];this.childrenList=[];this.addChild(a);this.currentScene=a; -a.setExpired(false);a.mouseEnabled=true;a.resetTransform();a.setLocation(0,0);a.alpha=1;a.activated()},switchToScene:function(a,b,c,d){var e=this.getSceneIndex(this.currentScene);d?this.easeInOutRandom(a,e,b,c):this.setScene(a)},switchToPrevScene:function(a,b,c){var d=this.getSceneIndex(this.currentScene);this.getNumScenes()<=1||d===0||(c?this.easeInOutRandom(d-1,d,a,b):this.setScene(d-1))},switchToNextScene:function(a,b,c){var d=this.getSceneIndex(this.currentScene);this.getNumScenes()<=1||d===this.getNumScenes()- -1||(c?this.easeInOutRandom(d+1,d,a,b):this.setScene(d+1))},mouseEnter:function(){},mouseExit:function(){},mouseMove:function(){},mouseDown:function(){},mouseUp:function(){},mouseDrag:function(){},easeEnd:function(a,b){b?(this.currentScene=a,this.currentScene.activated()):a.setExpired(true);a.mouseEnabled=true;a.emptyBehaviorList()},getSceneIndex:function(a){for(var b=0;b500&&(b=500);if(this.onRenderStart)this.onRenderStart(b);this.render(b);this.debugInfo&&this.debugInfo(this.statistics);this.timeline=a;if(this.onRenderEnd)this.onRenderEnd(b)},endLoop:function(){},setClear:function(a){this.clear=a;if(this.clear===CAAT.Director.CLEAR_DIRTY_RECTS)this.dirtyRectsEnabled= -true;return this},getAudioManager:function(){return this.audioManager},cumulateOffset:function(a,b,c){var d=c+"Left";c+="Top";for(var e=0,f=0,g;navigator.browser!=="iOS"&&a&&a.style;)if(g=a.currentStyle?a.currentStyle.position:(g=(a.ownerDocument.defaultView||a.ownerDocument.parentWindow).getComputedStyle(a,null))?g.getPropertyValue("position"):null,/^(fixed)$/.test(g))break;else e+=a[d],f+=a[c],a=a[b];return{x:e,y:f,style:g}},getOffset:function(a){var b=this.cumulateOffset(a,"offsetParent","offset"); -return b.style==="fixed"?(a=this.cumulateOffset(a,a.parentNode?"parentNode":"parentElement","scroll"),{x:b.x+a.x,y:b.y+a.y}):{x:b.x,y:b.y}},getCanvasCoord:function(a,b){var c=0,d=0;if(!b)b=window.event;if(b.pageX||b.pageY)c=b.pageX,d=b.pageY;else if(b.clientX||b.clientY)c=b.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,d=b.clientY+document.body.scrollTop+document.documentElement.scrollTop;var e=this.getOffset(b.target);c-=e.x;d-=e.y;d=new CAAT.Point(c,d);this.modelViewMatrixI= -this.modelViewMatrix.getInverse();this.modelViewMatrixI.transformCoord(d);c=d.x;d=d.y;a.set(c,d);this.screenMousePoint.set(c,d)},__mouseDownHandler:function(a){if(this.dragging&&this.lastSelectedActor)this.__mouseUpHandler(a);else{this.getCanvasCoord(this.mousePoint,a);this.isMouseDown=true;var b=this.findActorAtPosition(this.mousePoint);if(null!==b){var c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0));b.mouseDown((new CAAT.MouseEvent).init(c.x,c.y,a,b,new CAAT.Point(this.screenMousePoint.x, -this.screenMousePoint.y)))}this.lastSelectedActor=b}},__mouseUpHandler:function(a){this.isMouseDown=false;this.getCanvasCoord(this.mousePoint,a);var b=null,c=this.lastSelectedActor;null!==c&&(b=c.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),c.actionPerformed&&c.contains(b.x,b.y)&&c.actionPerformed(a),c.mouseUp((new CAAT.MouseEvent).init(b.x,b.y,a,c,this.screenMousePoint,this.currentScene.time)));!this.dragging&&null!==c&&c.contains(b.x,b.y)&&c.mouseClick((new CAAT.MouseEvent).init(b.x, -b.y,a,c,this.screenMousePoint,this.currentScene.time));this.in_=this.dragging=false},__mouseMoveHandler:function(a){this.getCanvasCoord(this.mousePoint,a);var b,c;if(this.isMouseDown&&null!==this.lastSelectedActor){b=this.lastSelectedActor;c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0));this.dragging=true;var d=b.x,e=b.y;b.mouseDrag((new CAAT.MouseEvent).init(c.x,c.y,a,b,new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y),this.currentScene.time));this.prevMousePoint.x= -c.x;this.prevMousePoint.y=c.y;if(d===b.x&&e===b.y){d=b.contains(c.x,c.y);if(this.in_&&!d)b.mouseExit((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)),this.in_=false;if(!this.in_&&d)b.mouseEnter((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)),this.in_=true}}else this.in_=true,b=this.findActorAtPosition(this.mousePoint),b!==this.lastSelectedActor&&(null!==this.lastSelectedActor&&(c=this.lastSelectedActor.viewToModel(new CAAT.Point(this.screenMousePoint.x, -this.screenMousePoint.y,0)),this.lastSelectedActor.mouseExit((new CAAT.MouseEvent).init(c.x,c.y,a,this.lastSelectedActor,this.screenMousePoint,this.currentScene.time))),null!==b&&(c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),b.mouseEnter((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)))),c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),null!==b&&b.mouseMove((new CAAT.MouseEvent).init(c.x,c.y, -a,b,this.screenMousePoint,this.currentScene.time)),this.lastSelectedActor=b},__mouseOutHandler:function(a){if(null!==this.lastSelectedActor){this.getCanvasCoord(this.mousePoint,a);var b=new CAAT.Point(this.mousePoint.x,this.mousePoint.y,0);this.lastSelectedActor.viewToModel(b);a=(new CAAT.MouseEvent).init(b.x,b.y,a,this.lastSelectedActor,this.screenMousePoint,this.currentScene.time);this.lastSelectedActor.mouseExit(a);this.lastSelectedActor.mouseOut(a);if(!this.dragging)this.lastSelectedActor=null}else this.in_= -this.isMouseDown=false},__mouseOverHandler:function(a){var b,c;this.getCanvasCoord(this.mousePoint,a);null==this.lastSelectedActor?(b=this.findActorAtPosition(this.mousePoint),null!==b&&(c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),a=(new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time),b.mouseOver(a),b.mouseEnter(a)),this.lastSelectedActor=b):(b=this.lastSelectedActor,c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y, -0)),a=(new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time),b.mouseOver(a),b.mouseEnter(a))},__mouseDBLClickHandler:function(a){this.getCanvasCoord(this.mousePoint,a);null!==this.lastSelectedActor&&this.lastSelectedActor.mouseDblClick((new CAAT.MouseEvent).init(this.mousePoint.x,this.mousePoint.y,a,this.lastSelectedActor,this.screenMousePoint,this.currentScene.time))},__touchStartHandler:function(a){a.preventDefault();a=a.targetTouches[0];this.__mouseDownHandler(a)}, -__touchEndHandler:function(a){a.preventDefault();a=a.changedTouches[0];this.__mouseUpHandler(a)},__touchMoveHandler:function(a){a.preventDefault();if(!this.gesturing)for(var b=0;b0&&CAAT.DEBUG&&CAAT.DEBUG_DIRTYRECTS){f.beginPath();this.nDirtyRects=0;d=this.cDirtyRects;for(c=0;c=this.dirtyRects.length)for(b=0;b<32;b++)this.dirtyRects.push(new CAAT.Rectangle);b=this.dirtyRects[this.dirtyRectsIndex];b.x=a.x;b.y=a.y;b.x1=a.x1;b.y1=a.y1;b.width=a.width;b.height=a.height;this.cDirtyRects.push(b)}},renderToContext:function(a,b){if(b.isInAnimationFrame(this.time)){a.globalAlpha=1;a.globalCompositeOperation="source-over";a.clearRect(0, +0,this.width,this.height);a.setTransform(1,0,0,0,1,0);var c=this.ctx,d=this.crc;this.ctx=this.crc=a;a.save();var e=this.worldModelViewMatrix;this.worldModelViewMatrix=new CAAT.Matrix;this.wdirty=true;b.animate(this,b.time);if(b.onRenderStart)b.onRenderStart(b.time);b.paintActor(this,b.time);if(b.onRenderEnd)b.onRenderEnd(b.time);this.worldModelViewMatrix=e;a.restore();this.ctx=c;this.crc=d}},addScene:function(a){a.setBounds(0,0,this.width,this.height);this.scenes.push(a);a.setEaseListener(this);null=== +this.currentScene&&this.setScene(0)},getNumScenes:function(){return this.scenes.length},easeInOut:function(a,b,c,d,e,f,g,h,i,j){if(a!==this.getCurrentSceneIndex()){a=this.scenes[a];d=this.scenes[d];if(!this.glEnabled&&!navigator.browser==="iOS")this.worldModelViewMatrix.transformRenderingContext(this.transitionScene.ctx),this.renderToContext(this.transitionScene.ctx,d),d=this.transitionScene;a.setExpired(false);d.setExpired(false);a.mouseEnabled=false;d.mouseEnabled=false;a.resetTransform();d.resetTransform(); +a.setLocation(0,0);d.setLocation(0,0);a.alpha=1;d.alpha=1;b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(g,h,c,i):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,g,h,c,i):a.easeTranslationIn(g,h,c,i);e===CAAT.Scene.prototype.EASE_ROTATION?d.easeRotationOut(g,h,f,j):e===CAAT.Scene.prototype.EASE_SCALE?d.easeScaleOut(0,g,h,f,j):d.easeTranslationOut(g,h,f,j);this.childrenList=[];this.addChild(d);this.addChild(a)}},easeInOutRandom:function(a,b,c,d){var e=Math.random(),f=Math.random(),g;e< +0.33?(e=CAAT.Scene.prototype.EASE_ROTATION,g=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):e<0.66?(e=CAAT.Scene.prototype.EASE_SCALE,g=(new CAAT.Interpolator).createElasticOutInterpolator(1.1,0.4)):(e=CAAT.Scene.prototype.EASE_TRANSLATE,g=(new CAAT.Interpolator).createBounceOutInterpolator());var h;f<0.33?(f=CAAT.Scene.prototype.EASE_ROTATION,h=(new CAAT.Interpolator).createExponentialInOutInterpolator(4)):f<0.66?(f=CAAT.Scene.prototype.EASE_SCALE,h=(new CAAT.Interpolator).createExponentialOutInterpolator(4)): +(f=CAAT.Scene.prototype.EASE_TRANSLATE,h=(new CAAT.Interpolator).createBounceOutInterpolator());this.easeInOut(a,e,Math.random()*8.99>>0,b,f,Math.random()*8.99>>0,c,d,g,h)},easeIn:function(a,b,c,d,e,f){a=this.scenes[a];b===CAAT.Scene.prototype.EASE_ROTATION?a.easeRotationIn(c,d,e,f):b===CAAT.Scene.prototype.EASE_SCALE?a.easeScaleIn(0,c,d,e,f):a.easeTranslationIn(c,d,e,f);this.childrenList=[];this.addChild(a);a.resetTransform();a.setLocation(0,0);a.alpha=1;a.mouseEnabled=false;a.setExpired(false)}, +setScene:function(a){a=this.scenes[a];this.childrenList=[];this.addChild(a);this.currentScene=a;a.setExpired(false);a.mouseEnabled=true;a.resetTransform();a.setLocation(0,0);a.alpha=1;a.activated()},switchToScene:function(a,b,c,d){var e=this.getSceneIndex(this.currentScene);d?this.easeInOutRandom(a,e,b,c):this.setScene(a)},switchToPrevScene:function(a,b,c){var d=this.getSceneIndex(this.currentScene);this.getNumScenes()<=1||d===0||(c?this.easeInOutRandom(d-1,d,a,b):this.setScene(d-1))},switchToNextScene:function(a, +b,c){var d=this.getSceneIndex(this.currentScene);this.getNumScenes()<=1||d===this.getNumScenes()-1||(c?this.easeInOutRandom(d+1,d,a,b):this.setScene(d+1))},mouseEnter:function(){},mouseExit:function(){},mouseMove:function(){},mouseDown:function(){},mouseUp:function(){},mouseDrag:function(){},easeEnd:function(a,b){b?(this.currentScene=a,this.currentScene.activated()):a.setExpired(true);a.mouseEnabled=true;a.emptyBehaviorList()},getSceneIndex:function(a){for(var b=0;b500&&(b=500);if(this.onRenderStart)this.onRenderStart(b);this.render(b);this.debugInfo&&this.debugInfo(this.statistics);this.timeline=a;if(this.onRenderEnd)this.onRenderEnd(b)}, +endLoop:function(){},setClear:function(a){this.clear=a;if(this.clear===CAAT.Director.CLEAR_DIRTY_RECTS)this.dirtyRectsEnabled=true;return this},getAudioManager:function(){return this.audioManager},cumulateOffset:function(a,b,c){var d=c+"Left";c+="Top";for(var e=0,f=0,g;navigator.browser!=="iOS"&&a&&a.style;)if(g=a.currentStyle?a.currentStyle.position:(g=(a.ownerDocument.defaultView||a.ownerDocument.parentWindow).getComputedStyle(a,null))?g.getPropertyValue("position"):null,/^(fixed)$/.test(g))break; +else e+=a[d],f+=a[c],a=a[b];return{x:e,y:f,style:g}},getOffset:function(a){var b=this.cumulateOffset(a,"offsetParent","offset");return b.style==="fixed"?(a=this.cumulateOffset(a,a.parentNode?"parentNode":"parentElement","scroll"),{x:b.x+a.x,y:b.y+a.y}):{x:b.x,y:b.y}},getCanvasCoord:function(a,b){var c=0,d=0;if(!b)b=window.event;if(b.pageX||b.pageY)c=b.pageX,d=b.pageY;else if(b.clientX||b.clientY)c=b.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,d=b.clientY+document.body.scrollTop+ +document.documentElement.scrollTop;var e=this.getOffset(b.target);c-=e.x;d-=e.y;d=new CAAT.Point(c,d);this.modelViewMatrixI.transformCoord(d);c=d.x;d=d.y;a.set(c,d);this.screenMousePoint.set(c,d)},__mouseDownHandler:function(a){if(this.dragging&&this.lastSelectedActor)this.__mouseUpHandler(a);else{this.getCanvasCoord(this.mousePoint,a);this.isMouseDown=true;var b=this.findActorAtPosition(this.mousePoint);if(null!==b){var c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y, +0));b.mouseDown((new CAAT.MouseEvent).init(c.x,c.y,a,b,new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y)))}this.lastSelectedActor=b}},__mouseUpHandler:function(a){this.isMouseDown=false;this.getCanvasCoord(this.mousePoint,a);var b=null,c=this.lastSelectedActor;null!==c&&(b=c.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),c.actionPerformed&&c.contains(b.x,b.y)&&c.actionPerformed(a),c.mouseUp((new CAAT.MouseEvent).init(b.x,b.y,a,c,this.screenMousePoint, +this.currentScene.time)));!this.dragging&&null!==c&&c.contains(b.x,b.y)&&c.mouseClick((new CAAT.MouseEvent).init(b.x,b.y,a,c,this.screenMousePoint,this.currentScene.time));this.in_=this.dragging=false},__mouseMoveHandler:function(a){this.getCanvasCoord(this.mousePoint,a);var b,c;if(this.isMouseDown&&null!==this.lastSelectedActor){b=this.lastSelectedActor;c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0));this.dragging=true;var d=b.x,e=b.y;b.mouseDrag((new CAAT.MouseEvent).init(c.x, +c.y,a,b,new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y),this.currentScene.time));this.prevMousePoint.x=c.x;this.prevMousePoint.y=c.y;if(d===b.x&&e===b.y){d=b.contains(c.x,c.y);if(this.in_&&!d)b.mouseExit((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)),this.in_=false;if(!this.in_&&d)b.mouseEnter((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)),this.in_=true}}else this.in_=true,b=this.findActorAtPosition(this.mousePoint), +b!==this.lastSelectedActor&&(null!==this.lastSelectedActor&&(c=this.lastSelectedActor.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),this.lastSelectedActor.mouseExit((new CAAT.MouseEvent).init(c.x,c.y,a,this.lastSelectedActor,this.screenMousePoint,this.currentScene.time))),null!==b&&(c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),b.mouseEnter((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)))), +c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),null!==b&&b.mouseMove((new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time)),this.lastSelectedActor=b},__mouseOutHandler:function(a){if(null!==this.lastSelectedActor){this.getCanvasCoord(this.mousePoint,a);var b=new CAAT.Point(this.mousePoint.x,this.mousePoint.y,0);this.lastSelectedActor.viewToModel(b);a=(new CAAT.MouseEvent).init(b.x,b.y,a,this.lastSelectedActor,this.screenMousePoint, +this.currentScene.time);this.lastSelectedActor.mouseExit(a);this.lastSelectedActor.mouseOut(a);if(!this.dragging)this.lastSelectedActor=null}else this.in_=this.isMouseDown=false},__mouseOverHandler:function(a){var b,c;this.getCanvasCoord(this.mousePoint,a);null==this.lastSelectedActor?(b=this.findActorAtPosition(this.mousePoint),null!==b&&(c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),a=(new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time), +b.mouseOver(a),b.mouseEnter(a)),this.lastSelectedActor=b):(b=this.lastSelectedActor,c=b.viewToModel(new CAAT.Point(this.screenMousePoint.x,this.screenMousePoint.y,0)),a=(new CAAT.MouseEvent).init(c.x,c.y,a,b,this.screenMousePoint,this.currentScene.time),b.mouseOver(a),b.mouseEnter(a))},__mouseDBLClickHandler:function(a){this.getCanvasCoord(this.mousePoint,a);null!==this.lastSelectedActor&&this.lastSelectedActor.mouseDblClick((new CAAT.MouseEvent).init(this.mousePoint.x,this.mousePoint.y,a,this.lastSelectedActor, +this.screenMousePoint,this.currentScene.time))},__touchStartHandler:function(a){a.preventDefault();a=a.targetTouches[0];this.__mouseDownHandler(a)},__touchEndHandler:function(a){a.preventDefault();a=a.changedTouches[0];this.__mouseUpHandler(a)},__touchMoveHandler:function(a){a.preventDefault();if(!this.gesturing)for(var b=0;b>0)*e;var k=i+(d/h>>0)*f,l=g+e,n=k+f;g=(new CAAT.SpriteImageHelper(g,k,l-g,n-k,j.width,j.height)).setGL(g/j.width,k/j.height,l/j.width,n/j.height);this.mapInfo[d]=g}}else for(d=0;d0&&(g-=e);var h=this.offsetY%f;h>0&&(h-=f);var e=((this.ownerActor.width-g)/e>>0)+1,f=((this.ownerActor.height-h)/f>>0)+1,i,j;for(i=0;i>0,d+h+i* -b.height>>0,b.width,b.height)},paintInvertedH:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate((c|0)+b.width,d|0);a.scale(-1,1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintInvertedV:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate(c|0,d+b.height|0);a.scale(1,-1);a.drawImage(this.image,b.x,b.y,b.width, -b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintInvertedHV:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate(c|0,d+b.height|0);a.scale(1,-1);a.translate(b.width,0);a.scale(-1,1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintN:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a.ctx.drawImage(this.image, -b.x,b.y,b.width,b.height,this.offsetX+c>>0,this.offsetY+d>>0,b.width,b.height);return this},paintScaled:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a.ctx.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX+c>>0,this.offsetY+d>>0,this.ownerActor.width,this.ownerActor.height);return this},getCurrentSpriteImageCSSPosition:function(){var a=this.mapInfo[this.spriteIndex];return"-"+(a.x-this.offsetX)+"px -"+(a.y-this.offsetY)+"px "+(this.transformation===this.TR_TILE? -"":"no-repeat")},getNumImages:function(){return this.rows*this.columns},setUV:function(a,b){var c=this.image;if(c.__texturePage){var d=b,e=this.mapInfo[this.spriteIndex],f=e.u,g=e.v,h=e.u1,e=e.v1;if(this.offsetX||this.offsetY)f=c.__texturePage,g=-this.offsetY/f.height,h=(this.ownerActor.width-this.offsetX)/f.width,e=(this.ownerActor.height-this.offsetY)/f.height,f=-this.offsetX/f.width+c.__u,g+=c.__v,h+=c.__u,e+=c.__v;c.inverted?(a[d++]=h,a[d++]=g,a[d++]=h,a[d++]=e,a[d++]=f,a[d++]=e,a[d++]=f,a[d++]= -g):(a[d++]=f,a[d++]=g,a[d++]=h,a[d++]=g,a[d++]=h,a[d++]=e,a[d++]=f,a[d++]=e)}},setChangeFPS:function(a){this.changeFPS=a;return this},setSpriteTransformation:function(a){this.transformation=a;switch(a){case this.TR_FLIP_HORIZONTAL:this.paint=this.paintInvertedH;break;case this.TR_FLIP_VERTICAL:this.paint=this.paintInvertedV;break;case this.TR_FLIP_ALL:this.paint=this.paintInvertedHV;break;case this.TR_FIXED_TO_SIZE:this.paint=this.paintScaled;break;case this.TR_TILE:this.paint=this.paintTiled;break; -default:this.paint=this.paintN}return this},setAnimationImageIndex:function(a){this.animationImageIndex=a;this.spriteIndex=a[0];return this},setSpriteIndex:function(a){this.spriteIndex=a;return this},setSpriteIndexAtTime:function(a){if(this.animationImageIndex.length>1)this.prevAnimationTime===-1?(this.prevAnimationTime=a,this.spriteIndex=0):(a-=this.prevAnimationTime,a/=this.changeFPS,a%=this.animationImageIndex.length,this.spriteIndex=this.animationImageIndex[Math.floor(a)])},getMapInfo:function(a){return this.mapInfo[a]}, -initializeFromMap:function(a,b){this.initialize(a,1,1);var c,d,e=0;for(c in b)d=b[c],d=new CAAT.SpriteImageHelper(d.x,d.y,d.width,d.height,a.width,a.height),this.mapInfo[c]=d,e||this.setAnimationImageIndex([c]),e++;return this},initializeAsGlyphDesigner:function(a,b){this.initialize(a,1,1);var c,d,e=0;for(c in b){var f=b[c];d=new CAAT.SpriteImageHelper(f.x,f.y,f.width,f.height,a.width,a.height);d.xoffset=typeof f.xoffset==="undefined"?0:f.xoffset;d.yoffset=typeof f.yoffset==="undefined"?0:f.yoffset; -d.xadvance=typeof f.xadvance==="undefined"?f.width:f.xadvance;this.mapInfo[c]=d;e||this.setAnimationImageIndex([c]);e++}return this},initializeAsFontMap:function(a,b){this.initialize(a,1,1);for(var c,d=0,e=0;e>0,f=0;fa&&(a=c)}return this.fontHeight=a},drawString:function(a,b,c,d){for(var e,f,g=b.split(""),b=0;b=this.duration?(this.remove=true,this.callback_timeout&&this.callback_timeout(a,b,this)):this.callback_tick&&this.callback_tick(a, +g=new CAAT.SpriteImageHelper(e,f,this.singleWidth,this.singleHeight,a.width,a.height),this.mapInfo[d]=g;return this},paintTiled:function(a,b){this.setSpriteIndexAtTime(b);var c=this.mapInfo[this.spriteIndex],d=new CAAT.Rectangle;this.ownerActor.AABB.intersect(a.AABB,d);var e=this.getWidth(),f=this.getHeight(),g=(this.offsetX-this.ownerActor.x)%e;g>0&&(g-=e);var h=(this.offsetY-this.ownerActor.y)%f;h>0&&(h-=f);var e=((d.width-g)/e>>0)+1,f=((d.height-h)/f>>0)+1,i,j,k=a.ctx;for(i=0;i>0,d.y-this.ownerActor.y+h+i*c.height>>0,c.width,c.height)},paintInvertedH:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate((c|0)+b.width,d|0);a.scale(-1,1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintInvertedV:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex]; +a=a.ctx;a.save();a.translate(c|0,d+b.height|0);a.scale(1,-1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this},paintInvertedHV:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a=a.ctx;a.save();a.translate(c|0,d+b.height|0);a.scale(1,-1);a.translate(b.width,0);a.scale(-1,1);a.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX>>0,this.offsetY>>0,b.width,b.height);a.restore();return this}, +paintN:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a.ctx.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX+c>>0,this.offsetY+d>>0,b.width,b.height);return this},paintScaled:function(a,b,c,d){this.setSpriteIndexAtTime(b);b=this.mapInfo[this.spriteIndex];a.ctx.drawImage(this.image,b.x,b.y,b.width,b.height,this.offsetX+c>>0,this.offsetY+d>>0,this.ownerActor.width,this.ownerActor.height);return this},getCurrentSpriteImageCSSPosition:function(){var a=this.mapInfo[this.spriteIndex]; +return"-"+(a.x-this.offsetX)+"px -"+(a.y-this.offsetY)+"px "+(this.transformation===this.TR_TILE?"":"no-repeat")},getNumImages:function(){return this.rows*this.columns},setUV:function(a,b){var c=this.image;if(c.__texturePage){var d=b,e=this.mapInfo[this.spriteIndex],f=e.u,g=e.v,h=e.u1,e=e.v1;if(this.offsetX||this.offsetY)f=c.__texturePage,g=-this.offsetY/f.height,h=(this.ownerActor.width-this.offsetX)/f.width,e=(this.ownerActor.height-this.offsetY)/f.height,f=-this.offsetX/f.width+c.__u,g+=c.__v, +h+=c.__u,e+=c.__v;c.inverted?(a[d++]=h,a[d++]=g,a[d++]=h,a[d++]=e,a[d++]=f,a[d++]=e,a[d++]=f,a[d++]=g):(a[d++]=f,a[d++]=g,a[d++]=h,a[d++]=g,a[d++]=h,a[d++]=e,a[d++]=f,a[d++]=e)}},setChangeFPS:function(a){this.changeFPS=a;return this},setSpriteTransformation:function(a){this.transformation=a;switch(a){case this.TR_FLIP_HORIZONTAL:this.paint=this.paintInvertedH;break;case this.TR_FLIP_VERTICAL:this.paint=this.paintInvertedV;break;case this.TR_FLIP_ALL:this.paint=this.paintInvertedHV;break;case this.TR_FIXED_TO_SIZE:this.paint= +this.paintScaled;break;case this.TR_TILE:this.paint=this.paintTiled;break;default:this.paint=this.paintN}return this},setAnimationImageIndex:function(a){this.animationImageIndex=a;this.spriteIndex=a[0];return this},setSpriteIndex:function(a){this.spriteIndex=a;return this},setSpriteIndexAtTime:function(a){if(this.animationImageIndex.length>1)this.prevAnimationTime===-1?(this.prevAnimationTime=a,this.spriteIndex=0):(a-=this.prevAnimationTime,a/=this.changeFPS,a%=this.animationImageIndex.length,this.spriteIndex= +this.animationImageIndex[Math.floor(a)])},getMapInfo:function(a){return this.mapInfo[a]},initializeFromMap:function(a,b){this.initialize(a,1,1);var c,d,e=0;for(c in b)d=b[c],d=new CAAT.SpriteImageHelper(d.x,d.y,d.width,d.height,a.width,a.height),this.mapInfo[c]=d,e||this.setAnimationImageIndex([c]),e++;return this},initializeAsGlyphDesigner:function(a,b){this.initialize(a,1,1);var c,d,e=0;for(c in b){var f=b[c];d=new CAAT.SpriteImageHelper(f.x,f.y,f.width,f.height,a.width,a.height);d.xoffset=typeof f.xoffset=== +"undefined"?0:f.xoffset;d.yoffset=typeof f.yoffset==="undefined"?0:f.yoffset;d.xadvance=typeof f.xadvance==="undefined"?f.width:f.xadvance;this.mapInfo[c]=d;e||this.setAnimationImageIndex([c]);e++}return this},initializeAsFontMap:function(a,b){this.initialize(a,1,1);for(var c,d=0,e=0;e>0,f=0;fa&&(a=c)}return this.fontHeight=a},drawString:function(a,b,c,d){for(var e, +f,g=b.split(""),b=0;b=this.duration?(this.remove=true,this.callback_timeout&&this.callback_timeout(a,b,this)):this.callback_tick&&this.callback_tick(a, b,this);return this},reset:function(a){this.remove=false;this.startTime=a;this.scene.ensureTimerTask(this);return this},cancel:function(){this.remove=true;null!=this.callback_cancel&&this.callback_cancel(this.scene.time,this.scene.time-this.startTime,this);return this}}})();(function(){CAAT.Scene=function(){CAAT.Scene.superclass.constructor.call(this);this.timerList=[];this.fillStyle=null;return this};CAAT.Scene.prototype={easeContainerBehaviour:null,easeContainerBehaviourListener:null,easeIn:false,EASE_ROTATION:1,EASE_SCALE:2,EASE_TRANSLATE:3,timerList:null,timerSequence:0,paused:false,isPaused:function(){return this.paused},setPaused:function(a){this.paused=a},checkTimers:function(a){for(var b=this.timerList,c=b.length-1;c>=0;)b[c].remove||b[c].checkTask(a),c--},ensureTimerTask:function(a){this.hasTimer(a)|| this.timerList.push(a);return this},hasTimer:function(a){for(var b=this.timerList,c=b.length-1;c>=0;){if(b[c]===a)return true;c--}return false},createTimer:function(a,b,c,d,e){a=(new CAAT.TimerTask).create(a,b,c,d,e);a.taskId=this.timerSequence++;a.sceneTime=this.time;a.scene=this;this.timerList.push(a);return a},removeExpiredTimers:function(){var a,b=this.timerList;for(a=0;a=this.inputList.length&&(b=this.inputList.length-1);b=this.inputList[b];typeof c==="undefined"||c>=b.length?b.push(a):c<=0?b.unshift(a):b.splice(c,0,a);return this},emptyInputList:function(a){a<0?a=0:a>=this.inputList.length&&(a=this.inputList.length-1);this.inputList[a]=[];return this},removeActorFromInputList:function(a,b){if(typeof b==="undefined"){var c,d;for(c=0;c=this.inputList.length&&(b=this.inputList.length-1);e=this.inputList[b];for(d=0;d 0 ) { xoff= xoff-w; } - var yoff= this.offsetY % h; + var yoff= (this.offsetY-this.ownerActor.y) % h; if ( yoff> 0 ) { yoff= yoff-h; } - var nw= (((this.ownerActor.width-xoff)/w)>>0)+1; - var nh= (((this.ownerActor.height-yoff)/h)>>0)+1; + var nw= (((r.width-xoff)/w)>>0)+1; + var nh= (((r.height-yoff)/h)>>0)+1; var i,j; var ctx= director.ctx; for( i=0; i>0, (y+yoff+i*el.height)>>0, + (r.x-this.ownerActor.x+xoff+j*el.width)>>0, (r.y-this.ownerActor.y+yoff+i*el.height)>>0, el.width, el.height); } } @@ -13293,6 +13295,122 @@ CAAT.RegisterDirector= function __CAATGlobal_RegisterDirector(director) { ctx.fillStyle= this.fillStyle; ctx.fillRect(0,0,this.width,this.height ); } + }, + /** + * Find a pointed actor at position point. + * This method tries lo find the correctly pointed actor in two different ways. + * + first of all, if inputList is defined, it will look for an actor in it. + * + if no inputList is defined, it will traverse the scene graph trying to find a pointed actor. + * @param point + */ + findActorAtPosition : function(point) { + var i,j; + + var p= new CAAT.Point(); + + if ( this.inputList ) { + var il= this.inputList; + for( i=0; i number of lists. + */ + enableInputList : function( size ) { + this.inputList= []; + for( var i=0; i an actor instance + * @param index the inputList index to add the actor to. This value will be clamped to the number of + * available lists. + * @param position the position on the selected inputList to add the actor at. This value will be + * clamped to the number of available lists. + */ + addActorToInputList : function( actor, index, position ) { + if ( index<0 ) index=0; else if ( index>=this.inputList.length ) index= this.inputList.length-1; + var il= this.inputList[index]; + + if ( typeof position==="undefined" || position>=il.length ) { + il.push( actor ); + } else if (position<=0) { + il.unshift( actor ); + } else { + il.splice( position, 0, actor ); + } + + return this; + }, + + /** + * Remove all elements from an input list. + * @param index the inputList index to add the actor to. This value will be clamped to the number of + * available lists so take care when emptying a non existant inputList index since you could end up emptying + * an undesired input list. + */ + emptyInputList : function( index ) { + if ( index<0 ) index=0; else if ( index>=this.inputList.length ) index= this.inputList.length-1; + this.inputList[index]= []; + return this; + }, + + /** + * remove an actor from a given input list index. + * If no index is supplied, the actor will be removed from every input list. + * @param actor + * @param index an optional input list index. This value will be clamped to the number of + * available lists. + */ + removeActorFromInputList : function( actor, index ) { + if ( typeof index==="undefined" ) { + var i,j; + for( i=0; i=this.inputList.length ) index= this.inputList.length-1; + var il= this.inputList[index]; + for( j=0; jEbeyS{O9tH$>lC27eUJV{dQ+|Y-eU?p3R$Cg-WGjZ{ckZyzPOvJ@B>%-uA%T z9{BI{fHL2kx~ir#+fcJ*=UJOe@v;^9UVeTQ_&U@vm+e$=xcRN?#^@j1+;W+<(32~e zLb0(;u_0`)r&poB{6F-j?F`=PI|#eb;z`P$TVqb8IN@G5@7 zr_<-RH?=O-ofrOU;x?((m}eJ;mKk%rTdA$@u2^A$D8-a1%D;w{eOF5M)|(GK&}hmO zbGELQ7y36JiYt^N^1q@MiW5w!*c;&d!^2o#_a`YUtM%@)dbLfVv?ix7c^&GQ)3#)! z;~E^5lbu;B+p^X-;^(<<8!#oHST2hwwB!>@Sbx{Gv-85Z>rbl}+DrdyFWUY=(LH7T z9x9aVz4#|dX6eaklTQ~}9qzqo-$(zouE>w}maJrVtY*LY^#^ut=faHGnt@-m>y#hm z7GxQRyEt{NRk!F54O^6GKkww^oqZPWuYWCd-G%pCl{;RL@BOcp-KbF`<72Kn0-2KS zRJr|9?R9B?z7zl0M@bq&Z(Y*NAtg3_)k=kL6qi1J?zDJsC2*rJyK`QLIvUbPMro?$ z$Y<$j)^>TtnU8xfIWVo`)~%+7lvPl90$LTV_uV|#@##rvZ0CU|XA9~*|M_xb6WX)r zXrf26g>nU8jY6 zszc*O;jfZg(a*>1adh$;suQndizbJ>PgJgKQ;mg3Tf9yZDz)KNbq{(!8OE5Zd_q_f zV@ly_^a;6X&v0(uD$yk$uFa0xeD`?13P`Hslqsg2yOudbbv*s)(!kub?`_(g z_dtAb(go^grK7!I0PqZEV72||Z{p^;A9&Rm!<@Iyu#`hOv>kBnmw+mUetH*`5YxtMmCqWv>2Xt54@n&H}#+ zqQoP*eBmsjFQ18EeH`kwc@=O1)%SIEF^5ddjOSo(nb{jNmdf6LUD}fG#Q%O=%2H}P z5DkbBBo8nFM^bvRLvh_*E~gJZsoGTY4D+w8jF8;LcXGq!kk>~rAwLZKYi#zw?SyDtQ`_nk$S$>rJwv4Pj zVD;6Fvq_Pu0U{LGh~4G=RGZq(=TuGDmIQ2 zzFgtHUcWxMb?Z!UkfvwCqgl1O_N+!9U$a|P>#l_AR})v*9!q6s77<-L&~5vA%<*oE z54_{qy5tX34GTvz=Go=BDUfevf7avAo;yLb_TlpgBL z3RX4urM#RRxtahusbY(H55jL|bP+C22V(;$^Vf3&5O%eYB=T|FF< zKPC!@ekn&Mc8D_o06c>M5Md#0x3TrLrWW=xKzqkAnd;cYWR0lLuTQ&+I^+5FU3DFQ zz1?{Z>CzEAb7W2?~iw)-V8I#v>x1 zojSi`L+9L;{CcJKh?#R9?T1hTs94FyVnyk3|8DXs-ajY82bigV%?~;|abmB{0CXAT z?$GaH|Ic1Vk8G&B(MCx6koF z>qt#V4~x(+03fcIgd|-jCUOI{pr_xmJ@wmD`oeIlPt{#VT?_!~^D^paNIz7t=&>g_ zBKaQr7}A~4uy6(dNDqAu+l$*y-=1b`YZr>N*Jm8IdaBA}ogV~$fKk?$VcNDeh}T^L4DW3%3eGd=1sx+Z(4eV ziHocC1!$}NGwK7vf9^um(-Q~6sy5mfa-cA)`KG-qEji62$8FkFqs}htrB7LSOjpVy z@H0KcM{B|RPRJS(8#ei@&Dl!f@O9?QmV?)3kQi-Om_Z6Z@POi~tC|3|Q|U zZsE6mM1#rBjkY|wF2}v~=e`FLVpT6ZEJ^IB*j#%EOIQAt5RzzyZvt%r#vO#Q-cM(Z zdpCZtIqQ0HZ0>82w;TmZ{P{#tDZEaORXW)pK{W+2;u?TYD((=qUUgM%YXbE;;MbdN z*@{ZjxAyZpbmZc|GQ%Qfx|S6Y1$cWM>S##wU8mm)d=QbcRl@-AB@L+mG2mbepkV-# z2VY{VxgNLx!M?b;U@&0l2e^GVp2Zm_KY8IR`OIM}sygx0>AqkaYwuv2YR7L$nx1^D zPec;i+aPsQn_?StBCWmfJ^!%;O9ys)-1AxwSH3soUSdL;U;t>GKvTpbqkF27Zl0;@ z=O?(u%l*qXPl`#ke%-ri*iBW^+O>CEiY-~ZF)|YXq^vYmx*RV0UD&3U#j@S5)oX9$ z#S2u5JW z+=pUaAA|r=F9U!)%dJN>GEyoR z*cG?($8$l$>rh8S`k+Vg;r+0-OH5a@GCSD1TdhS=umupHWF{%;CI`8{z$EE1ZWd+K zFJof8KRhypnK2u+`7uREZZ8~_xv5q+elXPIbR(mOLDyq81znH+BX zXXm7|0|uzq5~Te9WiPg{#jNr8kTXXIxG~XHw&%kZy0*2gn>{+NUzO=KlOobmWCj4X zB0>wGRMq+2dPQVkzr#CJ#)^F^rNSUh&8zk;dK`#2xp_zE3>fJVkQM+807ulyF5b?6 z9Q7_eOxN-U@<3qt@!b_&A^8I`N!XkL*lRaqlaTmCY{A@6w}sX3texgxtNc{|+6-5< z)-KGVYH>DowkzA{rB-0z8SR_nzH-Z|q0I&X*A+~S{(Ge=jEyyTO}q72{!zK^IF=BS z)EC8Q6}0<0)G@bxaAw%B=!D4B0mJ~H&q4GB1HdIbFat2U zyisEO2Z_t7H_C1KIZa>6#?+G1y4Ec%yiXJn2^2;yB$<>I9)s4nZjVb(Nc)i!dlPu&zWIeqvu!jAC~wul@SAgWq=S)1i=JAOEful@TbTZ9-EwD&a7R^>-XH{*QehG z{1m)JW&o%aAe12HjawFETCFZg_1i74;4gr7c8{rot{j0}2+U@fU*Ub*N)*yP<~X2dfjqQ^Uak2n%m809@@a*8e32z|>SZ zJGW)$G`%vNsrUEs3_)jt#a5)Yy9Q{&P|lw2rQEqX|AC36(IQCp;Fhs709Qy@q~=wn zY)x6WxOty+-Sc!j4}44bc_)bV`Hi)vFbm@wOrdhsbQXEQ1f(Q~u#Gi8ryz2@|MWHr zyw5dqoB?<|{;}pFTL5RyXaVBm)1H3>%KZAesxI#i?HaHpGb88Vfp8S3-7WiNZ%Up;0-?ML(-37HIwaLq_f{mlaGGWL0#bm74|yRF}H13b=Z>jL#5?k zgx*p!nt}m^w(I037+7 zFsq7ho8~0~Il?W0wMh_s0E`210X$>!uskeF6+OX=ys8yeeIrg(CpISITI{}rAS`4T`d*HUTVS(NR`==mZ}6P6Di zsQbHgD!)xr6o|ciWkg6z5%pdLDN|G5H^ifFNeJ3981@n2M{|L@`rrJfBkOT-4%fcC zG6GAX5&voIvE!Pd-I&|ZR&3|eP=Rc&jS6MHqtweDv@R`=jca$}Hp$Ng?Jx8?`j)X^ zyX$|!&*k31*Jsaj_XOM5U?N*vqk(#RT;5vzm%_FvQ#duWP^jX9qf=P))MpG#04)P( zv@DzffTY)F&i;CQo$60k%t6he!5& z=1H`l`5);<@udOHx&C!o>ZG4!8 z0iZTyECX10_pWe-8<_r&!pZ%m=aK~pN$Dx{ED>G)gDum^`EC3+%GseY zR4K=&vZsB&VZ|6O01!+oet`iXV?bF8;Nv>#SYdWnVbxI>1HquJWYIVl9UH)+qCe#b zye4-&xgGP69baggxfxMS2|8O!WH*c zh;yxEBMg(|iGxYyWN-GkoB8Z&UH3kn0A!7{Z-Mu~hT3gd*<#oExY4K{fq3NkLxi7P zO}{BrO}3=Wc=-9kLlv4dD8QnBlJ;$ytUd6dudl^4g>h@9D7ArKSJ?Pn!@rIWF4VaPj%k8DOHvnOvE-tq>|m#dG)H2_}5Ou0+@ zeYO*eGVJxn{}*mui_!SGC8||^stRHGdei=7Jc!WM^U*@OCsnH~DPb}NS0AR)5IEVJ zPHD5tamKM@$8@g?X*cM<@*GgB7qheV7u)hO+DwEW8k|y+B|CMA%oHFD-yG04eD=E7 z^yE1;hPV5zC9@P;`w%{ysn?EMGGoD@SDELOUemal)y-iGrM+!P`DOqN`}$a4K2h7n zqAq^eBachDg<{;Q*cOF(C2wLzarVT}og<#USIgFxb^zcU01yMf&WLUv{~Pw@6}cQk z{i@Y9&L~Wk*)GeS+W(ks{%}F*#e+M98Ty|8XgZ$cL#8|<&z#Ihe2LlPWugTm-8;7?(sjHk_0*@Ya9Qb78s#RY$C~rmgZ=ue8Wm)Xq(#G7jiT4~=}m5ejGfkLwBTt#s$({TxUyG=e;7L-(lemqLH4enrhrHa8mZA z84$a%_7iTI?|?OZsP+LgN#FV15FPSDx8zoQtIgck34#z5!+`}u!K7w}U` zDJ{Z~o{PID-eFNqpe;byn+C8yY4^9^1(kwT#`*WU7yuA=HDNbCQ$46{qrgd%lF<)c z7anT8D%s~(BL3I~KnyM`TI8~#)ybOpIZ&Sa%-AUFQ>=9S{jwD7=^R0O%Fke5`UEkk-XcP5XK$e1DjetT^`%`l<0bGZ*`Vo>pEdjs< za=Os_fktg;Q}CiZD#rL#ui226#;MHZ3`#l(_4S{K5tqam{eU$03hlZw|pB{-9Xpv zCpaw;ICPWK$^$!&KZyim0LY~Ne->43Z%0RW5s`-*-gWtWv`)eg<`3}TZo>Iy8y~&W zL?;hjkn5~CPru)sT{U_vI5dFm{dlixPlJT2?>Qu}Vyb5>KJgw4k2|-b;`A*G6NdHW zh3hB$cypUud|Q%hM-_9rGiYcB4dIt7h3~NTgLO=$NPC2{N@AwFe<;VlO8!EZ{Gnc( zbNs@^I?TeI5DRsPjGWwOIxesndu=4e6{cGdbxd03;bmrPltuNP=XOCOpi(_e3XYiE zEoH{RMB}iKU+oVku?}0)ITORUG-F~@qQ0}!Zb${f8B!+E!rEN`^lbZ!|o2uU7f$vP;o8}l=NAr)u z@CB=zgE``H^!T>8yF?B3`|r$9*mL{y1Ur9J_1FU_|>P8@ly>eMHR z*Ad=#(Z04TEXMvqX^}>w0kF6IjkP)XG37VJ#fgiv|NK5e`>%a+9s3#i)!Hz!=_NzT ze`E4&eWy4xxBQeDE5GI_uzaR=Wo(7a6qfOTwWWeb7pW|qJ>GHCF^X{Q_|iyQYhyS_W8U7 zIuO!@HjptO5YfLqqbz%_Q6*}p$*<=^tK;|XMVX74&f{z`acONZPwnDNz{3k+%z1pQ z&SKD?=owWNYer_66!o}XPJN!lkO7nmkB>rxccM) z7Nka{u(vK_pD)^7g>9XC1%2_$$>Z$Opt1}`crxK9sUIr*OXm{V^e`LIb<^2XjWmyd zQ_PW37>GR0H<1|ee3vCH1tAQ-|AjUIhN6JWUZ!5%eto=GJiNiTev1z;Uv56KFU?K# zH4$|*8-%^2llgBZHdPu+YyYNe?|qv<%UMMH@r-hoF27rB(5Xni$JQ{we@_}7?z)AT z5~>@OhB}@+5q`AM`jF=TH3k}55!JT$KVatO%Nf_Sh(8-r$B>&1;RjwK4J493h)QNx z&nB_sVR3BPkTPmJB}rJJBEbO2Dt`)>-Cob;EQ~7^F%HI|a`?;kbHbdzFjZkztu?b) zsA86lrn4O!(J(G)rZfM+-83(X=h7zDB5P?v)aprC{7>iG07)_p3{&Dv_0M_gu&R{wj07!1Q{s~hv0q95yga04CS)jhE?$^jfwbRsN|>ahEUpR(YUk|J%R+H3X)sTdqvmYN|ZG>`c=S zYO_CF+A#d}%46wq7QiL^Pn#4|pUcnH{WzotgdZyW=^49eJXsj~E#p&?Btv26SdmN& zAQ(f;yE^Zw=O&Fu{Qehz0KCmL319*aytnSb^O>xx#&1SgavGb?iG5!SNA+?T`U8Ft z2@v&CrOcl;URSh<>e%xgC{LCwNjLLW&vX!chYT_groqgfu|Z?2H{-pt#gHEQYgpNL zSA0}-^F&UN*ca;m5>VZ!Jk+sa^Wu$&M`G;6|RAm;Iv09uB zq1V+P5JobqJaHZgE*q9m&QeX_#hO1?{pSEQIGq1oagD=wK73_%DBH8ppQWU&R-`ze zBZe^tMHN_*{9N-_1P&`Vt=%BUOJ;+LaKf*aI3QV&$`Dc}F51>dtx`JL3uXXE`u=Z_ zlaNr6|F@O_SkKN+DD*nUFRl8yv4xR`zD8iJ9SndrVDRJ?F!{j%1P(G0(j5>z^*KrS zu<(a*C5-(j4DZ1=vJQx=x1^1A$=tp-C+W@Y?Zsj;CYdg&pL5X4m1)B+eA=kk&V-<+ z|HRI6U&YIPp)EsB-u*hK8Gmw_&(`BdZExNSW$n{03dtYs>AdHuFxG>_55gb8|Ca!X zAM*|0^&7_+LHNh>AHKxRtHMrgtiiBkFr%|0Ll}rX#)pE1vO4@AO|11}48RTm%LtnB z$2CeAS6~9LlwfX>;`%!GXHM&WU2!#1mqZ7mj&=P3(X$6@??Nf}=~qqBSGcr6Xbqy{ zT5E^rPA{L?J^pBIqhzQ|6}|YVEaeaw^W{WpUW$ibxQj= z>;p*fmVi|#GK*Z6JxPWkgV5%=o(I6Q#7>CV(0RSLBh?8rZBHZFn zsXh=u#N_SvGU|xEqGo1BoAlM35G)Y5=7%c!5@!>Ra_B-byE0~iiGrW{oER{y17nT9 zyay)=Iv9W_dy^fJFW(`|)J@mqOkc%+K(fAsKxRN_bSV|8o^dnXzs&b~yk-S{VfF6> zNbPgBY-XPhS9eF?&P{CBg1M|gKqx!=@0+>U001BWNkl-IDF zx$amVm_FB4v#k%`-P5ZCn>wSMn4i=YC?CrK1YiKbkcu(M=O+CM8Vta~luTOY_cQePT59JmvVH2N7p z-&9TmzsvyOdno&6C^_|MAHt(bu(+6i*ltg;`%1gK!g|gZ;vX~5eUP=I*)VhtE+84G z3bA$wA`XDjg!cL(X#j+zAu#}05~yC*lAkw|p4BM8z@B*-bv#*Q&2XieQfD7yAd;b$ zxrLEheJe{`yq#Glbw=B15R*$?g7RZim07ICaqKU_#4$m0$)6k7`&6$Y z@;o`(d~>GkU`DiY#mB8n^zPw%;QdSqU(*NvIg}e(7aMe7*_<0w8Z~;Z(QqsBKTi17 zeGWpakJx6k8~ubIg;8G-{sh4W0q0iynu~BJ=9JLdWRw97!E;>syhDXHv)f~xTFvLF zw0w~T0*^WLd4oQ-q|3C>Mj^rd|nb;M6Sxb(_b;Ije-9T9%0{kcW(j_-`;zw;zM^)V4} zBH}bqsTBEHPD|;5unA-p77#lw^!vk%GsuYn0EY_@akIDQc}$4^1MIB#2~(8*cZti) zr(Ao#kQc8h7w>VO?Ihlr-3@BC^pu#X*`;|C<8aPI`s(W6FD~yFLhT#Url^JixU|BD z%^E(MqQnvam}~SaBz~y%A>nHvgXn9XxkqLIpp}E_e*#Mpmj0wA!ukFh27r%Qj6ICk z(?_4(lgoP3{HpaeTJTknruy0i##COjjh|b&6<410)J_jA7EXUV`A7J5AFCgnXFQAl zLpx1Qo>P!&>A21~#llByZboZyFGoP@QlS;hAG#7Vnn)S|r z1&hi!Ik~d3Zk42}^pyN+?+X|J{*$wet(xkkR_a5{9T`VvDK{ek-!vz2 zt1nq%oh7^w0yGHOkavMYu3FpXCy`eR!Jt!dfdRl8G_5T{B}oQ-$Oi@hKn#F*;J1^f z|7M2|pS?-XhPp4Sj%QU1ThhRi>#j}sO>B(+>{;f!4lBmAzR>fqv-6X8CSgmgjF zWrB~gi0H#lX~{(x09M;j=aQip`keY5%M7AS{>{Ju^x$e>FaW?qVE26e9}*2jYTBqz$MOwH3(hTCuPAa*$o$g8Dm}_WNIz=cJX@zEC84CIQrWCUG=;nLQg7bxVWg!D6&(>Qf6ImetEaw+`Y}PW8`>O z$EkrsT;jbt7LVE5+NSsmUi(T!uWM~z+gO!8k}7lKopze#4<7arg=cal)j#zU`UU-G z?x0rTV<`sTk$%Q>jh}%E<`)+jVOpvNLm=-0zNTAWy_UY_@AP8z-}RS*oPP2w)u_hze>INGL!m)VZ76sEI$70R(g9?`Srq?gdt6 z$r6p^L-DzFUq&7AA=6D1YqaZ%0f_bym=`g*Q#GMcL;Bq&42WDN+?envG_hhtaPk8p z=*S~aYRZpzePC~AA~Y`0x{&6DBs#47V@+2Omkb5~b{3u6Ik5C}Q?(jEU%@#H7u#A? zq5Jr0SmpZq`G0nn#Xmn44py@gV4~o{WWmU8GJsW2ELTHH{ziMTc5Le8uz?6a z8N)(@2I*fH2%^mm{2=uQ%y1J7ovw8H!e9_cgdfNbbMr!VP#u<&Do(d}+z7>oR(#se1j*2M~_73Uz zh@K5`Q;duS#R@7lh_(AzO|!KLl3Xs;17QtXmarIcXVCsB*M?kf*tOF5YIW^QFxMRH zt!(5xuc9A#)cbSiy;Qed`;Kw1ns|#aBbI6DMTAL&pYjoI!883|1b#38v@El9cQ}Fs zfPuy~SW^8XQ0`N8Dz1sq!vG*0W$Vg=uq^N_>ixdOK3WQmUzWH649FAlw>C1JrL%63 zG_(NH3rYXrt{`oobMeC&985w0$>MkG&$!JB^Xs5e>F6m+nKSog)Uli02hDh69poC~ zqXU5wL3b=}meB9|h+4YNO0To}NuGg&TL}5mz=1XeK&SG_?|~nZJ*>Y; z?GG0S9nu^wXa!KNU@BnH#bMWxr@~NhL&YgkA|Rh`INV~@&{jJZPo58~bzOVHU}DOE zV}3(<82$lp>yBDj`Y`0+4HY2QTuitFP)pSEhmm$aTd*G#6dKeCk0)&2=ro-iD9j8huv*zjRye(d|=%Nbk%h(0d* zDGz87t@+DDA8D;Ns=qJ#m->{LK^#s-0KYbVLmuEbT*yn>U@C|5t}HUTuWFy?y!`qm zRBm>z!5<&%6jmioTWSg?f={j{BC7|S6*`&#{}U$w;dgR&W;X*Pr%{-p?#rlSb$&j0 zt0Uchg7$*`g^mvmNjn31ispF7fA@j^%-%8j+6HYvb-%k4W>sF^ijc3ImKXpzjQq6c zo1Wo<*`lAd0I37C|LphM=?FG|ZeUi_0RR&X2B6;$`#mZxIphW+O&Wo3#yV>(`*qb7<4_yvP&#a}CG|h% zr!GTLjKe_{M*Ko~-bB~f%%~I)HdMs;2L+J4u0F$=?)VcW04Mz+9We(8BSI1JEY&%$ z<5rojc&;_ml5B~X;GHty{QyySGKR}o5BKci#+n@L{P_eY>$4sGc2+f%;GkW-=N}wx zVQF;xN4s%@jaAGsovB((TIGorl2ch6g)#dgJGH+JPU-8u zyA(^R^Bq$(o53ary0JSICup+3115loKAs_^gK(2Jnrx#;Sc0Y+X-MmXJTf5fCul8z3J6jR|_r;y#P^;S9hY96pyNt^fiICjNoe%RIC@UVBZE;z?x)q=E~a z6@UyZh$uno2jMSU#_`MAt3!33h?ko_co}spHhFT_F26pt^;mkJS&h2JJiGqOw)_$% zByAv1NM=)PmjrC~X&0E2wyYc8@_=vU6%)`m)Q`IIpTL{u~EH!=FaYDwsx~x>o>04<0W5p z?7X+v4?D``mwN2RB-cIs2++%m5{K_D|9$(P6P_gPOL&wT*x{?1373bse1iHEHpHZ- z{w2SYzPrp2Ab#anEw8Q~)btMg_$d$ORdx&^(g6fBAt5AnD3|d0iGkYl6LFZM0BDBN z6{?B(`L{<=@T+!HsZIi6m(L*R7^8%=37^ST)%OXS7;{a($iih8U=aY#( z7zDZy4gcy)(+H|IkSU}o7-)eR5NcY!F(NrF@oP$x z6Zf8R{Boot^*{W&7y;^I^d$%aF<0PVWsskVxFEiQt5uNp!6kCO{P4p{dQ_!pt?u26 zd#tNG`mqe+Abrl~}n#UC~un9Sbt7?2JlRs2f5o$Tm8=5 zdBu{Su)Pg-?^!y(f?Sp^{|be|q?>n{pU^%T@N+J1H|hn+T@KH+Uty{-^1~bjR5e-7 z{;vC}Mq6q<_Uhm+RqM*xg`XIKOy2|%0F~+!wytKb zXoNar?(T*Yf2Qh9uaX;}J;(@wQCeD4#4{vPQZJI~f9{3Ec0g>DK5uT}){&2Q<=uOs z9;h=2f5`?Pv*lw(G91bR0Fu5nv{}MBpHCi$fE?Z&N~C5nY#}L+)_7$C0m2VeF!~x7 ztXFB>pCmc?)yNBVa+)fAh8$i{ei#EzwD#*sYJPeT>IUWzK#U9g%~Jiv#3v5kIGvTb zq8Pe6(6rs1uiLdNhct%3@T;!hs*KoWAW$F>sB)q1#l!`|DdA+Du|Q%-=?3RfjkWx) z1C@Qb;qc>3jl2TJ05RqmGXOqbg zx+#WUyLt0YoZjz_u_5EToHTu9iLVynXJI)>t1C@XY(geG99hzY3LBtJ?B#N(zBI1s z8EIt30mPLX*tRNPs`$-I+c%zIdpz|r0amRXD$P&k~9Dp@5SjP@@O-FT=>z?0EB@7pbKH-hrIz90N6JH*T~-l>6lV6 zm2Iw7Tlfp;W)Shm-=#P;(WqolH&kA301y=+FseJPO@c7enm?_pK=r?%n*U0y4O9BO zxG$rQ4H>hfQ`o5PIF|MFZ-0x&3{AiWNNg0J6L)LJjyjnkVgTeaAoW9ni>}&DqsE0L zH_md`=4g=*HWonoEKQNJf7|uVa#;oGH&0H_VgU_Cg_uET0LYICg9C!VodZD;C|G*w zZaqH_+BR>NK?h|(%P}N+Tmz{8U>pR%I_`6|ovKdfS({7I`wGilJh($xP*7Yud|#~f zL**a%>pemEQHQkDbQ~xnV1g>;c;DGOYv~#bl!ja|IFt@^Q=YF#V_BuRX5Am-1^tgP zb7yGtWvumylT^-|?1G>SJnhocyr{`dYA20{7ZF(P{-pf;*Cuuq+I}@w^PEf1ln+Kn zk%kIcQIC<=`)Epm`d?e?0|G=u2yt>e!ZX#Cv;f?NaUCurC98iWbs%Q~HtcTgw^hBx zK=Ve9?~PTOB?2%bD3cfo)U^(?S5rkPPfoofcaN_n*B1;q06*Kg<>RMT7iSdK$lvY& zD{3oL1CaCs1`f=KVQlJbR|d@lY#c1A7H6wmzthCY9{IaMK*I%G1cB+o$DSf7N&f;D z$(gyI2tUf9J|AMS;D44b9;Ve6-815s@l1a@Q^|R-T+K*i@hyA;KE+fF{I z*Wq{7b4ywT79hBcZQB6F6NinlKmfnv$Bo1z;s-946eXMqsM>Z6B^7QJ*V3oA&Y6~p z8O@X+n};|D`%>WQ0nh*du<<2rzLn40IN5w{Fy#l)C&Eu|Vxon?swks0rWtSOTNvk| zU7g#Py2(*tCP4__s&CNOT}a(Ojc<3wg=IVq5Oc!=^f3TP3w#MdNxs5P923QqcX48; ztUHJc48S4dKAA3rQD4KqW@wAO(m_zFb+bputr*#K%Qsb*l;C?egn$b>0)V_6AOfD> zEY`T~$Tyn!yjZm_*Ti3(VeL9)rCg9c#3Ng`%js#o9~>44B|05j{!A0X@5$*5^}nn- z8YQU2QLK=>1KJc57ahogwuC->$Zp(u5Nc?7fQ5dDUVlzfqoOd@3Jm~Fv*u#(x zNli!-9Is3$8XxSGsVFe7P>+*J8BBo82oRo@!-#-qDhLmpV2bqI#aSEPE0#@~cXG<( z4NV<9v7Ue4H1wgqvj#+;Da?yzDKiHFSRN^DZ`zfTqEBf{-mRe60~9X1{=-`DN>?g^ zy0vX3g5zgb5p|cpgNVpr0<;+byaUACY)BDt5E>3cgVu{QU$;ZU__4sx(KeWXkgzau zQ9Tg0_Nm&mW9Q;fVUt5~vb%dwn~2Gk7Jo#C4awgM^~h3Zm8w&(C3|bhW#pGXSHvG{ z+FNY=_OPfJix*Wu7vYCgDg%%`BvUf1_`@zjErQ93a_N7Wbu=?pSYdq@>$Dv|a}*a2 zP@$992F&(ldswYp^|`+069WL3*8QQr$8HH3NR0&-03r)!3mS=XV;)7Bn`L$KZU$-tmpKd zhNP>%dBy;a@jy2@+HS*>&G_Ty>3G738ozL zbGy&ro0o=^yK`?^rD<$c&ANFtvds4VuUO=Y;VrhMB&A(PwdDSk5i}8ex$1<(kq-Wc zp=!e6?BvA8S9o+`tDj$SIekw2jjInj1|wMzRv09LXhWrqJ^#c6{CS>lm*sJgltEMg zNGsPD@n9fi#z2nORTo-nYtY5j_Oq5HkE`~09xjn&Z}%WF<-D%+2y4B+b7_5X*@c&E z=TqgQM$h>MVpLG)(Ax>8b>)RN;J|_3o2}omPY9Dx@uN+|>`)#}J2?}u!g3@93)ii@ z6AN-1CanCSiH63JmZVAgml*)cOiVy2M@RlgRY$R=-;7yaqj+8J&qKYg1qUTwMjXBw zwl<54YYdc585$jI>CCv+xO`tA+y8Q9l%e{`qduo0*{ZG}iE0QFKWyeU-`*zHlrwq( zQZbJ7Mdt#U@6SN?AWF7L86#F#kL57TkUEC&dgA9g=EZp3`Sv$hPJ42bpWN0lJyl_? zT}|`{n1KToD~mPTc_u0w?KHW022(}Ep86U2sgEm^bK(O~jcm&E!3YFS$NI|exxv@8 z+TS~)^N=AqT|xML&i44;qIrp|MRO)#&`-&%>+Yj0?1UmC{sCtW`S-{eCkVuM0ap%i zz2(QMj!Y4Z0^ir`!;doEyYkD{heV{F8zh$iuj0N_{cE#nZB7X_p?j1W`=B=e5fxwa z2a*8N2BJKBF8ZjRVhSzz+_n`?rV0x$l~U=c;D2npdp|T{r|~*?0II#79DCo=B-^zl#D$;sH{QsIjaOORxW|61UXS$*e7;Vj zNtyqiO)ZPP->!Ly1F1=ApW1wV{ZxLx0UDrHE$pjxXjWpdO;OX&IL~8~%F$L_Xu?pt z2{(^F2#x<=IVa0&7!Lp;>19T))5me1!AS>EH^0Rj!dqX6z=T!S(r4hClq+}y>&(MU?6<%Pt|u@*D{o`3uu5mHF>jo;8UQw%*96kQ;K)9}!atH|#ZHI6pbZ%P&0PzPvSh|*>bhvo01>XkhB*Ntz zm;exeEK#;$CWqgXBX#)K)m=NEGi@tzVk5qX08Z>L@4d%pcY^1nNvwIV znjv+xR;HQjs~4C65NH)M$@SVah?Tx_a}rL+DT8Rz1uaa&q^6Z~l0QGweCD^!xk2+1 z?evui1h&yj&H0nI0(FKT45F+7Kseb0z!(s4ZM4_^t_uz}$ga;27*ZGx3X#>04(R$ zTbUW>I|j2ZZG5uqZfT4ofGpFo+O=JD508*0#V zPTdykA6>lgd-!sEKOz_~R0R_t)c5?aa`c_Wvs5spp?E~096F##N~+UK(mxK&A$7l1 z39}5Ul{HJX3O4U%4b47;&sk+@d$Zw`it0+t)$i|rd7t8Rxm!=2np?iS^lLcE22qm39b6_n7jbQ>uK?7i7{3C0WKPM+r#d1gdnR*gXX1LU`6edff2m^8g zf&ozlkm?_5MHm)A?GHd_U$?c*6Oj`I8BoVk_NMBr{0_EN5l22TY1V zUJil@fJ^FrFo<*@6iPsQzz_g1eqacQ@wBn%*kh`VHJ`@JsoW3egNpdrgSW5T5?)|*RM~5H3e z>&NKXd|=?wu!l*d?9Gk-0wE$|MDgT;5g_J(7y&FL{d3`(M)gl=txOgD$e$axZ>>=vqa$V3_^!z0x%=AwT!}Y>~g|H3_#Hivo%CiUw)6e_RaOh=?m{L z?^mb#jT|%#1!+&9VYziT{_>hhlM?miML5*|162!}DoZ&;Q~w}bo*$6%5r?v|{f~}4 zMmRA5$U{I(00dM37yz;XASS@}@{bIskT z@d#;xtI}nnig;oGU{MUDEgKf$Mi9y)xr(BAfb;f}8=^ z9PrRJNU=_BVI^V;=%!L!LdjT<#s40Ms9h)z%nC7DSMJ1*r*~xMt{dGvuIrWIVymFs z4iI~}p0x7;{{cW8E-;v|HG=dH<39i-f4WG}`1!<9LFhs32hE%-@Ca}Ta8xU16?|l9 z`|#}Qh`4I+*;SS6rz<^{A%UB)6d>0BneuC0=?o3aF|nqVA^^ zG0Cux7yu+bq39gXmwBj-f+?#}`{2G4woyD{%z|jkND>j+&-k`9CoxxH(}JHpgM#y-k~zaeMbK$K1& zd!|t@g8=|R)wd*pyxL<4VH)5J008U%P*G!d0RT+K#4$l^(uBKg#@vU(&F!+HQmOb# z6vl5Dv!q1&;qfg=o(IUbR1Vn%iLr0QIr6{vei=>nw7j91Ls7?6k75P!e*atC> zsXVyUFYv?G0l+t@hSxdAb?+~L9aE;*9a%bi%C!jpT#@YTVJm95KTqCr~nZ1bDu-{`~y08s*YhulhBpVNOYh?f?? zZ9$s*$dIt$BuMARiM^Paf&aK1>$E-ku$6O zkIIJ>ni6yE=+*O4oq*Vh=o7-{a(-}gRlho0_?~*?0aH_5!GG|iC~A9LVeL49v*1io zywdURj@9cb6m|PAIM80njQU}Gl5|S%A_f4&3unIrzyJWi002TBMt&ze2HxiXZ~Ao3 z$UR4<8RgJnRghMvhGn)b2D5;E#0~&30bl??1Of8c$tWt5q)cIOA^p>z_MicP@f`jY zfW7su1BQzuc9G6;ZdbpY3Kj!aY%SvXft?HT0jOT++kr9j=7?W}tD|ysUq7V9KUag| zGznjLqd>rZ%-Khh+=4C8!ii}r)Ye2Vf0SAG8f$$@|(hvJj>nm3dj}1-! z1NFc%48Dmr-a}d%^JJ667dHNs%gC!gN5p^Sw-b7-vL9WZUZ$&}y42_t2Eq@bPlO*G z1~oJ~jgU6V{)N4G3nA4(+s$bmk&h&P_=#c3k2+chMc+o5+JLoL*b(68C|9n=e2B#< z?KJZ9rR@RrtekAZT|$>lEaPCR*4^_2s3VvZLhN!L*^l!C09f;vftW35S%?`yymb+? zeV?vap{Aa4hJ5g^`=nUApY0}GuK9tz-mymG2`(lCO?-W?hZX>Bp`|0F1G3Yl0g$qKSRZ3)LE20J!XR)#r>84=?eC{lJg!hSdps7$&6t7ZHB#s**Y%V}-^G z!T{6{K!&9Hr~HVccxd{tbrsuIk(Ms(UOCy>N&H55+vAB@O`oZ-d~kR5?;n5ZUi<+n z3R|)Oqi*#-&~eEwHwq`0>&6`T*r{_(GaM#K0}t_KJ|>iEnueZJ=1x$wA8y7>=F zO)agoH2NEDL?6HvJ1}xs4lx1vxexl6E@TJo0uCa^0B(vIM@2b+$dH(woW)G1Z-6ZH zjkL4F_z!kaQ6Wis1#s;=IeFHLkSX(u@uREst$V_sp0!-s}ul){#>p1U0LUediL*6G`z|Rc)RHv)knye}F{)&e;GRI_oIxv5} zQ`nQx(@qx_WMWdtULteq%ulqmK%wJLo)=7(yxxxi3qncj{z$9j#>2%E%kP8sg!1N# zySAoJ_b;4()>jrLI!#D$z__&4k&yay0T=+Z1yVm40U$c~Nd-!I2od6$me;w9X=&X{xMhDYZ^`1ZO~{rakewAw%n0HpuZhn{Jo zfv|O@mys~i$bjdMnyGgK9K9H0kUffA-i!R{>8a!K?dVV^Se!%RZo9Ad_1=s2d$0E@ z+5%;eZ3k>bFg_Ol`qZrdqC*!p+kSojr){C7k;b~oS3rR#7nYvATa8e`?gHZk7SAP#^CRW;w@=Tq7 zXgaUL_#CZSQDOSr4Yk`cBZaTNXdoI4czwuIAJLb~gHcZX#nA%c!3F?K0DzD-+6hKS z=BVj?*qZfmT?et22IR;xB>!H0N{*a1H748dB-f#!{mJPm-}3L@jF4hp-bV}o%D~#c zWy!qQ%`vh5zwhJa&%Exfg38;CkugB($U0Oikd+WB`mU zl-H13UxRTBIuk6yK}cv!AwZV;f!Is&un?9Y)c?Wbei^sfr@02d&GK~{&iU10JjrbQ zs(Q@__G_afQrN*s{e6xd8ri(j*03WeQycgZdlgPGr<+`{uBk5!c`@E;&STu;!tof> zSgiQ*4eG5eT@&%4cVJ!`Jl3!!je~^)&ehKtTL{zE6lA;%b?Jg#H*!3WLmdR+=L}Tr zv(&Hi10SWNrEM)$!D298O>M5g`$r$1!InNc&mVd448R!B1sGEV3We%d=3Biu8yT3b z;h#8m~l+qIafz@O!gzyUbX` z^VjI&4l!8Vs;Cb~xqaukq(+1v>V6{pD2b#snec-cDbrO@qwRkFw(NbV<9;QtW0_a0 zj_UQP4p8g;`EEuNRDRjF1+iy;-c;HB{&(-O45Kc}0qqJ1Jq{xRK=luXfB?_BKsJio z&!rcDw$?>f|F3y(V2 zier4e9^;859?FkrcfQ1g$pwNh111$F?M804b*$y4xgAPGO>pIZ9F)_%Y`;Yb)ps)xBqeN3umOva+F;4pB?;VdYqG&_Sq%La~ytzwIRs9 z11J9fK>7#a2f*!Q|ASy6f4VX=id6bU*ky!F1fLMUJpO3RfLKD(2f_c16aLRXZp_-* zTog+Uph03l4iYl5}m~Vw=Es+P3ySre|uS)akbeyZ@ZbB*PlMjYXR4K zDM9?NjtLcnAMKI_trKU$Stl(5qp3`W2mNAZ|6Bssj?ea4i-@Z&)U(Zzh49O%(XZQn zesrYkXgSm{e~L+JNcoJzkBGTJJI$l{HdwwLlZ<_-bZoJ!`L3Ga!;d3S@rOWNK;w+Y z9s1D3!DPFMLecO=jEkbjzu(8ttPIOqA1WKd3XCS9wW(UiEPda;$OfJpLe5Zpez|(F z%C?ZYtz64HRhC~wNJS2l{n#5^fd_yA&`0=@o~$J?(Eu2*4Qz|CG^KGLz8*9*r&iW` z9@lN z{`W1vs&1`RW{SZ|mGYfkdk;uY^Jh0lLHIE*!Hka& z;53_G2j*243;<36%rz(!yK*{Lb6vJp2Jih57dN#jwz*xS;+^CuBI53~Z5b|lMjAT! z=^|(DfS8FOBaOTq1fmbM{%@SF#^wsI(=hkd=;gN8aagdYqA4D(KH4_)fn4Ix=U>_$+r-D(y{ z#Q*!L>7pOmfXP4eG2a4X9~S@?|G#m~R_OTce8Galj!xoOV0oO#eTF3Y2HMO(4hyFG zm^m0f?t11~_S|O<%S=m7jZ@lYUcP!!R?Qy!jD&dB#Q+e_f-M1A=o_0V>-U1z_FuBZ>R-r<8UxcGsc`3S*H5GGi$)ZF;kcC_IfT+XIEG*xe$tEw-iHB{-9FZA~F-BX_v{+jv{(pUk(2Y}#X+ZCj65a`?xe)%2I)p`ocT!f*$ zMELQHa>)W46BS%OE)`QG-HncS^B>W|V8RarCbrje$l_XVaY|G6vyn>GSi#clS~P8> zHtR+O@(8yAV}D}yTz#4ipkJwPkqjz+T!P?pqK{>vkel&ekFWKO^}KpZDnd&F4V=}e zYa$?)hhrhaQswCsD6#u(*`vL|Dl~eyJr|iGF3<$jyw5Uh}swp_Ajvbhs_Vc(dL^q zd;ig2)MsE)WJX3FOO&^;T+{>o`yec7eSW>Om}S~&@if$LboG|*vM_>0jKbfC3(ciSrF=PX6)P*x+?ZWDnaE7CUBY}T`!gVvww)vBypX<%NzE+Ei zL(5K;;24 zIqw~TMBIVo=~;L(;7(~KU)e8b*Q**)TH){`j?QpO!)tC?5eZqM<-8+a3cC3_(b$c@<*SeO#CmN$_9f$OopX{ zk$cmt;~up1-|C?AC0chwjKpRmnKyG?9UZNA-(?R70{l|?(y?NIprGdE*u zg2?0KGcW=4M>dp$vl__qJxjS60kp;sBRRAmzkvO;(k}J>b-srk|FOr9Uc7A9GD!V0 zVZ?ZX;T#crXs|#);35o!3+X{nNva0(`S{x%9fX!hT?d8hXJfsz`y0>v=-%)q?t=~1 zM4|YV!0SI>(%P*QrSal$9{>@4O$7IV@YC7;a=1+NHP&13-XD zEgSP-q5_UI-c)DrunvY1er}wlT3>60o4d_QAT>g0IJK>+@$&W6+IAjgAW@`hXK{VY zEqEv!(q>7J5kQ2W;<2p{V3lUgO`9?Uuj9Ek%&0jZBj*mV)b#1I9_nQPsEsHA?|2fP z(sT(whahu_FL>HtzX$u(vs>@^2frjn4COAh9rd?-#)N+pdl&vApQVWV>r(VFU8VLp z5FVJEn&$fN-MC0F0jfje#R-5=@8b|CdAlb`{Y12=Jgo79NjNyWGQ&YN1oXof5Pkq8 zP|_U91QNs^mn=Plm;#UMYkP<%MXh8rF1mU*CP+U~aIJ0j>P7Z{N(;Pb(UFh3=&Os}BZ(dv*;}j#gU3fnj5Bj!Tdl$a_-5~?@&0S~# zrazA97oV8U50O*^Y1f5ti_8EZ4R622u|DDbw9~%|&w7bJRc`sD&QFJ0%+;ta=tGfo zNa?g)q=WST?mN%dDlq_YfhggkbHhnP0Lya_H6S{145^XvK<#pMJ--fh)KzbU^_jP) z;ewQ56?OHeJaK?@Wr<&xJq5}G;m6@V;P$n(E1ds7bk}!pwN0N+S5pOK;DD`uGT>b@ zA>sKP>m8rmUQVO!$J&;4l@f!s!|^P)1LK1JKaMyMeOv@UN>~EGo?I*g5Ceco3O^(- zvI_tcK!k+y%PuA)Bpd=5>l|*j`S+D0n!SAMOA~E_8$e0^OSxozP`ma0)3KfNCUHi?{uA}=R&+99==e~%$-?r#diZ8KD z#lbdU0syk+2!Ce-;5|f$@l5Bof4xdK;YS)7P$tG7h$Bh)MD!`0tR0{*j8FWp9oFD{ zDU%Hx>Lm8uQ#@R1E9M1G=QB!6x)VRw{r7jdR;iC!;B&4-&Xhy{$`LICe3^~F-MXZI zEVp3?002yqeCc|HOgv?YooIrtJlbKH!yx!F(brBx&(2OxY;1)`2Mw`3qB6*R7Hgsr zUO@QqJ#pb10Z$xiwYC|Z?nrrbxpO1p&QA@AseEVrS{GHCVxmgHvaA7Q6;2e3aDt(( z@?K_`f^#}Ae1ESgKiaLSIA1+VGE&o^m5BtRK*YpgfPoUX0e~cb_Md3+S1_zW!pazg zAA||SAAbx3g0d@P#{Y-RxonBZIog|UvmSX>|GJ=5^Vgw{QgwwF#AMH>VNZFV*=kQ9 z>R%+JJ|^OibzG=(@0a?7IXXKsoC0TOXQv_jr1Gb2efwC#wrG|-Vx~&t5|rA zvQ~CP`0?HF9xMeQ42FQP2f&g5m@=-lImX9I6Uwjcwpp^(aZfqFV3Pc){%9Bcgg7wq z+@`8E&~$7i2)-`hr%H++hae6}m)1z-v?v>h=#;Xv2rlJl$DZ!_K^SG>7+*U7obrI^ zSU8&nbECvDjaJ$Ja_rbK^#VC1(BtA;9qSiyjGxc^ArXEM06_So=AwMOQ$1~{<;|!P zsNYD^#5cNkH_m58J8j%DzAdUVjPdZ@ z0bn4Zq6c9HBPssjuB!kot90sDsw>qKbplX06@~IaNB}_m1f)*JZ>kAE;A#Ih#y^h4 z1z7SH@ZjeZ|HDVCk}n5jDGkiGY{f2bU8DI!bC?Jx z+6hJ+L_9mdTtObu|GZuLfXb(MGUUWF|Aq9bYHhm=pg2R^GlQJU)pWHBqWV)AXvf3o zlzp9dJ@KNj+_*To&?COwKmLnBy=6qlkE+}%nb0)Ye)l91%&oBv+k zWwN=8hbDY^zu(==j_vI1&ivnd^Ja#gJ31uxsLj|rEupPWPx;xIHdV&%TTUpvCoHPSq3}8Ww!3u|v;M6jOR&ge^@+m$y z)RF2+?w-$|f0JI|M|%?RqZ|N#z?;`efFE2w7%Xn+^XvD^*0@j7#(pINKk{j`+HU~r z0DJrZ@*?m@-wD+N%CddZiB*-5&lrt4F)Ud;eIsx&h~Nh`JO(}du(^&L`0Ktpq1Oap zdH|hAG|HiYnd*VEF#us(Q2>95pcVSgM`_?vK4~yhak~U9^W(;P!M8>i^Ayt=@}q+v z@B8|sCPw`UEV4zZ?^ST@iL?Sg%FgdTg9w+? z9JkdzV5CJ7%MrsxKj!|ySl6nSuiTj5C!R`8mF&6V>BfiuM%Rpet@4i!SG{}}rhfP| z_+7ta5AGMpDDa~`-TsKU%WXQA0ze5&i3tEe6e()6cwyYQzeRvGWs2nX0OG?X_-_mu z@^)s>+wRAkZ@G#=SNhhtD!*QrlG3I&l9b8kl9LfYUk3b018^sRCy8FH7t-Jv5C`=> zO+^v#1M~^_v5^!A-yeRM&nBi9;b2_x9w`pr`su%4@Amq5*f)sJ3i?Z{<)f?CjoUap z88RZdEQLM@Edc$_J9Vc+l=S@u?E&Bvi5MO+O!O1*rzGX$xp6We+JVZ4du8oN{WigT z)0}?iw)#{N%TBL3oz3gMm1k@i)#Y->WvU+5%BI& zHogmJ2Jwv6t`<#uEl?jhg*$S&gq=$i|fek{iK3J4G;76FWIS7~j zZv+Ig&MRKBr?Vt(R=N`!10Oto0Qo;3ywYs~#6MANK!Rn0DCcoNn197o>PFGIp^j8n zxKWde7qls9^P_wKN81olyOP9@aH#u<0Q#W1QKu!hI+$?ITrm#TkCyCheR^1PuA(+f z3)}tZGiJ}kpE(1NAK(s#0SC4~;sfx5zzl#8w|n6{jdWq;uSu`cmBfKm{#=x;UP~9L z!@>YBI@5eELZuj2n2b*n@R?b2ZU z!$*H~Y*pn?nmE>HAvz0ls1pICXcLQkCR|;ZNHd~_&H7})pw062@rfw}A7A6PV%=z^ zDF;`HTFD28Rk|LgECo_(TvQnJb1DSvYYpb{f%HNJ!y-?x>k3ESu} zer=CM+MvxNTOP{DJ+eAank0XJhe?T6R0%bZK!PvL!;6-y2mxBshrreTSl182dEoHl zhdknkf;Ilo01)sa{i|rzhKdWHKZidplpE?u&w=@IixRd+sgqDRwF#~b0Y6FoXKd<8 z(mp_+fS<~M3+;-f^37#2OzsEAs!=MMQhIqj0sr6?Po*e+uKX)`nk3g+g+YlmNt%QU zNIy$rhf8z+qwn^WB>n1Ti%GG24jh+Us3N}$9VmS(k|f6m5ku`IAC!@n)V?SP135`; zxJG*V>Dyb$rfN5P9+J>#I7qbfw6kvC#g01mFgc3{EgB&ZGd|hbudXXcCoyVQPw3soH_d$6&FaTg4YI@o?^4<8yuY7tv zO?_WpPG+tFXrmfVZN7DP$W>}bl!y02?}W<79R2DgLHXO=xf#%V!J(F&=4{W0xnI}? zAPx2c!FAvD>+QNNJ@Bd4ugV2ebCXJx-=HgJ2n;4l3b(qCB`;3{! zawdS?9nqY@6_)~1dbp^&IKPiDJeMIt|CIMpF&+9F7$H&07vtrA7|~)pICuFr7e5pk znr@;p^S?7Q$FqQFt{=~FwEi!XDNSZwFsWw-ep8!&olof-0Aq;z(pa2&X`1tAepR@TrdWfL=po=IfPw}9;dG5S3`Q{AE0r+6i!cz52gNC2azb8g zISLD9R~L(@GiTm9H{9@8$2rIo8@kR7b>#KN;KjFdoNragawI*5*ro`hb`&Lkgk!FM ztGad)z{g4n5Ev(s(mKcM)5iIGuKw|kDBqp^GIycGI6xCX1gRhNDO38N(W>>*AjOmW zM;F(|jk}dTB1-=hmzs;Sz^SuPT4{?@BVZ>=Qb-TL7YXf&K~@BP#3PIb0MZO#T7lB? zbE{*!z5MZW-|(}?2RK$Qy~=U&-(2FirvV#fNB|HN`_G75#T%pt_>uR<@FMriSF|Xr%s*04X{VUHb~qT z0J{S66Zs_2MQutvST9uyKqk&-<5^&_FaLJsPk^>Ydy-TykC$IV+j9O&MBw^b>!+B# z4cotFV&@k;jcy>4Cr;ya&jp8SwfLj!-_R(a9>f6j`S>gAtlp(^@XB9YoVAB&G?I8z#lKShi z)A}sNfFB9CF<-fj*Jd47cn3F0Ns{QcH*^NyHnl8YCD0i_e@3<(b8IIs>3)B1+p<@G zV*{RX4X2%6zi(z#5ahPz}N1CSH$vE&!d8LH>4}%6I{@zt4HN3EFKw?Hpkb;ZB_8T=z z0{rMNMB=l;k8c6-?%Z}mBuM{Y07Uga(x;WA_5a)kpaS0r(XXY`zAgt}9!+cBjHK(Q zP&lmht@5KfR{dGrE0qU8{UHCjd+G*3T!TbS0Isp)9R|*S5~j9b&F{rE1jfDx-Gh8qt{wc~9;JzF`vojpc^Y zGpbMR-JRcdC}#vp;izk9BOrCdh6ePI^@H3;9i8@~16aOs+V$Aworj^D=kEUh#uaFYgYd}Ynk;MhQJ z<8aqOX>!EeLh*<1?%TI|9oME03#B`x{+AZXU%`Alxm60Y5Ic_uRPx&ZxFDtS9mS+5 z?f!b~*_9BsVsS9*-QUIF9`%q&xP>b_)ZDkrh7sKQBz=^l>j;Cf-$LhnT*%Gl7p0}L zi2Tv0UBxz)gFjjLQ{I$-pVGk9n6goo7eCQ|gkl`|(LsD#Im}+UKYT30#x0u1+K$xO z8{OFL$Nv2LV(i{xr5&X$L@AR2_d>tIwQ4kU{M$g3(I5;C*5BUI@2-YpKr!fJ?{u=1 zHJUkv2pAC&5zy28tXvwSd0nIj003afqBdU&(Ggiru4f3EUA+ zegZb6p>F{UfT3{o7i`^22WruMC?8!LbCLhi&8XNrcY^E(T+pUIiW@5^mGDzt+&a~5 z;^a?r=tvHgxwvK?VRG=tdw_a)RW3h`)Z8Yx zz*m!A4q6{q-P;Td0G8W9?H_0-Qf3L(jbKK1}h`v;|%i4ze%(S?Y%%_5p%R#JMi3)Nm$aJ(mm4~msG4Ukh|%! zoeoC}Fuh(?99%GfNRkB42R{*j>fmwR;0rZBfFHmP!n`Bp6Z0U>-Olv83;;jNQFYw; zu_NCbw-z%oaqkr{rG%-PeRjcVc@>Qr4(w4%phAN=p4kw|fge);vo~=UIY?JWdIEmR zD;Y@gG_-7w!ZB~JRI!D>^l)9*eRD_@h0EQ94ma*ylLE`EElmam1wL!erGTDlR8lnQ9RpYoz(z(C3n zQ8|X<5C+BpbEzp225$)YLHtJ@4(VxdfFEE0u!?!9J~irgiDv0l^`i`siHT_yxTrVE z2dG1Who%eG_%MJ2iTw$F9b+Ix=@|m_8|1@#Ck+6#r!Hmc|I&Rb*jT7z3)bhUkENa? zV=3zU1#jEl*5Mzg{FW`9ZOuC?l-l|j;LxT-A|pW3H{vLKkXHxh&%vL71J9b;`=>#b z?t%9RaEHc-_J$xPkkY_>Ru1S$18J8ecw7?`Kw-#Fz>m3nqDgMH@k$MQ#cgZ;<%-k4 zub+Q+kZtRDd|Sshi4RYSbAYQmjguhI}O03zX;sSSt$5aZz|X`kMg zJRa|#&*9&G`XG92%Q~%(-(S2qb{i6n%($Qr&6=rg&3bFxCQi6tfHmZR&v#4IFr_0O zK!hnFv7d0`kq7d+Wz{wI#{03C(&~<%+QLdCHGk>Xqf1!Bm+Jg=3vKJJs1ul2(WT zKsrb-pqN*xISsai{G|1lF4OgwW9qoNhBdQQ=}hJM6Rfu$BRz*kXa6G&`a0%Gw^D*$ zu=ucsfdA^hQFEt$*5wE9!~PGHMoxE=13$_{7#IN0{1#pKrDU@q-b?Q9do2735Bm5qoOM#K9qdx?cZk0w8OU0OVN30lN(cVZ$Y{ zkKwz)wRkcg<9X<)Y^<6Q8FPa-k_CbRaB{VT9mg?QRF+K;H&Hnv5p@)|?)^PxOsp{p_DA^*a^UrGJ|)1bH9YQD|7Bref%rCDQO%D6cS#!- z5rZTe)*?PN&@WotIyUfi+_c%2GdA#f{O2Wkp8Lp{8G^7C6FX}|P5XYg;!85k%S3yh zJ5Cc=`LMatxQkne-w1>bCp(khGIQ(H^70LUFjd+C>Ck3!K?C19jWJ+|;CD-y=0n{j za$?dH3^Xtn3hnCklO{p>->r+x+<&UzuP`y0Z0r^oj6}j<0@&!ZEK|cHV z=01FB3kXsyKWr)~Y1pF5%K|29mt|}Ngd9`Hf@YOi6o0-1!pBB~lum*(-rO{BgE0b$ zgZ$x^8<*W5-X^xGvXN*1Lj%A-CQ)M{J(vdM#XF$6WRwX8AS_1nBe#xT`#uaxa1Vuv z_du<7r!C*7yc6n11G)~hb)brH8r69auN8<1B74337u! zT@DWDyhAh~&KwXZ?@PdgY}8b@WP z>ME42kVgC-a4jv}R4O7i)ZEZBo(q{48imJ{x5K^+e;V7(p|FKg>SGC70r8ta-lvgq zcaOK+&}w&_Mm6o>m_7VdNa>jnM?~KOuIU@2IJj2%P1 z@e?C2rZIIe)0k+qOG6*MTV?C)bx%8OiY8SlL@Xc$f6v8xKN??T#AEGW6Io!zZaif$ zvk21FgIh01pjqs#&gMWTOe7isb6}2`RA=78CMlGk*{E}8Li^cT+EwJs{z{RSiG&)t zF{#vcoIB8sJ+bVWW3Y64fIfaS1@m#uatnAwmVkeXbN*QBbR+-j2xHOQY$y({ zI5c&h> zHtU`&@gMC*11|=17;TA+0aA+bVmk&z#9!^U?`1Vo_4s}6Qc9`S-X+yPS@}Z+43aYd z2t(Ps&xg5n_DlQHN#x56!Hz)dS9wrOVB8W6?jiwH@v#GJVKEH@BY;1M7y!)gikA3@ zqd^~FkKNEfw4E!d%cQ`BKeRgz3*su*yDFusb&ox7{-y5>#+TiLdevxov?u4zwGQZ< z*bR;d^S-abyYJfBZNcZe*{QlLE72A_G0_m@v_-CP&quEewt1TyEOaS_EDU%+i z+KindC%;X)uCd|J;_{CUlq_c5n7$F3cgLRkcy|D3d>a`2PJ4SZtO60Iis*(ksNx#m z0>B7c>k^TKPS_gy*e`y!j%Sx4omgEgNgcFu zvop8;FJGprMLDKal;Wo?6y|~m*QRI+@Mv2;mfL8!OU*?t-Vur?$mAYBHkzi{uIHV`Bv_tiPQR^TvC}3kcm=1 zz={ZxJq9#BI7Mt~x4ihlz8%9T4lW-E6{otnSLI;#MO>U_YtwBZ*TwjB`*TtqeLW}e zmp2P-MD2y=!8PW0L6FR`G!lexkTKu~1NBa+E#GU;%R5rSguity94eM{w!FgU6D3Yu zWB^EWAlCrgdib_Yjipa@);eNg+3oLL%<^eTMXi_^#b9$!rs0KC;F6rO^cb^u7uFe+VvPP9SdRUI58% z=2y#>bTDrl^j1?XE?&K@*P*Z-hU$iGOl?dp<}1`%Nc56j0KN&@BY^Hr_d!2y?>N@N zSo=`A>~g`h_-#Bsvfd{SbNHaBMBC&2f*B|@`F@h!@KA^5P3)3YMLzdTYU#9q`w4Ce zgHzgqJw>ZcRDXWJ?U36a%_#UwlG`tyFEsHg z2MiblSa@I&%tYWv9E|-yYin;Vx@kny0O=x|{&HL$eLWX(RrhcjU?FXR3BXcF46+2s zB=u7|Y92^o#5@7`)fzUv>;6!k&XW=)xLfMlxN8eoUn*p0<|2YWq76y^fx&Uh3s1Z| zOjgW)a)|-I*R2YC>Y|8coUJ{VxvgDHO-u`~9o?)NuTWe5tKi$lQJP=GI%1J<4mk#U zSZM<&U=&7xL25{72;leI_57c8Z!0uN30P5fU%svGwAc}nb_&-ogWt{aT>A6}(h?vn zGsF#29s3;^5Gn_Md=uE#x_*bcW?3yAVP`^Hr#j8Y-0Z&xQ$L3G;=nVZ4$~dy+rmI8 zGtZdWyxv?p(tUh!J7&f51w4$h-%@qG$e1t4*Rc zD$__!{OvH!19uaRMMQ+wxqNxeqwsL;#R5k)>{bOW*MeyI*aCIFbkEE_TVDRW7RZS$ zpwkr_s9B#y2R>oS2@>#QfUx8PttibR3xFR$BQgL0qN`7$yJa`<+`xpawL^2pSLAuKx#YAP=SyRgf>=HS;rFPB56`Rcda z`Sq0gbsWl&I{4E@j*=BW03SraFJ16Ini`0CqYm_L?$wyjF{dhpL>7rWr+L8Q<6_ii z(Jxhl`Tq86v`e#Y;Loqtz}6=jL5&Y88RCk5n57bA!U<)2do5nwccatzb<&ND{KW;o z#5}=&3jSPLgoXur`ZvY-Uqk*gN+b0%kw%jsqGO7&h9U>(1M_fS-xPVC53~g&wXyu! z6ny*Hb&lWpl3E(^aw%1w2iIT(!d|QX?z%73-%xy3hULgQDzy3mRFd-fJUmppXggek z(5BR`0A+waKp-jbv#nivH2j(mKq;!6u{5X4?=MGguC~(iRYbg$7Uf8c1TPom;|F>j ztI7}cvviTe|G*slI_ityO~aaO?XvGxg^~H@S9th1IuP@~U_fE<4OKsWA`$RI>K|kK zeYLc1;KAEb9riG)&ZGM=A6HubWHoR1ES31|RhG_TJ;nKVgx5E1=OM;trGG;BpyMbH z-<-S;)3;%2W}%yh%E}w(m6fYofNMSq@L#bjYszgROE5h-Akb-I=OhJ z_lCJS{aO~?mfJB6)+)3kzFK^w)DHs&RJh1DbjvNzlnng)FW6Uav-9{>cmNutu(vqo z3^8|25`-M|0XE@5u@mZq4W4^#1u^&2JukUaPzzL*O7yZQtRXSRP#>d zs<$6fscN%cH_lUCapk}g{ z3`hQA^#hhRVlyU>s(fXdjBdpbl!fRvq}d){dDz+!EmmfBJWE!14hy)n!|#h~)+@Ig zsa8z42NT=*j`-}4tTG%na-R$bOW^-@eZ@w$mZrx@Es4@-K$2St1I(m&KDR8=q7o}w ztof$Z5iu+){kfrzcYZA7Shk2$s2u!B!YA+X4J| zO&AlVTZ57v&+YrU^Tm&=+E+F7Ui2V{8yB!=Q8z=c&w5t3`OJlD(tMnCYIO!^JvH+U zbFeb8hYboy+EO?nqsR=18a=A7by>k=fgjVYBL%my*W#?zb1a|zKWC%*oxOed_`O~m zHlW=N(wm>lRnJ$@;+!mU6YF-Rk1Q-_UaqfLg_)aP(pOHwqH079am+4(M}MF9;lX@9 z)8@a#?LP0cF=br_mruN_usv>Kpw35HxLbDLCW#6PdA@kHL*cQor%4j=0bNLE2oyMl zBT#kIW^`ho_>2nn*OyNxb^3Kci(oN0C-^1szxz{JyE26=-w^l{@S}nv_{$}JdH}w4 z>D@|8|HapmZG&xYs3WY@wek1jkCqpY1w zl{9dR(m#NvPuT1p>xZ@U$>goxdv@Q}PP00H;WnPs`!vU&1U%)nGGVuwTJiVYdl5G; zU55$5pKsMkeEr`vv8cDtV+Y%Qb9=QImfQR| zg0|4$zQK_82e)z10Y3pg0FC^qJs73sF0=ytOoN9r0`j-nI;=Gg?8*7>H?`+86pv{v zjWUs;HN*fQpF+E(^X;({vSZvgRIRjxN#HLf^!5CjuTl30@RKSME(TYUWC3C{aEOIp zcovmxBN{P2%lx^Zj`3?N{cU2xKE^W>6GiPtMtyt*@iDKxubO9vI_T=KBAsj;Ot%oo zpdK`!<6Wwv)iKQizj932zZ=mxo_c&c&*n$I(Pa`DP_=@~o<7MxeUUDt7x zAMU`_{!Xi`=R7CI82dHAW&=w&d#a~7Y#ZM(aXUUSV@~q>dLHL2O8q2NGF50wh1Ro8 z>&lWOd2_%8x8@(njrx|OD&Mw0CY(%kfWdB;a*#qM+j zU`Za3UxdAh-y`3FPM#*qu5&>hBVWZYputjXOANGFi;r!2`L@SRd|Eqo&a!q93i5RB zv*X=sbp+J67|f-?o-=errq(7_M+@z^J7~fF8kmEn@SNdBqAEn>n{m$AH4>QnsPkSabngfr`hnv&uI9@&Fq`Vzy$)Cso@V&2ndM!RI9nmXKpP6gy(LT4# znjfK|k@gQrU;^+i@o|DotV{|o&p-a$+xg`p2P`_`Jz&nE3NWb5sU1?IRDOoK!_ZIs z;aR{0BC}JPVOPA8Fy&XjMtpJ!3kG8_7*XJeW8T z>^1m7F_N7|v10io>vAa~3;sII*`ALB{`BKhS4B-`&R}@@v}9H#xW=vf6y|i1?Qd|m zZLL}rGI}et2figenJO1obr_Zxr3~ zhJTa6>_ELqgXSNq0!`=p7>g6t{zBCrO)Jsb)z18Pk^<1-Njjlq0DjQZxA7~FRG&L> z!<1gSk(3f-vzt@vh=Ux|>nlCyb3FR93m-k^JN*^o$Ln$zBpLu7XyQ|Q)94n7b4FRv zZeEM`Rh)ch$Td>yl0=uHgv{?7{X8xz=ymM&c(vw`shQ^dfD^?749?wVK^@am#O787 zs#Y&j9yCgb9g{$mL z6bfs;Q@w>!$(1PuOw7QvlE#lOKhV66Q1Kn7wQ>CPk=UTu@sT$!zKgh5rrHbMD#6uD z7k|*ARkLf;C;oi)*IO5o7&rA_c(AkUoQ^)UFF$}E=Q_~d``>+2c&hc-ThlYzy1MP6 zTiL}s7OdbiyzgjkwAP^-(=i$PGWV5ams($A`fz@IzV&tgaZ^Y2OSAfQi|3)6XTqDJ zOzbg%X$#tTDk?a-o6WcP{Pp+C1s*J!9z3S&iIFTqTEa(+S$e7tkV9WXA53k0F;s5k z%h)+Bv;(Gd16|#|@P-oQqOgQjY1?ChV?RT+X>8KBjiKp)1Wly=F_A{0h~Qkb51&r> zy>-B_Yx|wIho)!m7kybNcnpF+()V6)sO2&?YCjkNsQn>D65z|rgF2fZf-z_MNAqUC z&$+vtTF1BZ%MP}6wOmHrADAZ$q9x1PNqZ&GfJ!z1hno71+~~1(c~-sLmg}}V%)2=D zB~-hlwZVJTe}M8An8I~*Q0$R-Q|+8lZ#w_AL3hq~3aPU%YI{Y6c}(E~WlfYO75Rd( za(qAcB3cuLhf=F>pG36btIw?XX<4RPjmC_JNm?zO*2m*Gb}8bYy@^%vnU0vJ zh1x~6Y}xSb%{8On+&=#<+^YRoFE8DC5Zby)-REa--wY~h!E7kk^SM7Ov z-}CiI2L=X&eI@{!fls3&3dMDGgyv0($OV7(6v`u~nQP;W&h-=Ui;qf70F8ZV8gsba zME@7_hF-ROxZy)sIRU9%>r)0xkQ8MMP}w8#BUhT^~M; zmq{`T{wTNKk|T%KI)2;i89yBj;GY^n(tP(ywRdjG)iYuWMO?x5v#I6DYl9XiS&6ji?dD@&KSB#!NBQP`V zf;pruH|9j(Ko@{Mm=Dt8q^UC+x;d|N^qtT(v#vCpHe=I@Ox4d&@p)k%W()9fus%Pe z>G&Vbx3I>Cy(DQLfPdQW0juvD%(VOJvB|x!oSX4HqE4Dxz`u+W(^&n%2f_-{fJm8I zKOi3?&)2tRpx-)%r>Se2&rMSbT4330JvSvm^!pD*sEaT^Wp{K-z;7*o}Z_ z7U2Flb1md5h40vLpz@T>n{OCy)6_!`v~sj>(9GpE0Y1Gyx=yJhqI7vYS##5!&t1O0 z{b%PweRJb}0rU)c?)zzhyOT<+ym;+Rf2jCpge2cyVzR3(Ytq#2aKm4MBsFP@weqQ0 zl9`&`;49K3u^R)W)wjtP2>|rDM9Z!Eg4qmRQZ|{zOW=<NGgZGAA3w(wQjm?&ekoRrHCB#&&F=dW4^KFzF(CnwkO+OQ%$OO~+SfF)c2dRTB5_p|TH9Gn_wTr3t}bqtK?L@AZ!qct ziPHd-hnNGprhK?YoS|iCT#+8XW9NxdQ#P#%pnQ35##`XVZ+_jCCR*<&0nGEW;azDb zos1WlLvs4HcItlnQtU<%_yPE!gs}M0g=}ihfBN=%N>%Q?e81-g`-vBk24e}pMFf75 z_Gx!INc;f&x(SB;XZYxIk>z99rWRoY{s_a=K%zE4JC#oX7_>hCQ_pYzjQ?Cub=7GR z+>2XD_9ulV-)CPnXv}t;{KG6egd99~RuQIRE_ON+S&dm)NQ}}il~XNR4$#Oz*g!xJ z1_0o1h>}UWvP6c;XAb!^7k58wUwzfHeX``a?h;ynHHGKzjt`5ki?*OPOX)#~aiTQH z1A}LeqSljG*DJFrJfp5b@W;Ny>z_^uQ7W|gQLqRGsojXcp3+G#)wKZAgoH~#@~2II z{bnX=Ejz?@0WWU36P12 z#+;cvDqhF5YNsv)Li<0x~mz+#Xc8lwA?4y9D&o zazAeMPkS`L)&O=In5F?Cocy#hf!-esJ)x-}!di5!L&uu#>QyS-uF$S)hOMTl%>Q@y z+SYXyO)V|2q8;|^J=Sf)n)SKLa4e3ORY4As*TQY-j^NrUFm~)ZbtTK;GDCS=lVIov zA`nRr6F`-??WhxAE10cdTbA8sakctO8-WmjAYHY}6~fN_eXVkzIdg(2Uute{sAFo+ zkX`YZ^Iv#&rl;ba#!P9dFxRLxW-lV+Elf08bG3=moGBHSDz(@is z6;>*xhA(eZSbpSSVWH4yEds*hOz&KX({Tt2rn+6WdQ?Fdhw#=7KMlNc>DEmvJG&F3 z7A$zLt30x+&Hl@BukZ9dX`x>4ejsSg<@)0)9s|)+|4j4VUTmrF8S$z!m%#+5`Xp@wJSB{ zA)9rfssHDOI;Q><*^@$=iyt!NO!kznD>c(!UUpV47nO~rL2HYp@LQwrteIPcLe1&cNDQC2@X&8 zJYWnUv5G`YfEY&pWLkt&fFJp^N>+#R=XO`4G36h!ZV4c%{`pc{&X96upiJV^O|f6j z*0QmQ0oA^-;cjQAM8fA7JQZWY>f`=DAR!a7bTY8!YeE+y-v3<_kYo$s$I68ntxrpPMl^5oEeor&%;>>J3Ag`G9do70RZaMH9Dp6tvxGjK~&!T{CgD#{`%^sj;mHaM-%FT^orc5JE zr9%UPHgMqlR2YAd61D9ZOU_#vd_;wo6*Cx-&On3UKm5KHKzuaem(C)SCtoH6dFlNv z^gh0zK=7x{n;YtwwkOF;_5a)g9eWh2&G;6m7;wwm@*{tr1@ggR%?H&avCnQr^X-HT z61Gw{v^E}d{TrJG&hg>%(y`0l@Vs35;qZZiHu*|NtXAcSdp-MBtRd#{UI*wd2DQUY=?cayT=2zuigyoaw*fi~;!FU0o%Y%0jxQZ*+UT!RU|fPw@ah0zmQ;gFq*GL1C`)&BAumlBwPA%MSF_zVfS=`4rDRyXeR9^HrSJb7BbL!bz70D2Gs z8M$I<;bHM7#Oti`^Hn;>Sa{@jt^1bid!my|)rQ+%7`35D>7KtI4{hJss}M_zl|RZ6 zL0DAxi|s=9!@GewK2}tKuG+R>Ro)(w{P;tA!N!}wjNTU|klO%IIMM?gOD-Ocjh%9= zR)y-Ds;ku&(8MLG`3(U-$^esu_Q&^3ZGdouAudjBTa;gB=sQ3;pbv4N(LLFF`d64+ z>P;G2w{H5$d%A7jZ9ae&=>DXinSO*oZc+Z{@mK8Zmq&e^p?xD=E^SnUP3Ut7J)RFQbWKmwoBK&uUOy3N0Jm% ztcaVW0f06D2WN@tlO#;Ipm%5}4q=tm4IPZd<*INqZWxk4cxI8oqHuEYJ(Fet>BO}0 zYSZeJE~9Q9_-C}`cs?xCqV?HWrlnM9KDcFCnP{H8tf{m>l<8Z&)K5vdC9kw~EnR;w zE@--tk{J4-eqi7x>SY zDcpv#U3H4Shw3J|#TSSBOP0Slo|uj(PLkk5x=?E~bY!cv%#W)%VR24Y=VG(K2#)}t zz(b6Ozm1)QoATfkuW26vBqGo=lmW~Devtg#Z#}$}0)A=}x<;COUw)US6&6&U+{NyX z#8;^+2hCqlW966@SLwFUM$Y_e&L@r9yMD^UtZw`r zcAsw<+u}4U_!Xr|iwkBH8X0WgDYgUh!nhBF1A(v|tw>WAtY_WZe{aTuI}AyRn51NBrFWJvwnWYrUyrwWVFm2o6q0#5>vA( zhUzC8G#QFV7|lV$4~8i%z>hh9kQ9yiTLE*rdf5TYY&{sQ`C*8yDs|EB|A5P(5# zG0WG#sy2K*CFspJM;Y;aecehm?HdOLzAN$MR&(6Mc2Yzb_#nJFEVW1_rY!%jm4Eqaf- z)H+5E%Q-P^A`+bkfUsmBNnnUb1&clT%Y%h}pRC@zy5Q#f>DlpT~A=a!mn zSbp0878x~-d0h%ZvDrm6Rpnw$=38o=4+*Ol(n z@~KZyn^1U~+!%E|*8lonX-X?gln4H@21)B>k9mh}HWv6MA`kr2+G6QT*Q!-3i`m6) zY^_|!;d4FU0(|+_q>%7Q-H%d9%`firp1!*!PhBiw%UG-O&U!;LL!DDUkf~xzuwJ+S zO!8Hv&=^`MPm*k_33^U?A&Fh~;_0E#!J z0l@hHek*RV^)1)9939%hu+Ezb`43$%0Di5UMtAP)F&FIv>wK|oscK*fzyJVLu}w0z z^)<#QP#(CKy8o-+S&^6kgp(g&5AcTzqf8JEJL<9IXqQdHnry|jPh?+n?YyE6RmUfha76%GTw zMm|9!|Gp3=9Tjze`$LIQ3chi4 zlDliQ#l-PM%17U&Qki_-BuVDXU*O#hclfp|F<}^IK=?NC97I$vaw$BC`!cdr&!xvQ zwCwLc1^>KdT1j4G-bF$SfHO9|IHePP^l(AcF)+uEAE_M=&n=@jaDr7h2!jAR6#yR0 z0M>h#c(6or5sz!c(>idZ!w*aY(o2H~5*i??7wSV`qIst-)jMCEF$R(w4ElW4DoYH| zG{C`4FDM!;IEMxX2SnT>$rM)3#-5eh7LNfxHUN5b`>oNZ;`<`JKHSW=pI@s@PF{OL zOLy5Dx_ZmdR`>oH-ZjELQdkbjxEt!@qboNvrz(q*hzA#KME4@3b+M z03V<)F7ZQIC?8Byvt!-+iDm!T%DZn&NSx6<9)tL%)>93a$lESD*ItmEC^h#d11?O}&O|q`^0aK8zpQP93McE~d>c z|GGYXBKy4jX}p{P!2M7sk@RB>52red@hjgA^BXk(kU?WwF`eB1pMgIg--|bx>iwJ> zjNIpy+Rm40eczf{f5n$+)w;x@it%My`A4!h7F@zpg6o8Y$HUELvQYbK%*umbSLOM< z_%f}|6eWBN^j%v^jC%y8O3}(e;8}0DBo%O_H;>6y{2x+ z_u^5sQdAeBL*TF#sQmE*K@vIrOJ%<7$yvIV(sQmKF69+FSAI90bVLInIu-m_2aa@7 zT0z4g70Um_@+gctqL2ZU)A{8XL^%EG$?Bbd^>zo}dP&o6lV z^6!8-hm!9lj6!k{t((&)vfJL!F*ajvTYqgo+HRcf(nc#5hn$m6)8jx1moy;MFAP;5 z?T_ECqai&Yol+VtKW=K{$mWX=xAdQbatL(EMLPJ=u3nwoi|qZ}Nxx$4#*iUz|2`k~ z1(jvUZF;bapU7zKAKo!^Rb<8TXD_|^3FiTTsE<&7`MoI|E*KH~4hOWAg8ANyGcT@Q z?M7*Kx%&M}esaN#qW=$gH~+mEZk{uLu#)Z%7h@5PO=4d_9NJbs<{%vOxYT4eqQuKf z*LV8=(027|!yJB08(R;C(NdcB93O+t{%#!s%KBJzj)SN*TSJ9wg1h4 zw-H<#o-%JmmFrs~rp0Xi+~rEIMTbZ9UcTS6xA#VVY%PC{1_=2T1>Ap@woBz5k_aC@ zz7weY3(nxnn7F}TwSAQn4e)5LFChau4+tQFyZ{mqbuO`^i31{aI;5x0hA=9RT+B<7 z^eUz+QpWa3&qYTDR`m8xk>RmW+IXTq(t$91a3*Tr#ExyV8FQ!ehzk4Ke%5G~iBj;DOKRQxzIV&kprc}# z=;tdGY%0eW|3M7HG(bbYpzr><^ty6PxcUWY0gN#LsE=4D@}IkWTYA4{E;e6N`O=C2 zC0kBo0m5n8O{2z>^9SA3x?ar9oK+@=`Mzkk-*T2=D9|q2azyXkW@n9NQ1Ms{kA@1*!tC>fO&+yhxxo7 zhdk!UHzhgM#qFe{gLz$mzqru{m4%Ld+O{t%Nd;Nk>?Da4F0vK;^Ok7|E&YLeM>r}94eb2U6AUm9?!CP|)%mBE#b)(< zGVz;2$v_Nq>%?`#>e_$MpxYticlxgx-E$z9$2=h6OVWKpo1sIdm#9Z#I74j~!tz$=>YDSFYerODP-=#L#1-tr;P2*@N$k zvy#&vIrABiFv^$JZtn$$S}s?Q+J|y6exMHNB|IZY6coz0>zcT%#z=wL0{(f+w2ZX& z2OjL()@73CM^@9MjXn6Y-rWC0QrCW5HD5CB6b!)Dw_mbaRm(|gIjb}Cr9I0TU&9aZ zw-}mF0@q|fno1jDAOm5bL&v58f}|4SoaMz3h>PLqh&W;v1WA+*av?t?b}^q^vw#5w z_oHXPvL=vz_ciG%@eg$um!LrnjX`v#28n$rJ=i6H%JWA7ORR8)(k&TU6R8udIBek!%99`58? ztX{1G59HvFd;nrd=X|$Q&CHs^ZEj4NlH|UApSvvS^0m9s>8n!*Ui{v`H@HJe49J%Y ze{&moe%L&b3BbKc3xPVof8MD(f~7HL=bj^-Cav4}s}w+g{+{8QXtgvKg1!ok6#6v4 zALR9=1FO)ca39w4%qGf`l`b?ICBK+-Zq0}uRj~g8jU{B~lG45C8R0_m$J7-x91s>X z3KrFJ;MkPsczEI20{$>ist`F>;?9yh0AHhxxqT3f_=sk8b!DG6O57C}#yK&!LM1~6 zq=98F5v;SZQ3tt(jCNqLEw|P-#P#Zd!qViv;z5V_5Qi)h!-(Tt4n@E)|LDzd#6k-$&dMN99p7Zh65G9 z5tTlwB7diNpOD`1UI5yV&PlaPYGp71B&DMaLy|qhk&eKhRL}?)sX^_e)4%|K5Y-EV zDmt{t0EqeFr*Dv^8$?xqdGpm5yWRipJG1b!e{SG=yUX+D=IhS$cNZ=(tIOvaQ@&x2 zR;l4&f1Qt7e?58;b#I$CeTM)^(?$MO{^di8M_SqhZ4Rai-w3^1fIkL)(n!%eOtCzi zR2Z&yVS}$_>!vU%)*%g%ofho%z!V&gOa_4&Ck+QN$bpaE#Wra7sa;xk$a^}Y^vSq5 zbzPFQMc}3BvcaYc+io1yLXv8!ngG20pFh82rIaGrk8*0|7`uT-ukU z{t~r4n4h;< zL6Z830SE~SSw3O)+Tm2LF*nP>pLayXo$pJ;l`3MTq?@86;Uj~!HW8QrFaTJl1<436 z0H7~|HU>m=Mz~PXk;>c81>d=e{GBq!;DxN5No0)K>g&nT(~PcaSo z>HX0)x%fr^w0I|E90t`fq)H-b9-cD<)PYEiihTvFw$4B6J-Uyy{vHSKfU1`*#y)+! zUt)MLwk|BcZqk||O?4KJX?TV;t?f&<`o#4%NvSjrQeS}T|K!0JPaFCK7n4izCpx*f zHf-x2D2@3X8w^p;@Od>h4R31H_8>_fjyWefIu}$aO+T?TVJ)iG$p2|bc&zhdkHNPb z3%ahZ)}i}$4&aH>W`&04fwLr})b~vkG!xYRQ2p6wmA0+(Pg~sm z$BzMH^Eo{Oun>mqpvkVbY&t)}nwT;Ic}hzR0gX`@>jFI5OVO^bt}G-ZguRV1`)J0d z6{(IL2EiZ8v^+m8U_W-y)g1xrw>>a62SXJSUChh$xj*q0RGVUlQ}%l$sdJGQR{h{| zs{K+_XRT;ta70I=GDw9=ppSB>V~QP;(jy)u#^DICQSmvaud6CCf0R~?gJ1q`5k{a-5-byt##a6u3)jg9oG66!stI6-3XJnhPQC&Ac*a zo<5GLjkE;*7T{wxd57>hGrxgvQURG0pwp=)T!D z-_9Rl0I$~y)J?s%A~WfCLjqr@`>|UgNc&3_)-!ZYolT=#WXjG)I!EBA$;)_=k`_S( zeB1}1kNXnygzt>T2pS)dP6U6#9E97n`ev_)!1bK9N4lL9133%P_ zaQIEm;b^f;t8#VwpZPMaDVm6BZ0qMkuODdYvtD7QI>ka?{JUXFFNpBTj6(21^j>tx z;4-b-9PF`7s~4B-SXEcf00<;g@6rHC0D^}H5!jQ9F!94dJ^}-DSfrz}kdFM2u86az z21Z=MGOZyOU;nj1K39c%5sAyR5Jm$(z`&a?(^8J8z;4AiqU4M()AHiWv_|k<-0|{1 zXu|T9$e$N|$>ClMG$H^{808UNN{29jg*+{N2dJa?jUqjLdt&`*dIIH8-5$OCYkVH? zqs5Yu;@noB%GOrOff|LjRb`V^g)bD+*_8m)(Z1qXK)E3~(fei`@Cl?S4DS)|6+ihq zMH;-**Ss(=0vJ;a-J?phM`4~M8Ng8;{wsIDdfzE~5B#Bw+P#$<)e2K=Cl0Y{Wy(r> zW8%4kC;l3z$v6MMgM=~cCA{yU-&g!E{0a1pSd=yhnoWX1yf$jfQA zHF&4b+xQ(_y*$1$^zQ0^=4_@t{QVil_CuA@Iu#+mM{3vKyV`mH#4z>%_(6k)xiJrp zPm_NQlfn^ZYHG5XLtAN~@3H9)Kr6lL#GvBsfueBS4h{H06UU zf;oj#8FZZ<7oApoMlr7l`l8fH_e0(r|Hj<>dhd(MV!k{-V;BAXovf_c3C==c4|9ny zzuDZ@NAd$asC~(}G9j7dkfEg*_B0}X)v?AK=LMTYM>?zQixrvOae`K?YsE?=_z#}{u>og+4s z-@mQ%vG((m%rI6kTI)Xn7>cp_48ObQ^XmBok2iGh z%!YA5U&#TuKfs>|fZVIUi!|>KKTSjS4x86~!-%GSlrAkUFJIYj@%~zCM)ds?pby~} zQ{4?+ZS+h=;N=j>&`=zwXdIz?0Gmj&i7;YHC1!yO4xocgH-EBuWUI5%MH>Gk@XuSO zmA6bQjo(YUlJ#72wCYE*I$S^pGSs=nK@>-lE-15(tsBvdJ)2QVuWA)<2xb7~z<`hl zorXYMK4?=KLoVep6elkyrL@S8^aK#3aUw86JZY}Lxr>Yn@_>t{&g{4I^@^E+Z-yaH z9_d=(pDi1UT3K7(e;)KqvLS*+^QF6YSVxn;BqL#BB1ub#Z-m0A4H1W_CQzY#<}u4_ zEvvm{LwLQy%wJE@>;H$LrX z)KWco;!f7d>KUSPO6wstp;KK6P!Lbg0Y>1+;mFa`UPKxkB$4+2 zje2`~Te`3M`9;gdwl>sG@-{%bVVVg2R1d~NB7~7~AO9ZjAMG%wCiYbqk|gssUAEJ) z_RJoO_(m_Ci4i1ei~tJd>H*8rG>mnTP9_uz&nr7p5p|+rE!A1!b z8>^`QQ&_~G6rNu9R9AOj#{y`A8w9m;N# zEnn1U+FQRpdmFi(skBNw%k6K2_0m4lY?)C~no__DC{cSU0y&k1`(kPu?FpC05yX?) zALGiii1@2ret%iR(3AvLRycn7P01bhliip`^_IoO++zbC>Ln*V_~$Lt(i!)V)PR?V zK^&lC_=8M7kNf|!Op89yw75rmx>Rjkzu*N7z!(THc!JQ*G#DYAq1tkSIM%0S5jEkPSrXgG5!IJ}|)pb)TG2CbpOc@$)Doz^5>zC#D5;rMWng@~JEW z5@G@nPGM3S4f~?YzL&cx{r|h$v0=mEo7+5J2-Pux30df)4aK&@p)%BW#dgCtreiF_ z&+i=cP5qQ?dBlA1!?3sb&%J)-d)`#Vy}$qvgNJxx1mN%Vu!EIRP(XtBOxW0`(Vmgd zyoQwJs-*~ncgGYb+VSr9zGb!zX{$51F_<#tKr-?M6GrNPG&r@7hy4{xiR;b92y>2PBS{sy0zz;uw7E^gt zm#EO#Q?`XFHI>^Tyq;60N`4QkOG)a_SGO$dD5?Me64OaUK~&LJ^q9&-8TcM)>;v-% zj1hqy_XGj_K{S>C=!rz|UsP+8!CevA=E_Z(xpFU`WiX?BI#;p2lf}eAoDoy&!51Q$S2 z9O=vYT&R&k&86H%4N)3w1`S+5Vq`MO)7Kao^?a@AJN#|MNWOInP=3ai%hFaeR{Ndt*JB z_X&3z*df^=;Dg6t^3C~sH&eW$*H@`DSMAh_T%|=tiB)+;MYT$)0o@TI?o``%Qe~8# zR5Jyy#^vZy&C%Cgw9+`N@?oxnv6TS(!?j#t0|!V0NJ2LGI?i7)3Z#eTP!xH@F2 z6`I^?sXG7GoE<0Q78r3~%L@FK!uEHU{>R^LZ&&(Gh^~fcfB{=yD@Oxu?5@n>&-;YA zr9GUl1jUrdlz`6fkKLiq0Px@+kiD=;*7Am)!CZ0EK1%8zbbi{AKAw&?1UNJe#WUZ~ zW*%?lBYpc>RI8@?R?zS3)K5}Yeo_&(nBEnoc2dzi)3gu3cgRg7ia-^kf*T@aXjc#y#)S0-mAXx(vIvN zdSja6|JEIz8L6D}4`NvGo>8W@57!ftmaKWk9FiUmYurVIOK& zxctQ+0X6@~5sq=T*3$CcQCa_CZEB&a>U-skUkgjgzo%DAFNWH!EwzdqW{h=GrP1u4 z9Q212eXiTweQk1mj7#|3OR`nlwzhfwUnN$fBIBeg3oFg<3QE-9xRh5b)z?&=_g_*U zO*^UQu8oed_<)ntnnG!!U;!y8F zsgu73GfIF!gR5L#E3FPH_~3w{y0$s#?A5F^YR1^APFpOgwAN}%Ei*Gqem`#>Eai+c zq=xD=6ej~{-pAWs9PBifv>-$W{rsQ{v~ioG3d~|>GHvr_hv3vD#h?uV8A<-o zW*CzD05%2~w3-i&JnYr|YTRkIp;fJm>*HyK682tz>spVhFIqI`|NfLUNqv@-%sNH= z2k_!~5Wv9Hd*71cdQj0y@9l5+W&}qhy}ZR`!9mcPb{>VZ9%u^FCv<#(DU~Z^2jqw3 zPxJoNE~Ohgqi-2SRZ{{F6>O(`OI>aMN3yVDnkuOmY#7dOnjE>spty`u=730i5y#6vRJS0Lx%e08gku&KIr1Ahqk3dqMq4_;Z(-p0qE2Tk! zBt=TsKT|%$>*qz?;EYJ6SC7kM`O$X-;+}D>zf22#-q<_L{vo9cRQan9kff(ZMYU=< ze|DSxeeA3M+JAOoQ`E4(dIE_DtVe-pAE(aO&Q;y67um>-AqF5w{cbyRXjHHp>6{xO zOE69tTJKL|96wI--6bG~WQ%|m3vL}d7iVPL4)mVAAeqnG)a$fyF5UX}b3R8K=b$Z& zQKV(luMcA!fOXxoYt2F%)X!A+Xd8+LW%}AG)9V zY4UsX+zJ-Sw7I-a%6cZO&S!mAi`G3~_pdX}r$S~t$BuE1>ic}_V48>L!CxO2&@2p< zWq0N@wW5>!;jS0K*tbBy575Uqg@7pl1TaoKGeC?K*;D}hx4p2{FRJL|LH{-{Jl%cu zxW5O@a2ZK<9C9Uk2WZC#TYu+Zv*Q8qM}DzPt3K6u(8mW&>PKQC#4@e=^b&W10_LK? z;!dq5G0o4`rqqZ3OEPkUkmBt!+U`bJWX-7Bl#2B7`mEdIvMzsNE&$aK5a?x>Z;2tm zxIrphsM@njilrR3c~eK`)pX`-W2N}`V_u85e16_g9gW2$_&U3d3GI0YYI2e$$w>@= z7=iqn;2NNVd3f~6;~%$Sgku)X!}PVue_E@W8%HZECL|Q1Iq6FLPAUE5IcZS;=cKJM zhf@ExJ9>niVBmlanzl;nQ++(Ud4U0d#82nDKjb?NnLF3uw1I)D9x4jj?=N!KlmK|~ zzDNa+%9`@t8*7~26Y`Pdk83jW)4#?&1-@_SBR}1RddZ6_qaa1Sq=#WmJf zRIBccJ)wh?Px@RjVVM><8_a3YGA;VBc)&!p_-8>NjtbY{LZ~yiMmaHIwLreEgSF?bf7i*?(G|dtfU}cb_c{k3H7zvxh!sfMXwNN@Mq98oCM#is&$4e% zg@x5xM8Zi~^efAk_49OiS7N}*2U(-RA`HEEKA$Pqz|D3#wLkLLO8IQD6W$jE{#xHK zuyzigGP5)41wP@M!*_*%doaV$Qc$>jtZErx5g)X*H!DxsEfE)ay^Ok*8cA zmiSR1V)IN2F$>5;|J=B?RB140ErOtcpnw@E0AnTw7E767BwM1SHQDz(#(`Z@jy&jX zDc{a?sy}^WBmk2X{m(0!O0@^Tlb=^7jUXP~)G-L-$IX3fW!J1(*_o@Jc}TjQy;$<& zAlLRX=tJ^LPrCbl>d0N+2Yo$xBj$J!hd@FN#$)td9*5)n;Xk29!jW@5{J}=yU=84h zlz-&Zxq1~r`uFggD96F^4ZAp1F9UaTB0Ri;N#Nbyx|{QD?_S-z0{9gciXyKWz7^8+ zpQfaM&CP|cyOjQK7yIzw32x!RQj~Nd?4#VP-!4p2F~Hwdi6X!748>Ok7RC8Y%a1qlDf zfk~z?tVSKlNhM*c?`aDg1b+}IrEUB1tbs9tLw2FFPT*PR1ZKO0sq(_ECR*h znY#C}Y0})JT!AgP>3pcYoey**cG2I~Io4NuLG_7>RuI#pMAJ zi7R|GRjQ&z0~Vb*u`|446SJOYMK%H;Xb#>`6~R}1ut9}cROznAHn@B2+b2u-ll(?W z*iV1}ACf;D+`u4ncl_kUDMhn8ZZWd@0uuNN#n7I4({d)OtrYM(r)A4)PQyg>uoIl@)Sf*98=3B== zR503zWm^0PBCZ7m9w7y0tcZ2~e0ks(jLGk3YO^!mY~Q`}{F^sS&2KE<^#xrzRhKC; zXb`7)ZDVC9jcG43w322wQ#~gZF57isedw6t=34#nI@`@}P1(ExfB}F913yh|0#M+& z4%Yt5oYoDEp5xP?0Uq_;l(X-E0exGxusunjPtraFuFx^=|cyG5z#L4^M}nYt9SnRf}bY!%Hlq{|0scO+TRa8xzSy@9BMW{(KFULDGjYG#DkE5di)O z0L?vnb5b`{K0E4B(nW4ucffaaeWAPGQ%^bU#dh*nRWoXnVJP>KCbpi98WKt64uA$T zg(;MV7yx3rs8Y%g4FF9kQ<|Z(A<#!Y(n#=SXi5NaC`VII*z^bLe~;d_Df=gX;sfVC zRL&&uM`jR8EYl*giL;=9pn#yj&zAz}<2wx+Rz&A0{AbTe^Z{K9XQlU?mU=- zaanJhZMh#R-SvvgXU}%A3&AyMNC^B9hd>&DxcJ=UfP{iEY-Y#c+W(r|&3laQ=j8b6 z`1b2<9IamCnE;!!%Vh8e&=a`wfD90Zik?;hpqHeI$2FV<@yr6^i1{J=H(~<#dXbM0 z1mu`zhQzP0ji9oWk1vaBM%%xw3Z4J9Y_q~8nhgG28F48nASfUxASm!Nroi#QjzI%` zI&22`?~2cn2KQ?xOa1`={I_<$FyU;-*I)nu{<~wd7LGrd|Dm}a2b=vY`TmVt1pJ2T z1v5Yl08`lnTTZ*Q!%)6Q85c9A&6Cf#JAQ2MWbKP-5d`=`Kp=pXZ@2>(0Dc+(_7w!q zd>LM?kK&}-Z%D0AP4IwDHfEHDGoQ|8R~Q4OxW~{wkLkfKRBJR}=2es**nD4`&zGU= z1`YlwgE$Kc2nq-a2nzhNC~&Jp)omc_GNgW4P0T=E4$R1KL%7eGlt5`5yN`ovdi<-d zE16<#u3K-jNss?QO+fHiuL0Q7`rJ+yo{Rf6rR>8^i1+ zdMzCv%xp7O_4Kl-vGmq;iNKbC7y#dn8H=}L(-{DM%;)o< zU?N~%8bPbjev9+)nCyM2liXGg8Paa4WMgT)ePjptv8`D@jSN36XfNL>+rp}t-B2~j z!=n2KhQEBeq4dWYpAb6wM=7*4f*A!y24;s0^gS|ht46DF=lcZUCI$e~drJ=Z`82)^ zT^j>^=FXfsUy#01XcULlYSpRJ@5Ed^GW*pc#+bpT#jHVqzgfvCDiahC6c7}6{1k9& z-J$|2eYHYyDcWmWz(6VdGJ0j9s#{E%X5m0{X&cPeajqhrReZW)ZvImt5sBknKk(nlCD%#ry;&^N8SqO!3E+uA zKsgpyz|`?qH5%zV3rX=^m889Csa9uct+jc%q3eq-b*w5oJ7Y%m13*8^?6@yKh5&z= z4B{XtASfUx@av(#{zG?T++A!`^M);d>&*1ws;pH?c|QWJg_K55sRJ3@*TzxWPd%3_ zETKY|gQeEu3fsA|o@U?E-M(-1%MxJoXDR*bx-Oq|3`%TBcxiG6mo{D0R+WyHN-d@X zEHu_u>WgQ~s;*U)D>W82%A4;*m)oc{mHCQ_iXtgjnORg+Ro1hoYR|ZFng>9gZ-lO= zPp7M9KMU}0b`pyQ1O)^I1O*-~1tuOTJi%H#aYol{L9Q~_t*f2WdwHeDS3ZKSSg4id zFzUN>r{Z?}OOf8bU(L=~pHL*P_eb-X^H*DGnSjj{Sf+6Q066HO$5K+|AepQFS8}5KH|UA&^KG6c7{;6c7|>8U?odI*;{ox8M7* z{X1=WO?(R1H?|t{pe0XbS zt?3WlRo&a_xA*R31O&9Hg{r2rrkpIVv7HT*;XgD??l$%x z+z=4_Lhkm4##UfwawD*rg{=VKyuBMhZebz-(BO~*%Gry7%`HHlj$jo}c~xUiD`OrL zfRG?LzdP@T02{EgA-TJawXGAcy8z%{a(O@6|J-HrvNE%-va#|4f#m;n06w%inwat`i%b5O zu8*Doz}(r{o|l=~&CQL;jg869(Ttgehll4M8LX^~9~6vE9=6Vg?u@ohl>d<+4t6qj zw6J%!u(KuqN1~yTor|*o;KR~?55dM>PVT=2+dBOhP#=&nyBpdwvoHafZEXG-*T1Np zoRz`<+l>E_+DX;J9?Yx^cCvGEH2(01Ddm5dKd}41EBc4m;@KM*nedFPrN`j zRv-rpCnvk81Pcp`1Pc$lxVShAt0WhXgebR|DDXeL(zZ^{hPKAw|LC>&(EDG!9RF8d zUNJ|op|hQ%s-2znew*AN$$B)#= zi%ErtfS~^-EiR(!zI@_?=#HaycV2zuBkg9UKSYWJWr%F0IRFv3K@*sd5E(hzFS1|T z5)-@48N^nztuFyiC=IXrK})WUU=MEUG@;pDP@Vs}WOLwlQNDH3kn%#ds z`=eEHwB~h`ea*N3*U8S9T@IS;aY#z=Dk09-s?UevA|cLuhm!1-6twu-ALi?~+b(~z zp)?H*fCb@yt>5&AOW&>~$Untv>zRSOJ86mHMtL{d_ZlL4U8(YOo95!YWeyY(!$aWg z&wC~D>w%nC7VmDcBXq!f`+D~i{jQben$jkJ(Dpl<%jcWe{>qc_%CEmVMMs!J7d4-E z5771N)RIr|A@Pu@3>t(3CGL*UvE%~KvH}E+Phoz$GLkcKPsZ8QFg@(cZh?PGRGL68 zvMy@qhZS2*XuO|Otyn%}ElKz->ShJ^9uZi7lDL^{#RNe%bs#7P zBPO4AWYL6lE89+>w_hV0f;KQtd;(M$jCaCa7F{x-rfU^xgcz z{p7F4%8#wvrjq>5j@mzP#foo zSBBSxO#0$_gr0SINYURbS)Ukv{usA#d;@xLz~oHApByml3Ja5v?a@nx5Blu@S+dcA zHG$r@(TO20=&_S+u-<5MH($D5e58Sk%s=dcgy$Wm5E8m8R!_#UFh78W3krMftiLMU zz*2qVcurL@d-Na127YTm)-Q@IUbxaVIe?*iz(mn*q<{1u^lYL-dbagnbK|y-$sMwj zDew{8nLVy~h;*+&fw!v}!`xBLt*hmKVON7#rx}?g`P#js%llOxa(i3KI z{hT+u{)=+U%s6it>JSz~`B9%PQ3<4=i|uV;3rXD78S}#SGQYKuf524#1jtBc5TbZs z^BzRbe(EVizNo$JnTPP%p>!kR5)9FCfIGQUAm>8mu_6b2E&3E-Vd5|*nvly8r~;MQ@00#&hHQxsvYKEI;l;# zTNmc}5sP#YYc<+0WkW#nj29;I9jN{w^gT+i1F8q2;p{Koxb#B~)3aq&9{PbbZbNbv z6PB!wJ$rCj+a5iTcO4U>FSq1A2R^D14E{Ia&D`>II21eY{JGFqvkU&_Qaam#f!@#p{W)Dzi&F&Cn$zh%-{+*7Sw$0tocp?vB?YhfZ+!wo{r#AhBM^Nx z0S_2&mQGxOEoR6(95fleWEJs}RPYg8B;2uYw0vm22){ehf3DZT5B-zP7vFQC`vZ&= ziMWCLDkp2qp-A#A;X2~?-eQ8J>Ehjg$jDfMh#g#ZBXLw z_GA+X*nv=P(b0X&B2Vbqe$lk6uti|0q1u#!8|by07-WBbOV&l9SJaogS-VXh^AT%) zO4(vZav#4wn2i^p;BTnBH#iPX))-#@ZQ(PUbwxk8QU=H`%-%Ggp#4raTqfQ?11P$n z9E|4xcZKI5V^wic-E?G^&3!YSqri_uQVXWi{jvVUERpU*irNXb`(}?+e>dUMG+fVBOMosZ zORhVr7#MYsy|<(Vz#hO%jjxvaVM>#0m}!|(O>`8&KB#x4fX%cm`9XB)o<0)d=G zK5yEL4SDfBN-_^Dip^~e?Jsati@6)usn(%Pt=ROf%#j39K2Wv7QFG&G1cXVcNDc&I zadoN(hu&%d(!Y>;3}0%z8Ev~S5*oyh6p*pb$O}t5Z4o!;cF2L&GsqjURp`a--27sj zH(U%+N?OS(ktNjmgQp_vk_Jv9B=9v-mhNB z#?@lgQ^Tn!l7775iV1>-OR7>Ar-2W+?wWf)oO-|X8jYDFk;F<4zk`T3U(VX4#Gsj8 z#Ii^|7+H*7p&%&u+VwM)GrFxwj9<|8JJ@B1Dv)izHg;gI&mRld;b5slSB;7#%1WMN zUwlwZVH6`hWiA^R?%{WmO4`YJ`Y$ebk2(V!b|7I-C#+R(w!#ftQR&j1fhhU0MR$T2 zBr5$ltbfC^3{(ps{KAcMc~|P!`2KoY_AZNjz;!q4Dk;anS%W*1Q-){ueaM?uLLkCM zUs2`ySK^;Ssn#JvdXk6Ze^IwEp)en(7S;9$Zr(#jMX|&j@)0RF_?S~3lcp8FIccdB zpw*qezAcZy?7gDX$MutGFX>HZ`(=>l3x6rD^t!boZonqM3|@`5po(5jJyM|?+SsFU;D zrRxnY(c4;e(9wxR1)==c&4$ogNRgC%v*5+j+}ZRS0R(h7qc_eHSgNZbg>h`r%~eIT z&&u4?xNi3TVQjQyoWhCCDbPPbkSI8i#q2SLo5t2$j6Q1LZ}1;31*|0w2yJ!)NA8e3 zlc^V&_K)I#UlsL@xFDo~`}#H?zW8>(Df$i0GYHe?qP*v5nAtUyw%__hwsCr^&42WS_#>v`GFilSaYW0)Ur$Fhw9yXA- zg9`MgArs`s6~#G4(fSu3%Q<(d-vqJQh5F5qb-FL>nw;yiR|usYGlKf$p^}mP&nIPA zF04?VShR{(D4An5NMa*ja zBdilwhcFCc)W?Z2k;XHK+1N^GQv7RZjYYo1;7M1zP*1W^sgwZPO!%8?wuTGk6lgJI z-vn7R;GT+rh|Nu{-Ph5c#jl{h!pZf9Hp$$w7y9#z1B!U7U6l_&S;@rl9drlf z9Gu8aL|I@n;d53?laBa8F6a>!*?~EY%ylE*J?Vn*D2RJWaT6G3U~XIbW@GXrJ8ORM z15Nt9M8EU9`&KP`oCB~Cp=!VjH-!JyC16?#^&|Px?>3lv$R;=8@<|!&g@3v~GFGcvqTgG^awHy@sO)E-6R3)Mwx$Ea!+-kI4;RytfHM7i|x)2jQ)RFFIN~tNCecn1x@;aav1K5TKIpcN2XL zH!=pifTJ}bfqy(cA-T~k&e&e30eR9UET=kA^Y#5pG}6;7JC~w$+M-p`>dcR%@GK>XUc9EhuRz2rDC&G!b+)5LzTP1?h7Y0_NF- z`%U-TrEo1sLxTH4Ftjq*#fhD47^3GSMSIh(zCZAPx$#cE8-nhl+C00WQcJL_biJ@_*!|7K6aP^7Y=$4Agk*K76a~yr zp{fi*j)5K`La+~py81;YoQKKpPYFaYnDX25?Yayh5yhM=`JT|qN88IGqKK~$_&pKD znah0MCI`O1?nHd zBDu&he4b2fS@L9E7v8rt$rvEJ)wc?cD>KUOz8mT{bRPMXj}VP>K8+-e>@8pac#Tfj zLzbHQX~pDQ!6SIx*(PBmv3@I1KoBmbTs7HCmS>!0tYBG-q3y(Fc?VG1J%~Fh`_)K6 z+oV|oSt79B@bde2QJh$A7J2Q#ZTT=B3Z?t4&rMNVy#^<|-ld|57ojE7j4nKjY|R?B zaG!L$?twgR=^3v)Jav6-B^(+gv%I_d%`EdfJuh;HK4sFQiVwmG+EOdVo zbZW+ha#qxXq&D2q-WDNmR61X8lojrK70-J9sXHAq?S=4c2W$Gcsuya1DtvlI3U&om z|4rAvVX-hINk#8_h-d^O;qN3DMKWv;jR1u>1TEkl$*J@+K@L##sEsU zA~Cdu{K@2lt1|%ol{I37XyA)goqj^4EK?|C2=&5K?@V5#N z%=nNW*Y-tyWhQln@vTfN8tud?!7cUyUEP6wFB1DzX6AKdj?^1F%}#6_eQ5-4u?Bd~ z2CTfbbG#{ZbS&}3BRaagT2>M5aX4cHNv4s}_r`nw<_>9E@_@aZR6zT}Ur`eF`cjj; zK8!8j@M=NP=_p69%+bkDr*;LY8JX3<8JF+OLI!08HdHeE>Cj=f(G_9JIJW^M?}EW= zQ_>#k76a!|hF_`FO7u#Gg-$lY-_7g!Su&k7NKIPhgqhkK<-u%3*#UgRzLI8rK2e1& zOw5?@zNYMIl-Yp%fQ*dL7T0TkqP^J_)|9m7K;p65LHiSOISBrF5$IcZux5v>4nvhG z7yzd`vHwmEk9c6fcFY39p` zy?a>E%49jy3VDmnhL9hWvZ}kW+4-$`Vdvi*HiHyhmNPRGas#mvCr6KiemZ|!78mXedZ(+(yX@6u&WAsx?0Im!u}02k*FXB*3&981u?YNgt3yBe4i6VkPB2W$9p9-(XsWw*t8-?RRa0SY zwl2rNs{UQLqyu5aw4kn_TW$@|yZ?{_?G!qI0;f0U_o~>Z!TGZzIezj-j zsRl1fwkAp~#H*pz-MB@4kMmPET6VZ!H0H+$L_+_{WQX($9vR(LfsZVmlKI{FFW|3< zATJ8r@FXn3%BV`HkP)lnoI@D)MTOs&nfQi$a{%elu>8d3IiPEkvlz~<9r?eqvo;EQ zM^9DF)e0mh=YXQQFGH;l5j*}MicF5(`321;XJ+D6?kZp!nHtV=^aBg}Y<{O|^UpzU z9_xlzkF~U^K;0nUYuk;js;`Fn%mYW5$l+^q=z-8%b;abE?UG#3ol|F>wKZghlzKnU124FS&qL zK?3J2);w_AG9s@8H70Y02!YtH>#tD3E6YOwo(3^DI6`V+%B#(RYEILK8l$AV&M@k@ zuaNqf`;j6su*actc{?DhEM10lrut6uB zKO~$%7+u((%Ta!A)Hx85b}JtLg}*a9UG$wS9{6;~MkNN8Xzy=A2o^VAcH+WNBM|2=1yHkAQ{If2azuJo1)ZPVY`4|$=+8j>U5_D?QPG1} zMtG=kx9@CXRf+w2LtjEP8ri^sDqUk+Hm*#>`u3@V! z3Kr!8CVnW^vR)l~9d85`D_07{8AJ)*@Q6S@MLKvw1yvNc)3K7kH!J^zt1-8e_3FL9 zT-xJgSw@MdxK>ot+#jh5nuD-@x8i?3i&xm(H*tw}_%+t35&HavfE!j1`_CKF%LC++ z*ZzG>wEH#~Eca41(F=_T3Wij<+>usH7`VIp>an)uM-}TYgpNwGl)!CXDDUDS_Cou> zH`3fJY=9JCBm1;|eIAiD|EtxRaefi5H%<{v_{Sgpt9H^XJul)vuLIANnLmW2kChuI+}b%mn!PZ0HEXO@}FNv zSy5ST)6|$XrO=*+y>Scvo?(*A?O-<%_cD4~zrw;Tz{~crZSqLcXUOz=do6h8fzW{0 zHtoHmDN$o~_dZD~5o^f}8JeOgX`jjYD{O9yP0%src0DjT4-XL|SA3Gr>!4=^>ic`w zbs$#Rfp20`N^=LU-oQ+aKyD^nXK4(Ng-7Rj4Wd_Ovv`ePYt1TJxPgx67XVZRO*ihn zREvlYfmZ1q4%;BQh()E+iy?!=6q?rJ$&3rZc9c}vKw>bC(q!I9tDIwOM0gDaxu%D&-Jg7&%Iu4`&fjJ$D1d~;IM9H@x1iXR-jIe!s*ArQ$fiC6 z?#M$?6NhEWAOB6*j>^kxcN~~lW#*g8!W|gJj+_EBb0q!q>q|;BwJ?NcIrIH@0w+Q7 z)20f^uEOB)O*xHur8D%d-9#A0P1dH3shlRhYgysz+3d*xjkEr?+#N{4j~G z1^rb$M$SW<%Q1=822&!j!~MAp>JIDudpGK98YqbgB5aoOP@aaN;rs2cm>u8^#rbwL z)cUBfb6ZIvbL7KNB#dM6d^w!Wxlh zH#1q;Y)+(Kr*Wa#LcTsAVP?)jkEs79`;KMVoI8&lAAOq!brs4$Be&m1;Av+rB&lGC zL)*9f`Z%K-(!Tw}A3w^U>Cg8Lg{6o+Z|@^SmxeRJCI>EERKUcm(@V+SS6t;ShQXFb zrlsp`F$~o$RJp#ICm%>TOgJUDq&{OdUXjSDSTUqj_t~l>c>@%)dsD?7J@#G@CFz6* z|M~{JoOwD7=S^Lg9+CJrSi_Ev65#Md>2P1BZvhYME!kU*Dpl zW#+g^1Y!U01O_v9ncmEFS1lt$DTr^iD@H}{O00fP8N?EZI@1KIYeV!&dM)CSCaw!s z$(uPK&SO%(_n;z%=i}k1F^+vPG?83KC@g7iyiEaVCnF^lqC|EF#@UvNap%u(r%#?d zbnDi)8?6V)p~6fVU&cg#xa*JIqqMNI`fF?a5aP9-i?phBl=P>_*%tnTul<8ad5E5P zM+Nr!9Z*(VY8YkK;Y>kkHe^s>Db~uX&J`iE&S#Z86yF3nd4EKXPNoLHgDG{EO@(ig zUYv0|#r+|M^7=TgZMvR?*6|lT z1fVc7(TyULaP|lmfRxsE09>U-Ozvs!2AHbDs!1Kfg~ZsR*>zwAD(Y~bPA*+P(rs?I zm?yieK`8&}O@$%D@7N?sy$K@@>X-WS8g%;BgoK)KxxCZ4r%w2Fa|dWFrTmEwV>vew zHeJP2Z@myz*pOv8ttVADrmo4*v%#TW!F|t8CW2rkS<{cUA>vZ@lcWIH!6CbHyd`+} z5*O9liuWm&PL0}HE*f&H=zv9GM-ct7at}BYx{SO@oblI@A_}u-zjhR)E^(xBL>wZD zfYD!&R;uS~5?53RC+V-zo!4#9nB-6b7@YrdQ$zz9BeLQyJ&VE7ntSV&6quNqi0S2Z zF~xgV-eE47OGNz3hBQ`;*V=FzyF)8L8H~Ga;%>zMIhh2C@wcV~Ru;LdWK01oTSZC& z;SQC#N-ECiHQrosE+5G%<1ZT(<4k(C1Y- z_aB+HwMT3e11JbyM~p^MO(Y8VUx)bem3%OGMUnQMxt+HdqI;=25=otTd89@rO#LYm z6JP7)9wD1#^r_7_bkGh2nMQOWKlbIt6o~nt@YCNG1<(@u{A+lSJpC}gSE6oJjiL`y zTPLzs`JiN3FgzKS*&GxC7RuDC*b6y~<^Y8ID=I(s?MRXkiILP>ey|;M<~YG$c(Nip zl(#)uYc9pN*P?H?8BRz^p>yh@`l!-;!3qp(dP!mCt>DLX$Pn??xCozoJ|Snf&!MNq z!Y9bW?NxRuC0ox;I@I3bow$6m5|JZ_x62*@J)3l;z4d`IA4DWo7cmoJ6D<(;MB)+Fdz`s2~5h z=Zq5ofq+5T|9fHW@W_8@BuPo_)B6vW!!)>!HcmXc(Azkjmyma{&>JdfkUAcvKbbdg zj`z;aeWkt9dWtC~#5SJqeNpGh{t%Z!C!2)V{dX~o5A59~N#=R-m|3R29j%X0(hm)B zsO3hFMP{ourn~$#674v6_Q@0O_q;DM>yo&tiq6oh4~{FH-v?a%1wzb}z&E|eG$029 z=~737WTPH)5mAG7&g6syDUsP5G2t8rb9e9GPD0TP*hkCp1uPzd9-}D8Pmds-6Q`7J zExhj=G=^RLJCEcVF4|wwmr)EFK_c9-69N3s96C|6ogMG>?QgK}rYroXh72Ae(#mtm zBT^4f75p4D*zV1(%9Kj3RVh!}lJ<|8tywBez=ULt^3T8jfbEM<XZ;k85lRySV780n((_ zM!Gt`Lxk}Jzk9Yn6p*dI>@9ib@5Z!PjdgICjEzn~x6*<2lwN%>Ppr(l-iAl|c{A}x|1Mo6+ z-Z+|k+eOX%b!#MKRZ+=vTm#?KtWj>o!+$QA<(mWjv*fw^QI@<=5(}?Dr>gGJNlpAQ zr1@#R+iWxq<0Ph^Y+#bffv>EZpG0W` z@VSstAln{jIB~1BX?&zrB&=3!yZ57C`-;yBEX2&$uq$6bgZFztMORu;s(-hx($?M9 zP+4w2Q_phrI=4@yQmHugc<&Q0)9zF1v;gv+AoVVq22kU!y6x*kLpB1;*1w2bv#s^b{K>e1t&joX& zWAhqI3B4TSj}&GCvMOurp$qcul7*%U#dG^8M>NYx4a6-jAg6Vli<5iSK}>2Ts11nX zp$Lvfxkrj6d?B*(yFj3n&zfO&mjf-cl;Wq;$c@ zv{v)(o%*Oeh1O3zZ%@}p1QQi11!+Dj0ms-Df2sFH%u!=T#!eKz$hN*#8?$xz&=}&( zrg42Q%(kk@I$&P-Ll5Wi99RYSsU%k?1;@y+=on7sm9Os*@(E87->bm6HEZxhCezKP zjelsURSARWwYLUEhf8-Q!7)`D)}z17pgkoQDMe74=A2Y03{D0iLDtAse7JhIA|b!h zpmzrbM3S};$HTK<^wbOB3Aj&7Bbg@}O&Kq5*X0HxRMlj^t=!}wH(UD!R_fPhhvSdN zD70@KH|F$D0F_EA5opJ>m)I>!yp^15TT?!PMxry+Ge>?a6a*t+hNkDK1-HOSszmjr zcDw9Me)37e5a(6F)3-pDwZ7c9mrZ>N2`cH-A-(fGN#l%O9WVCo&?-w@Ih1FL*L4^ zG-WzXx88P(7jHq0ENh+XLv%dD9SBY`@&LCqB_s=zse;Ee@}`QVE9uw|lMg!cw`b_$ zI_&ig42-sMG6y{a5;YAkzsL89K>OU~u#r<3(v^+LKAfdZ-fV8ayPJk{88~mv^OzA` z!xhj}jLB_BtW>w4xR>AHY;vRasYw^mI2t{Q1MT%9Dv{W6*7kF?__hyD?Z`5}C@((U z+GKM1k}fN{GB}_^gVuyAmSY$4__MpUz92)M@SSHhNKk}Lba<_Vmow+3&*eQ*WDI*- z?LlrlK`0k@>`pHDn=H^3;*JCUlk0Wfl(*;GVbPtTd+tG2Jgm`JY}YAO{)HP~x3PkdTYbA9D^ll}cr@ z@vj)etJvy0)7e^l_xvzLay{EgC}qCf0NX?VU?6e|^!`c93BHA}^lM33^%uRI+RVG7 zNfjIl&p1j%99R7{_SOn>1-hrJ9_tOCE-hgt^U8L!>(Uc6ppn-*D1k{WM}E=VA}#Q+ zmPG#A)Yk?#;BNMOObAlQ4dNazMyZ=8rZpjpLSF*=J(*=#NdC)Ba9(THmlWJHS8Jf) zxuDQ#voa^-cEmouHSsmauP!tGX}%^N(Y0)=v8cZz#n}k40csy_%5#Cs<(GpDzjdM2 z*|(|o(KjlRBQL6N-XqX!dB=-3Wl8A{F13~U18--wD;IaLLm+xu2Q`MBmcbai@DpZo zmcx}%ftf&PNRahDlPej4jq!=+7ifQTyKH}n7RC)XVNtYku|WGW`+EW}ANiZkBGQpe zj5IxleHH&i=%SUHQ=&8rTebX)C!ChxVOl7`LswoYxQYd!r@a`zCknX<=q2*_MIhF|F__Wcm>kQJihJ- z7*e$x61z6up|<0<-=j(RJ8ObF=pKe|myAs4pRDN70k!Y!6$R#YbQP?;L&YY%e~rA- zW}UIFQWoDA`@wbVOO&amVb_p_<1~;iOAdn_j7dyQ8gK=T<7Y?I?OxV(>vV*N!wLD+6?w^&r%pNIEX=NP0 zqqjas4yySLT?U`m5ME&o?-~vc9r@pTX|9fkpBv-VEc`ACiX-}Xk@ z0@^1`0g;f_Pf&{Wg z2KxfX;KRLC`dC_bt}8_3u6SnOD(|!s&1XyA3h2i>ilq!30PC6Bz_T)QFQ+6)wG5i9 zB}&MTt$qIPrYnQaGfz!yZ(9~){~sAcW&J_+Th#iPWj%tmeVmY29G@8)>2QeV^kYiS(Dw2zC)={e@6GZ%amy{S}QDTUx{0a7TGEbX49tq$F_+c zl;%#!7lkYe1$u(l_MRd6C}aWg7hBgMv#i35gvq&~h93oQh~sZYA!@%UvW7+{4BfTH z#MySvrxYoVhTMH9cu`?f#78{-0ByH{(A<@kN#U-8BakGmJ;$O2va} zc#CX9nt^({u-i7AY&{$0r6xA?=&cCEbUzU{{8oO^-`u&THA@K+>5KDeZ4o3U!%zfG;wWZI2aRssAWz7 z--|bKp>=Xo^Nld0+&FVWCjWDW7iL)jT^YmBtmYy>Sc8=0oT5lBn&A)7r^rpJ6;U$W za#R7uZEc4;p0)40TXi%gR=^&NHceE=&5ngziAqoy>+I`1^M3lxn)HFeU=Q91fqk|F zXS+u^?CW!1n_rm7JS&<|l+RCUy!s$0it8-2hkZLljYT-9L&I4o2IfXEGQw!j&;(^f_&Y|MTmL@vy@K(X zd|u1XbZg^iLu_Nv^vg%h8+C>UVaC2PG?1AXyTs+b(nJ{Jn4(DXJEk5K-wO5bfK<%= z=Ns8dlZPQ{X6S)g+s7)C9k#f`+Wn`^>f~{4Y11jM?ee%cA-LjPsFj>Q^Q(alFML;7 z-D#ib5aDcDW@mln-a~z91`*Qzf*xInF9WEb?Jl}}={@S%CS>3r(DUDmofrI|4R3^P zMlSzdwE9>^7W}NaLHX~3R>;JERkD5*x1ziXLBc^48VQ_Homogeneous coordinates
  • Control+Drag to rotate actors.
  • Shift+Alt to unevenly scale actors.
  • Pinch, rotate and drag on iOS with native gestures.
  • +
  • Priority input lists usage.
  • @@ -66,6 +67,8 @@

    Homogeneous coordinates

  • TextActor optimization by caching it as bitmap.
  • Manipulating Actors zorder.
  • +
  • How to set a priority input list. In this sample the blue actor will get input prioritized + to any other rectangles and its cointained children before the blue rectangle itself.
  • @@ -116,7 +119,9 @@

    Homogeneous coordinates

    CAAT.modules.initialization.init( 800, 500, 'experiment-holder', - [], + [ + + ], __coordinates ); }, @@ -126,6 +131,7 @@

    Homogeneous coordinates

    var scene= director.createScene(); + var cc= new CAAT.ActorContainer(). setBounds( 0,0,director.width,director.height ); cc.setGestureEnabled(true); @@ -176,6 +182,8 @@

    Homogeneous coordinates

    parent.setZOrder(actor,Number.MAX_VALUE); }; + scene.enableInputList(2); + var np = 20; var s = 80; for ( var i = 0; i < np; i++) { @@ -189,7 +197,7 @@

    Homogeneous coordinates

    s). setRotation( Math.PI*2*Math.random() ). setScale( sc, sc ). - setFillStyle('#ff3fff'); + setFillStyle( i===0 ? '#00f' : '#ff3fff'); p.setGestureEnabled(true); @@ -284,6 +292,13 @@

    Homogeneous coordinates

    p.mouseMove= mouseMoveHandler; p0.mouseMove= mouseMoveHandler; p1.mouseMove= mouseMoveHandler; + + if (i===0) { + scene.addActorToInputList(p,1); + scene.addActorToInputList(p0,0); + scene.addActorToInputList(p1,0); + } + } cc.__mouseMove= scene.mouseMove; diff --git a/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_math_bezier.js.html b/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_math_bezier.js.html index 01ff5cc7..970c3f1b 100644 --- a/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_math_bezier.js.html +++ b/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_math_bezier.js.html @@ -59,467 +59,467 @@ 52 ctx.lineTo( this.coordlist[3].x, this.coordlist[3].y ); 53 ctx.stroke(); 54 } - 55 - 56 ctx.globalAlpha=0.5; - 57 for( var i=0; i<this.coordlist.length; i++ ) { - 58 ctx.fillStyle='#7f7f00'; - 59 ctx.beginPath(); - 60 ctx.arc( - 61 this.coordlist[i].x, - 62 this.coordlist[i].y, - 63 this.HANDLE_SIZE/2, - 64 0, - 65 2*Math.PI, - 66 false) ; - 67 ctx.fill(); - 68 } - 69 - 70 ctx.restore(); - 71 }, - 72 /** - 73 * Signal the curve has been modified and recalculate curve length. - 74 */ - 75 update : function() { - 76 this.calcLength(); - 77 }, - 78 /** - 79 * This method must be overriden by subclasses. It is called whenever the curve must be solved for some time=t. - 80 * The t parameter must be in the range 0..1 - 81 * @param point {CAAT.Point} to store curve solution for t. - 82 * @param t {number} - 83 * @return {CAAT.Point} the point parameter. - 84 */ - 85 solve: function(point,t) { - 86 }, - 87 /** - 88 * Get an array of points defining the curve contour. - 89 * @param numSamples {number} number of segments to get. - 90 */ - 91 getContour : function(numSamples) { - 92 var contour= [], i; - 93 - 94 for( i=0; i<=numSamples; i++ ) { - 95 var point= new CAAT.Point(); - 96 this.solve( point, i/numSamples ); - 97 contour.push(point); - 98 } - 99 -100 return contour; -101 }, -102 /** -103 * Calculates a curve bounding box. -104 * -105 * @param rectangle {CAAT.Rectangle} a rectangle to hold the bounding box. -106 * @return {CAAT.Rectangle} the rectangle parameter. -107 */ -108 getBoundingBox : function(rectangle) { -109 if ( !rectangle ) { -110 rectangle= new CAAT.Rectangle(); -111 } -112 -113 // thanks yodesoft.com for spotting the first point is out of the BB -114 rectangle.setEmpty(); -115 rectangle.union( this.coordlist[0].x, this.coordlist[0].y ); -116 -117 var pt= new CAAT.Point(); -118 for(var t=this.k;t<=1+this.k;t+=this.k){ -119 this.solve(pt,t); -120 rectangle.union( pt.x, pt.y ); -121 } -122 -123 return rectangle; -124 }, -125 /** -126 * Calculate the curve length by incrementally solving the curve every substep=CAAT.Curve.k. This value defaults -127 * to .05 so at least 20 iterations will be performed. -128 * -129 * @return {number} the approximate curve length. -130 */ -131 calcLength : function() { -132 var x1,x2,y1,y2; -133 x1 = this.coordlist[0].x; -134 y1 = this.coordlist[0].y; -135 var llength=0; -136 var pt= new CAAT.Point(); -137 for(var t=this.k;t<=1+this.k;t+=this.k){ -138 this.solve(pt,t); -139 llength+= Math.sqrt( (pt.x-x1)*(pt.x-x1) + (pt.y-y1)*(pt.y-y1) ); -140 x1=pt.x; -141 y1=pt.y; -142 } -143 -144 this.length= llength; -145 return llength; -146 }, -147 /** -148 * Return the cached curve length. -149 * @return {number} the cached curve length. -150 */ -151 getLength : function() { -152 return this.length; -153 }, -154 /** -155 * Return the first curve control point. -156 * @param point {CAAT.Point} -157 * @return {CAAT.Point} -158 */ -159 endCurvePosition : function(point) { -160 return this.coordlist[ this.coordlist.length-1 ]; -161 }, -162 /** -163 * Return the last curve control point. -164 * @param point {CAAT.Point} -165 * @return {CAAT.Point} -166 */ -167 startCurvePosition : function(point) { -168 return this.coordlist[ 0 ]; -169 }, -170 -171 setPoints : function( points ) { -172 }, -173 -174 setPoint : function( point, index ) { -175 if ( index>=0 && index<this.coordlist.length ) { -176 this.coordlist[index]= point; -177 } -178 }, -179 applyAsPath : function( director ) { -180 } -181 }; -182 })(); -183 -184 -185 (function() { -186 -187 /** -188 * Bezier quadric and cubic curves implementation. -189 * -190 * @constructor -191 * @extends CAAT.Curve -192 */ -193 CAAT.Bezier= function() { -194 CAAT.Bezier.superclass.constructor.call(this); -195 return this; -196 }; -197 -198 CAAT.Bezier.prototype= { -199 -200 cubic: false, -201 -202 applyAsPath : function( director ) { -203 -204 var cc= this.coordlist; -205 -206 if ( this.cubic ) { -207 director.ctx.bezierCurveTo( -208 cc[1].x, -209 cc[1].y, -210 cc[2].x, -211 cc[2].y, -212 cc[3].x, -213 cc[3].y -214 ); -215 } else { -216 director.ctx.quadraticCurveTo( -217 cc[1].x, -218 cc[1].y, -219 cc[2].x, -220 cc[2].y -221 ); -222 } -223 return this; -224 }, -225 isQuadric : function() { -226 return !this.cubic; -227 }, -228 isCubic : function() { -229 return this.cubic; -230 }, -231 /** -232 * Set this curve as a cubic bezier defined by the given four control points. -233 * @param cp0x {number} -234 * @param cp0y {number} -235 * @param cp1x {number} -236 * @param cp1y {number} -237 * @param cp2x {number} -238 * @param cp2y {number} -239 * @param cp3x {number} -240 * @param cp3y {number} -241 */ -242 setCubic : function( cp0x,cp0y, cp1x,cp1y, cp2x,cp2y, cp3x,cp3y ) { -243 -244 this.coordlist= []; -245 -246 this.coordlist.push( new CAAT.Point().set(cp0x, cp0y ) ); -247 this.coordlist.push( new CAAT.Point().set(cp1x, cp1y ) ); -248 this.coordlist.push( new CAAT.Point().set(cp2x, cp2y ) ); -249 this.coordlist.push( new CAAT.Point().set(cp3x, cp3y ) ); -250 -251 this.cubic= true; -252 this.update(); -253 -254 return this; -255 }, -256 /** -257 * Set this curve as a quadric bezier defined by the three control points. -258 * @param cp0x {number} -259 * @param cp0y {number} -260 * @param cp1x {number} -261 * @param cp1y {number} -262 * @param cp2x {number} -263 * @param cp2y {number} -264 */ -265 setQuadric : function(cp0x,cp0y, cp1x,cp1y, cp2x,cp2y ) { -266 -267 this.coordlist= []; -268 -269 this.coordlist.push( new CAAT.Point().set(cp0x, cp0y ) ); -270 this.coordlist.push( new CAAT.Point().set(cp1x, cp1y ) ); -271 this.coordlist.push( new CAAT.Point().set(cp2x, cp2y ) ); -272 -273 this.cubic= false; -274 this.update(); -275 -276 return this; -277 }, -278 setPoints : function( points ) { -279 if ( points.length===3 ) { -280 this.coordlist= points; -281 this.cubic= false; -282 this.update(); -283 } else if (points.length===4 ) { -284 this.coordlist= points; -285 this.cubic= true; -286 this.update(); -287 } else { -288 throw 'points must be an array of 3 or 4 CAAT.Point instances.' -289 } -290 -291 return this; -292 }, -293 /** -294 * Paint this curve. -295 * @param director {CAAT.Director} -296 */ -297 paint : function( director ) { -298 if ( this.cubic ) { -299 this.paintCubic(director); -300 } else { -301 this.paintCuadric( director ); -302 } -303 -304 CAAT.Bezier.superclass.paint.call(this,director); -305 -306 }, -307 /** -308 * Paint this quadric Bezier curve. Each time the curve is drawn it will be solved again from 0 to 1 with -309 * CAAT.Bezier.k increments. -310 * -311 * @param director {CAAT.Director} -312 * @private -313 */ -314 paintCuadric : function( director ) { -315 var x1,y1; -316 x1 = this.coordlist[0].x; -317 y1 = this.coordlist[0].y; -318 -319 var ctx= director.ctx; -320 -321 ctx.save(); -322 ctx.beginPath(); -323 ctx.moveTo(x1,y1); -324 -325 var point= new CAAT.Point(); -326 for(var t=this.k;t<=1+this.k;t+=this.k){ -327 this.solve(point,t); -328 ctx.lineTo(point.x, point.y ); -329 } -330 -331 ctx.stroke(); -332 ctx.restore(); -333 -334 }, -335 /** -336 * Paint this cubic Bezier curve. Each time the curve is drawn it will be solved again from 0 to 1 with -337 * CAAT.Bezier.k increments. -338 * -339 * @param director {CAAT.Director} -340 * @private -341 */ -342 paintCubic : function( director ) { -343 -344 var x1,y1; -345 x1 = this.coordlist[0].x; -346 y1 = this.coordlist[0].y; -347 -348 var ctx= director.ctx; -349 -350 ctx.save(); -351 ctx.beginPath(); -352 ctx.moveTo(x1,y1); -353 -354 var point= new CAAT.Point(); -355 for(var t=this.k;t<=1+this.k;t+=this.k){ -356 this.solve(point,t); -357 ctx.lineTo(point.x, point.y ); -358 } -359 -360 ctx.stroke(); -361 ctx.restore(); -362 }, -363 /** -364 * Solves the curve for any given parameter t. -365 * @param point {CAAT.Point} the point to store the solved value on the curve. -366 * @param t {number} a number in the range 0..1 -367 */ -368 solve : function(point,t) { -369 if ( this.cubic ) { -370 return this.solveCubic(point,t); -371 } else { -372 return this.solveQuadric(point,t); -373 } -374 }, -375 /** -376 * Solves a cubic Bezier. -377 * @param point {CAAT.Point} the point to store the solved value on the curve. -378 * @param t {number} the value to solve the curve for. -379 */ -380 solveCubic : function(point,t) { -381 -382 var t2= t*t; -383 var t3= t*t2; -384 -385 var cl= this.coordlist; -386 var cl0= cl[0]; -387 var cl1= cl[1]; -388 var cl2= cl[2]; -389 var cl3= cl[3]; -390 -391 point.x=( -392 cl0.x + t * (-cl0.x * 3 + t * (3 * cl0.x- -393 cl0.x*t)))+t*(3*cl1.x+t*(-6*cl1.x+ -394 cl1.x*3*t))+t2*(cl2.x*3-cl2.x*3*t)+ -395 cl3.x * t3; -396 -397 point.y=( -398 cl0.y+t*(-cl0.y*3+t*(3*cl0.y- -399 cl0.y*t)))+t*(3*cl1.y+t*(-6*cl1.y+ -400 cl1.y*3*t))+t2*(cl2.y*3-cl2.y*3*t)+ -401 cl3.y * t3; -402 -403 return point; -404 }, -405 /** -406 * Solves a quadric Bezier. -407 * @param point {CAAT.Point} the point to store the solved value on the curve. -408 * @param t {number} the value to solve the curve for. -409 */ -410 solveQuadric : function(point,t) { -411 var cl= this.coordlist; -412 var cl0= cl[0]; -413 var cl1= cl[1]; -414 var cl2= cl[2]; -415 var t1= 1-t; -416 -417 point.x= t1*t1*cl0.x + 2*t1*t*cl1.x + t*t*cl2.x; -418 point.y= t1*t1*cl0.y + 2*t1*t*cl1.y + t*t*cl2.y; -419 -420 return point; -421 } -422 }; -423 -424 extend(CAAT.Bezier, CAAT.Curve, null); -425 -426 })(); -427 -428 (function() { -429 -430 /** -431 * CatmullRom curves solver implementation. -432 * <p> -433 * <strong>Incomplete class, do not use.</strong> -434 * -435 * @constructor -436 * @extends CAAT.Curve -437 */ -438 CAAT.CatmullRom = function() { -439 CAAT.CatmullRom.superclass.constructor.call(this); -440 return this; -441 }; -442 -443 CAAT.CatmullRom.prototype= { -444 -445 /** -446 * Set curve control points. -447 * @param cp0x {number} -448 * @param cp0y {number} -449 * @param cp1x {number} -450 * @param cp1y {number} -451 * @param cp2x {number} -452 * @param cp2y {number} -453 * @param cp3x {number} -454 * @param cp3y {number} -455 */ -456 setCurve : function( cp0x,cp0y, cp1x,cp1y, cp2x,cp2y, cp3x,cp3y ) { -457 -458 this.coordlist= []; -459 -460 this.coordlist.push( new CAAT.Point().set(cp0x, cp0y ) ); -461 this.coordlist.push( new CAAT.Point().set(cp1x, cp1y ) ); -462 this.coordlist.push( new CAAT.Point().set(cp2x, cp2y ) ); -463 this.coordlist.push( new CAAT.Point().set(cp3x, cp3y ) ); -464 -465 this.cubic= true; -466 this.update(); -467 }, -468 /** -469 * Paint the contour by solving again the entire curve. -470 * @param director {CAAT.Director} -471 */ -472 paint: function(director) { -473 -474 var x1,x2,y1,y2; -475 x1 = this.coordlist[0].x; -476 y1 = this.coordlist[0].y; -477 -478 var ctx= director.ctx; + 55 + 56 + 57 ctx.globalAlpha=0.5; + 58 for( var i=0; i<this.coordlist.length; i++ ) { + 59 ctx.fillStyle='#7f7f00'; + 60 var w= CAAT.Curve.prototype.HANDLE_SIZE/2; + 61 ctx.fillRect( this.coordlist[i].x-w, this.coordlist[i].y-w, w*2, w*2 ); + 62 /* + 63 ctx.beginPath(); + 64 ctx.arc( + 65 this.coordlist[i].x, + 66 this.coordlist[i].y, + 67 this.HANDLE_SIZE/2, + 68 0, + 69 2*Math.PI, + 70 false) ; + 71 ctx.fill(); + 72 */ + 73 } + 74 + 75 ctx.restore(); + 76 }, + 77 /** + 78 * Signal the curve has been modified and recalculate curve length. + 79 */ + 80 update : function() { + 81 this.calcLength(); + 82 }, + 83 /** + 84 * This method must be overriden by subclasses. It is called whenever the curve must be solved for some time=t. + 85 * The t parameter must be in the range 0..1 + 86 * @param point {CAAT.Point} to store curve solution for t. + 87 * @param t {number} + 88 * @return {CAAT.Point} the point parameter. + 89 */ + 90 solve: function(point,t) { + 91 }, + 92 /** + 93 * Get an array of points defining the curve contour. + 94 * @param numSamples {number} number of segments to get. + 95 */ + 96 getContour : function(numSamples) { + 97 var contour= [], i; + 98 + 99 for( i=0; i<=numSamples; i++ ) { +100 var point= new CAAT.Point(); +101 this.solve( point, i/numSamples ); +102 contour.push(point); +103 } +104 +105 return contour; +106 }, +107 /** +108 * Calculates a curve bounding box. +109 * +110 * @param rectangle {CAAT.Rectangle} a rectangle to hold the bounding box. +111 * @return {CAAT.Rectangle} the rectangle parameter. +112 */ +113 getBoundingBox : function(rectangle) { +114 if ( !rectangle ) { +115 rectangle= new CAAT.Rectangle(); +116 } +117 +118 // thanks yodesoft.com for spotting the first point is out of the BB +119 rectangle.setEmpty(); +120 rectangle.union( this.coordlist[0].x, this.coordlist[0].y ); +121 +122 var pt= new CAAT.Point(); +123 for(var t=this.k;t<=1+this.k;t+=this.k){ +124 this.solve(pt,t); +125 rectangle.union( pt.x, pt.y ); +126 } +127 +128 return rectangle; +129 }, +130 /** +131 * Calculate the curve length by incrementally solving the curve every substep=CAAT.Curve.k. This value defaults +132 * to .05 so at least 20 iterations will be performed. +133 * +134 * @return {number} the approximate curve length. +135 */ +136 calcLength : function() { +137 var x1,x2,y1,y2; +138 x1 = this.coordlist[0].x; +139 y1 = this.coordlist[0].y; +140 var llength=0; +141 var pt= new CAAT.Point(); +142 for(var t=this.k;t<=1+this.k;t+=this.k){ +143 this.solve(pt,t); +144 llength+= Math.sqrt( (pt.x-x1)*(pt.x-x1) + (pt.y-y1)*(pt.y-y1) ); +145 x1=pt.x; +146 y1=pt.y; +147 } +148 +149 this.length= llength; +150 return llength; +151 }, +152 /** +153 * Return the cached curve length. +154 * @return {number} the cached curve length. +155 */ +156 getLength : function() { +157 return this.length; +158 }, +159 /** +160 * Return the first curve control point. +161 * @param point {CAAT.Point} +162 * @return {CAAT.Point} +163 */ +164 endCurvePosition : function(point) { +165 return this.coordlist[ this.coordlist.length-1 ]; +166 }, +167 /** +168 * Return the last curve control point. +169 * @param point {CAAT.Point} +170 * @return {CAAT.Point} +171 */ +172 startCurvePosition : function(point) { +173 return this.coordlist[ 0 ]; +174 }, +175 +176 setPoints : function( points ) { +177 }, +178 +179 setPoint : function( point, index ) { +180 if ( index>=0 && index<this.coordlist.length ) { +181 this.coordlist[index]= point; +182 } +183 }, +184 applyAsPath : function( director ) { +185 } +186 }; +187 })(); +188 +189 +190 (function() { +191 +192 /** +193 * Bezier quadric and cubic curves implementation. +194 * +195 * @constructor +196 * @extends CAAT.Curve +197 */ +198 CAAT.Bezier= function() { +199 CAAT.Bezier.superclass.constructor.call(this); +200 return this; +201 }; +202 +203 CAAT.Bezier.prototype= { +204 +205 cubic: false, +206 +207 applyAsPath : function( director ) { +208 +209 var cc= this.coordlist; +210 +211 if ( this.cubic ) { +212 director.ctx.bezierCurveTo( +213 cc[1].x, +214 cc[1].y, +215 cc[2].x, +216 cc[2].y, +217 cc[3].x, +218 cc[3].y +219 ); +220 } else { +221 director.ctx.quadraticCurveTo( +222 cc[1].x, +223 cc[1].y, +224 cc[2].x, +225 cc[2].y +226 ); +227 } +228 return this; +229 }, +230 isQuadric : function() { +231 return !this.cubic; +232 }, +233 isCubic : function() { +234 return this.cubic; +235 }, +236 /** +237 * Set this curve as a cubic bezier defined by the given four control points. +238 * @param cp0x {number} +239 * @param cp0y {number} +240 * @param cp1x {number} +241 * @param cp1y {number} +242 * @param cp2x {number} +243 * @param cp2y {number} +244 * @param cp3x {number} +245 * @param cp3y {number} +246 */ +247 setCubic : function( cp0x,cp0y, cp1x,cp1y, cp2x,cp2y, cp3x,cp3y ) { +248 +249 this.coordlist= []; +250 +251 this.coordlist.push( new CAAT.Point().set(cp0x, cp0y ) ); +252 this.coordlist.push( new CAAT.Point().set(cp1x, cp1y ) ); +253 this.coordlist.push( new CAAT.Point().set(cp2x, cp2y ) ); +254 this.coordlist.push( new CAAT.Point().set(cp3x, cp3y ) ); +255 +256 this.cubic= true; +257 this.update(); +258 +259 return this; +260 }, +261 /** +262 * Set this curve as a quadric bezier defined by the three control points. +263 * @param cp0x {number} +264 * @param cp0y {number} +265 * @param cp1x {number} +266 * @param cp1y {number} +267 * @param cp2x {number} +268 * @param cp2y {number} +269 */ +270 setQuadric : function(cp0x,cp0y, cp1x,cp1y, cp2x,cp2y ) { +271 +272 this.coordlist= []; +273 +274 this.coordlist.push( new CAAT.Point().set(cp0x, cp0y ) ); +275 this.coordlist.push( new CAAT.Point().set(cp1x, cp1y ) ); +276 this.coordlist.push( new CAAT.Point().set(cp2x, cp2y ) ); +277 +278 this.cubic= false; +279 this.update(); +280 +281 return this; +282 }, +283 setPoints : function( points ) { +284 if ( points.length===3 ) { +285 this.coordlist= points; +286 this.cubic= false; +287 this.update(); +288 } else if (points.length===4 ) { +289 this.coordlist= points; +290 this.cubic= true; +291 this.update(); +292 } else { +293 throw 'points must be an array of 3 or 4 CAAT.Point instances.' +294 } +295 +296 return this; +297 }, +298 /** +299 * Paint this curve. +300 * @param director {CAAT.Director} +301 */ +302 paint : function( director ) { +303 if ( this.cubic ) { +304 this.paintCubic(director); +305 } else { +306 this.paintCuadric( director ); +307 } +308 +309 CAAT.Bezier.superclass.paint.call(this,director); +310 +311 }, +312 /** +313 * Paint this quadric Bezier curve. Each time the curve is drawn it will be solved again from 0 to 1 with +314 * CAAT.Bezier.k increments. +315 * +316 * @param director {CAAT.Director} +317 * @private +318 */ +319 paintCuadric : function( director ) { +320 var x1,y1; +321 x1 = this.coordlist[0].x; +322 y1 = this.coordlist[0].y; +323 +324 var ctx= director.ctx; +325 +326 ctx.save(); +327 ctx.beginPath(); +328 ctx.moveTo(x1,y1); +329 +330 var point= new CAAT.Point(); +331 for(var t=this.k;t<=1+this.k;t+=this.k){ +332 this.solve(point,t); +333 ctx.lineTo(point.x, point.y ); +334 } +335 +336 ctx.stroke(); +337 ctx.restore(); +338 +339 }, +340 /** +341 * Paint this cubic Bezier curve. Each time the curve is drawn it will be solved again from 0 to 1 with +342 * CAAT.Bezier.k increments. +343 * +344 * @param director {CAAT.Director} +345 * @private +346 */ +347 paintCubic : function( director ) { +348 +349 var x1,y1; +350 x1 = this.coordlist[0].x; +351 y1 = this.coordlist[0].y; +352 +353 var ctx= director.ctx; +354 +355 ctx.save(); +356 ctx.beginPath(); +357 ctx.moveTo(x1,y1); +358 +359 var point= new CAAT.Point(); +360 for(var t=this.k;t<=1+this.k;t+=this.k){ +361 this.solve(point,t); +362 ctx.lineTo(point.x, point.y ); +363 } +364 +365 ctx.stroke(); +366 ctx.restore(); +367 }, +368 /** +369 * Solves the curve for any given parameter t. +370 * @param point {CAAT.Point} the point to store the solved value on the curve. +371 * @param t {number} a number in the range 0..1 +372 */ +373 solve : function(point,t) { +374 if ( this.cubic ) { +375 return this.solveCubic(point,t); +376 } else { +377 return this.solveQuadric(point,t); +378 } +379 }, +380 /** +381 * Solves a cubic Bezier. +382 * @param point {CAAT.Point} the point to store the solved value on the curve. +383 * @param t {number} the value to solve the curve for. +384 */ +385 solveCubic : function(point,t) { +386 +387 var t2= t*t; +388 var t3= t*t2; +389 +390 var cl= this.coordlist; +391 var cl0= cl[0]; +392 var cl1= cl[1]; +393 var cl2= cl[2]; +394 var cl3= cl[3]; +395 +396 point.x=( +397 cl0.x + t * (-cl0.x * 3 + t * (3 * cl0.x- +398 cl0.x*t)))+t*(3*cl1.x+t*(-6*cl1.x+ +399 cl1.x*3*t))+t2*(cl2.x*3-cl2.x*3*t)+ +400 cl3.x * t3; +401 +402 point.y=( +403 cl0.y+t*(-cl0.y*3+t*(3*cl0.y- +404 cl0.y*t)))+t*(3*cl1.y+t*(-6*cl1.y+ +405 cl1.y*3*t))+t2*(cl2.y*3-cl2.y*3*t)+ +406 cl3.y * t3; +407 +408 return point; +409 }, +410 /** +411 * Solves a quadric Bezier. +412 * @param point {CAAT.Point} the point to store the solved value on the curve. +413 * @param t {number} the value to solve the curve for. +414 */ +415 solveQuadric : function(point,t) { +416 var cl= this.coordlist; +417 var cl0= cl[0]; +418 var cl1= cl[1]; +419 var cl2= cl[2]; +420 var t1= 1-t; +421 +422 point.x= t1*t1*cl0.x + 2*t1*t*cl1.x + t*t*cl2.x; +423 point.y= t1*t1*cl0.y + 2*t1*t*cl1.y + t*t*cl2.y; +424 +425 return point; +426 } +427 }; +428 +429 extend(CAAT.Bezier, CAAT.Curve, null); +430 +431 })(); +432 +433 (function() { +434 +435 /** +436 * CatmullRom curves solver implementation. +437 * <p> +438 * This object manages one single catmull rom segment, that is 4 points. +439 * A complete spline should be managed with CAAT.Path.setCatmullRom with a complete list of points. +440 * +441 * @constructor +442 * @extends CAAT.Curve +443 */ +444 CAAT.CatmullRom = function() { +445 CAAT.CatmullRom.superclass.constructor.call(this); +446 return this; +447 }; +448 +449 CAAT.CatmullRom.prototype= { +450 +451 /** +452 * Set curve control points. +453 * @param points Array<CAAT.Point> +454 */ +455 setCurve : function( p0, p1, p2, p3 ) { +456 +457 this.coordlist= []; +458 this.coordlist.push( p0 ); +459 this.coordlist.push( p1 ); +460 this.coordlist.push( p2 ); +461 this.coordlist.push( p3 ); +462 +463 this.update(); +464 +465 return this; +466 }, +467 /** +468 * Paint the contour by solving again the entire curve. +469 * @param director {CAAT.Director} +470 */ +471 paint: function(director) { +472 +473 var x1,y1; +474 +475 // Catmull rom solves from point 1 !!! +476 +477 x1 = this.coordlist[1].x; +478 y1 = this.coordlist[1].y; 479 -480 ctx.save(); -481 ctx.beginPath(); -482 ctx.moveTo(x1,y1); -483 -484 var point= new CAAT.Point(); +480 var ctx= director.ctx; +481 +482 ctx.save(); +483 ctx.beginPath(); +484 ctx.moveTo(x1,y1); 485 -486 for(var t=this.k;t<=1+this.k;t+=this.k){ -487 this.solve(point,t); -488 ctx.lineTo(point.x,point.y); -489 } -490 -491 ctx.stroke(); -492 ctx.restore(); -493 -494 CAAT.CatmullRom.superclass.paint.call(this,director); -495 }, -496 /** -497 * Solves the curve for any given parameter t. -498 * @param point {CAAT.Point} the point to store the solved value on the curve. -499 * @param t {number} a number in the range 0..1 -500 */ -501 solve: function(point,t) { -502 var t2= t*t; -503 var t3= t*t2; -504 -505 var c= this.coordlist; -506 -507 // q(t) = 0.5 *( (2 * P1) + -508 // (-P0 + P2) * t + -509 // (2*P0 - 5*P1 + 4*P2 - P3) * t2 + -510 // (-P0 + 3*P1- 3*P2 + P3) * t3) +486 var point= new CAAT.Point(); +487 +488 for(var t=this.k;t<=1+this.k;t+=this.k){ +489 this.solve(point,t); +490 ctx.lineTo(point.x,point.y); +491 } +492 +493 ctx.stroke(); +494 ctx.restore(); +495 +496 CAAT.CatmullRom.superclass.paint.call(this,director); +497 }, +498 /** +499 * Solves the curve for any given parameter t. +500 * @param point {CAAT.Point} the point to store the solved value on the curve. +501 * @param t {number} a number in the range 0..1 +502 */ +503 solve: function(point,t) { +504 var c= this.coordlist; +505 +506 // Handy from CAKE. Thanks. +507 var af = ((-t+2)*t-1)*t*0.5 +508 var bf = (((3*t-5)*t)*t+2)*0.5 +509 var cf = ((-3*t+4)*t+1)*t*0.5 +510 var df = ((t-1)*t*t)*0.5 511 -512 point.x= 0.5*( (2*c[1].x) + (-c[0].x+c[2].x)*t + (2*c[0].x - 5*c[1].x + 4*c[2].x - c[3].x)*t2 + (-c[0].x + 3*c[1].x - 3*c[2].x + c[3].x)*t3 ); -513 point.y= 0.5*( (2*c[1].y) + (-c[0].y+c[2].y)*t + (2*c[0].y - 5*c[1].y + 4*c[2].y - c[3].y)*t2 + (-c[0].y + 3*c[1].y - 3*c[2].y + c[3].y)*t3 ); -514 -515 return point; +512 point.x= c[0].x * af + c[1].x * bf + c[2].x * cf + c[3].x * df; +513 point.y= c[0].y * af + c[1].y * bf + c[2].y * cf + c[3].y * df; +514 +515 return point; 516 517 } 518 }; diff --git a/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_model_actor.js.html b/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_model_actor.js.html index bd5d24ec..eccfcc66 100644 --- a/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_model_actor.js.html +++ b/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_model_actor.js.html @@ -935,7 +935,7 @@ 928 * @return null if the point is not inside the Actor. The Actor otherwise. 929 */ 930 findActorAtPosition : function(point) { -931 if ( !this.mouseEnabled || !this.isInAnimationFrame(this.time) ) { +931 if ( !this.visible || !this.mouseEnabled || !this.isInAnimationFrame(this.time) ) { 932 return null; 933 } 934 @@ -1883,1243 +1883,1247 @@ 1876 cl[i].drawScreenBoundingBox(director,time); 1877 } 1878 CAAT.ActorContainer.superclass.drawScreenBoundingBox.call(this,director,time); -1879 -1880 }, -1881 /** -1882 * Removes all children from this ActorContainer. -1883 * -1884 * @return this -1885 */ -1886 emptyChildren : function() { -1887 this.childrenList= []; -1888 -1889 return this; -1890 }, -1891 /** -1892 * Private -1893 * Paints this container and every contained children. -1894 * -1895 * @param director the CAAT.Director object instance that contains the Scene the Actor is in. -1896 * @param time an integer indicating the Scene time when the bounding box is to be drawn. -1897 */ -1898 paintActor : function(director, time ) { -1899 -1900 if (!this.visible) { -1901 return true; -1902 } -1903 -1904 var ctx= director.ctx; -1905 -1906 ctx.save(); -1907 -1908 CAAT.ActorContainer.superclass.paintActor.call(this,director,time); -1909 if ( !this.isGlobalAlpha ) { -1910 this.frameAlpha= this.parent ? this.parent.frameAlpha : 1; -1911 } -1912 -1913 for( var actor= this.activeChildren; actor; actor=actor.__next ) { -1914 if ( actor.visible ) { -1915 actor.paintActor(director,time); -1916 } -1917 } -1918 -1919 ctx.restore(); -1920 -1921 return true; -1922 }, -1923 __paintActor : function(director, time ) { -1924 if (!this.visible) { -1925 return true; -1926 } -1927 -1928 var ctx= director.ctx; -1929 -1930 this.frameAlpha= this.parent ? this.parent.frameAlpha*this.alpha : 1; -1931 var m= this.worldModelViewMatrix.matrix; -1932 ctx.setTransform( m[0], m[3], m[1], m[4], m[2], m[5], this.frameAlpha ); -1933 this.paint(director, time); -1934 -1935 if ( !this.isGlobalAlpha ) { -1936 this.frameAlpha= this.parent ? this.parent.frameAlpha : 1; -1937 } -1938 -1939 for( var actor= this.activeChildren; actor; actor=actor.__next ) { -1940 actor.paintActor(director,time); -1941 } -1942 return true; -1943 }, -1944 paintActorGL : function(director,time) { -1945 -1946 var i, c; -1947 if (!this.visible) { -1948 return true; -1949 } -1950 -1951 CAAT.ActorContainer.superclass.paintActorGL.call(this,director,time); -1952 -1953 if ( !this.isGlobalAlpha ) { -1954 this.frameAlpha= this.parent.frameAlpha; -1955 } -1956 -1957 for( c= this.activeChildren; c; c=c.__next ) { -1958 c.paintActorGL(director,time); -1959 } -1960 -1961 }, -1962 /** -1963 * Private. -1964 * Performs the animate method for this ActorContainer and every contained Actor. -1965 * -1966 * @param director the CAAT.Director object instance that contains the Scene the Actor is in. -1967 * @param time an integer indicating the Scene time when the bounding box is to be drawn. -1968 * -1969 * @return {boolean} is this actor in active children list ?? -1970 */ -1971 animate : function(director,time) { -1972 -1973 this.activeChildren= null; -1974 var last= null; -1975 -1976 if (false===CAAT.ActorContainer.superclass.animate.call(this,director,time)) { -1977 return false; -1978 } -1979 -1980 var i,l; -1981 -1982 /** -1983 * Incluir los actores pendientes. -1984 * El momento es ahora, antes de procesar ninguno del contenedor. -1985 */ -1986 var pcl= this.pendingChildrenList; -1987 for( i=0; i<pcl.length; i++ ) { -1988 var child= pcl[i]; -1989 this.addChild(child); -1990 } -1991 -1992 this.pendingChildrenList= []; -1993 var markDelete= []; -1994 -1995 var cl= this.childrenList; -1996 this.size_active= 1; -1997 this.size_total= 1; -1998 for( i=0; i<cl.length; i++ ) { -1999 var actor= cl[i]; -2000 actor.time= time; -2001 this.size_total+= actor.size_total; -2002 if ( actor.animate(director, time) ) { -2003 if ( !this.activeChildren ) { -2004 this.activeChildren= actor; -2005 actor.__next= null; -2006 last= actor; -2007 } else { -2008 actor.__next= null; -2009 last.__next= actor; -2010 last= actor; -2011 } -2012 -2013 this.size_active+= actor.size_active; -2014 -2015 } else { -2016 if ( actor.expired && actor.discardable ) { -2017 markDelete.push(actor); -2018 } -2019 } -2020 } -2021 -2022 for( i=0, l=markDelete.length; i<l; i++ ) { -2023 var md= markDelete[i]; -2024 md.destroy(time); -2025 if ( director.dirtyRectsEnabled ) { -2026 director.addDirtyRect( md.AABB ); -2027 } -2028 } -2029 -2030 return true; -2031 }, -2032 /** -2033 * Removes Actors from this ActorContainer which are expired and flagged as Discardable. -2034 * -2035 * @param director the CAAT.Director object instance that contains the Scene the Actor is in. -2036 * @param time an integer indicating the Scene time when the bounding box is to be drawn. -2037 * -2038 * @deprecated -2039 */ -2040 endAnimate : function(director,time) { -2041 }, -2042 /** -2043 * Adds an Actor to this Container. -2044 * The Actor will be added ON METHOD CALL, despite the rendering pipeline stage being executed at -2045 * the time of method call. -2046 * -2047 * This method is only used by CAAT.Director's transitionScene. -2048 * -2049 * @param child a CAAT.Actor instance. -2050 * @return this. -2051 */ -2052 addChildImmediately : function(child) { -2053 return this.addChild(child); -2054 }, -2055 /** -2056 * Adds an Actor to this ActorContainer. -2057 * The Actor will be added to the container AFTER frame animation, and not on method call time. -2058 * Except the Director and in orther to avoid visual artifacts, the developer SHOULD NOT call this -2059 * method directly. -2060 * -2061 * If the container has addingHint as CAAT.ActorContainer.AddHint.CONFORM, new continer size will be -2062 * calculated by summing up the union of every client actor bounding box. -2063 * This method will not take into acount actor's affine transformations, so the bounding box will be -2064 * AABB. -2065 * -2066 * @param child a CAAT.Actor object instance. -2067 * @return this -2068 */ -2069 addChild : function(child) { -2070 -2071 if ( child.parent!=null ) { -2072 throw('adding to a container an element with parent.'); -2073 } -2074 -2075 child.parent= this; -2076 this.childrenList.push(child); -2077 child.dirty= true; -2078 -2079 /** -2080 * if Conforming size, recalc new bountainer size. -2081 */ -2082 if ( this.addHint===CAAT.ActorContainer.AddHint.CONFORM ) { -2083 this.recalcSize(); -2084 } -2085 -2086 return this; -2087 }, -2088 -2089 /** -2090 * Recalc this container size by computin the union of every children bounding box. -2091 */ -2092 recalcSize : function() { -2093 var bb= this.boundingBox; -2094 bb.setEmpty(); -2095 var cl= this.childrenList; -2096 var ac; -2097 for( var i=0; i<cl.length; i++ ) { -2098 ac= cl[i]; -2099 this.runion.setBounds( -2100 ac.x<0 ? 0 : ac.x, -2101 ac.y<0 ? 0 : ac.y, -2102 ac.width, -2103 ac.height ); -2104 bb.unionRectangle( this.runion ); -2105 } -2106 this.setSize( bb.x1, bb.y1 ); -2107 -2108 return this; -2109 }, -2110 -2111 /** -2112 * Add a child element and make it active in the next frame. -2113 * @param child {CAAT.Actor} -2114 */ -2115 addChildDelayed : function(child) { -2116 this.pendingChildrenList.push(child); -2117 return this; -2118 }, -2119 /** -2120 * Adds an Actor to this ActorContainer. -2121 * -2122 * @param child a CAAT.Actor object instance. -2123 * -2124 * @return this -2125 */ -2126 addChildAt : function(child, index) { -2127 -2128 if( index <= 0 ) { -2129 child.parent= this; -2130 child.dirty= true; -2131 //this.childrenList.unshift(child); // unshift unsupported on IE -2132 this.childrenList.splice( 0, 0, child ); -2133 return this; -2134 } else { -2135 if ( index>=this.childrenList.length ) { -2136 index= this.childrenList.length; -2137 } -2138 } -2139 -2140 child.parent= this; -2141 child.dirty= true; -2142 this.childrenList.splice(index, 0, child); -2143 -2144 return this; -2145 }, -2146 /** -2147 * Find the first actor with the supplied ID. -2148 * This method is not recommended to be used since executes a linear search. -2149 * @param id -2150 */ -2151 findActorById : function(id) { -2152 var cl= this.childrenList; -2153 for( var i=0, l=cl.length; i<l; i++ ) { -2154 if ( cl[i].id===id ) { -2155 return cl[i]; -2156 } -2157 } -2158 -2159 return null; -2160 }, -2161 /** -2162 * Private -2163 * Gets a contained Actor z-index on this ActorContainer. -2164 * -2165 * @param child a CAAT.Actor object instance. -2166 * -2167 * @return an integer indicating the Actor's z-order. -2168 */ -2169 findChild : function(child) { -2170 var cl= this.childrenList; -2171 var i=0; -2172 var len = cl.length; -2173 -2174 for( i=0; i<len; i++ ) { -2175 if ( cl[i]===child ) { -2176 return i; -2177 } -2178 } -2179 return -1; -2180 }, -2181 /** -2182 * Removed an Actor form this ActorContainer. -2183 * If the Actor is not contained into this Container, nothing happends. -2184 * -2185 * @param child a CAAT.Actor object instance. -2186 * -2187 * @return this -2188 */ -2189 removeChild : function(child) { -2190 var pos= this.findChild(child); -2191 var cl= this.childrenList; -2192 if ( -1!==pos ) { -2193 cl[pos].setParent(null); -2194 cl.splice(pos,1); -2195 } -2196 -2197 return this; -2198 }, -2199 /** -2200 * @private -2201 * -2202 * Gets the Actor inside this ActorContainer at a given Screen coordinate. -2203 * -2204 * @param point an object of the form { x: float, y: float } +1879 }, +1880 /** +1881 * Removes all children from this ActorContainer. +1882 * +1883 * @return this +1884 */ +1885 emptyChildren : function() { +1886 this.childrenList= []; +1887 +1888 return this; +1889 }, +1890 /** +1891 * Private +1892 * Paints this container and every contained children. +1893 * +1894 * @param director the CAAT.Director object instance that contains the Scene the Actor is in. +1895 * @param time an integer indicating the Scene time when the bounding box is to be drawn. +1896 */ +1897 paintActor : function(director, time ) { +1898 +1899 if (!this.visible) { +1900 return true; +1901 } +1902 +1903 var ctx= director.ctx; +1904 +1905 ctx.save(); +1906 +1907 CAAT.ActorContainer.superclass.paintActor.call(this,director,time); +1908 if ( !this.isGlobalAlpha ) { +1909 this.frameAlpha= this.parent ? this.parent.frameAlpha : 1; +1910 } +1911 +1912 for( var actor= this.activeChildren; actor; actor=actor.__next ) { +1913 if ( actor.visible ) { +1914 actor.paintActor(director,time); +1915 } +1916 } +1917 +1918 ctx.restore(); +1919 +1920 return true; +1921 }, +1922 __paintActor : function(director, time ) { +1923 if (!this.visible) { +1924 return true; +1925 } +1926 +1927 var ctx= director.ctx; +1928 +1929 this.frameAlpha= this.parent ? this.parent.frameAlpha*this.alpha : 1; +1930 var m= this.worldModelViewMatrix.matrix; +1931 ctx.setTransform( m[0], m[3], m[1], m[4], m[2], m[5], this.frameAlpha ); +1932 this.paint(director, time); +1933 +1934 if ( !this.isGlobalAlpha ) { +1935 this.frameAlpha= this.parent ? this.parent.frameAlpha : 1; +1936 } +1937 +1938 for( var actor= this.activeChildren; actor; actor=actor.__next ) { +1939 actor.paintActor(director,time); +1940 } +1941 return true; +1942 }, +1943 paintActorGL : function(director,time) { +1944 +1945 var i, c; +1946 if (!this.visible) { +1947 return true; +1948 } +1949 +1950 CAAT.ActorContainer.superclass.paintActorGL.call(this,director,time); +1951 +1952 if ( !this.isGlobalAlpha ) { +1953 this.frameAlpha= this.parent.frameAlpha; +1954 } +1955 +1956 for( c= this.activeChildren; c; c=c.__next ) { +1957 c.paintActorGL(director,time); +1958 } +1959 +1960 }, +1961 /** +1962 * Private. +1963 * Performs the animate method for this ActorContainer and every contained Actor. +1964 * +1965 * @param director the CAAT.Director object instance that contains the Scene the Actor is in. +1966 * @param time an integer indicating the Scene time when the bounding box is to be drawn. +1967 * +1968 * @return {boolean} is this actor in active children list ?? +1969 */ +1970 animate : function(director,time) { +1971 +1972 this.activeChildren= null; +1973 var last= null; +1974 +1975 if (false===CAAT.ActorContainer.superclass.animate.call(this,director,time)) { +1976 return false; +1977 } +1978 +1979 var i,l; +1980 +1981 /** +1982 * Incluir los actores pendientes. +1983 * El momento es ahora, antes de procesar ninguno del contenedor. +1984 */ +1985 var pcl= this.pendingChildrenList; +1986 for( i=0; i<pcl.length; i++ ) { +1987 var child= pcl[i]; +1988 this.addChild(child); +1989 } +1990 +1991 this.pendingChildrenList= []; +1992 var markDelete= []; +1993 +1994 var cl= this.childrenList; +1995 this.size_active= 1; +1996 this.size_total= 1; +1997 for( i=0; i<cl.length; i++ ) { +1998 var actor= cl[i]; +1999 actor.time= time; +2000 this.size_total+= actor.size_total; +2001 if ( actor.animate(director, time) ) { +2002 if ( !this.activeChildren ) { +2003 this.activeChildren= actor; +2004 actor.__next= null; +2005 last= actor; +2006 } else { +2007 actor.__next= null; +2008 last.__next= actor; +2009 last= actor; +2010 } +2011 +2012 this.size_active+= actor.size_active; +2013 +2014 } else { +2015 if ( actor.expired && actor.discardable ) { +2016 markDelete.push(actor); +2017 } +2018 } +2019 } +2020 +2021 for( i=0, l=markDelete.length; i<l; i++ ) { +2022 var md= markDelete[i]; +2023 md.destroy(time); +2024 if ( director.dirtyRectsEnabled ) { +2025 director.addDirtyRect( md.AABB ); +2026 } +2027 } +2028 +2029 return true; +2030 }, +2031 /** +2032 * Removes Actors from this ActorContainer which are expired and flagged as Discardable. +2033 * +2034 * @param director the CAAT.Director object instance that contains the Scene the Actor is in. +2035 * @param time an integer indicating the Scene time when the bounding box is to be drawn. +2036 * +2037 * @deprecated +2038 */ +2039 endAnimate : function(director,time) { +2040 }, +2041 /** +2042 * Adds an Actor to this Container. +2043 * The Actor will be added ON METHOD CALL, despite the rendering pipeline stage being executed at +2044 * the time of method call. +2045 * +2046 * This method is only used by CAAT.Director's transitionScene. +2047 * +2048 * @param child a CAAT.Actor instance. +2049 * @return this. +2050 */ +2051 addChildImmediately : function(child) { +2052 return this.addChild(child); +2053 }, +2054 /** +2055 * Adds an Actor to this ActorContainer. +2056 * The Actor will be added to the container AFTER frame animation, and not on method call time. +2057 * Except the Director and in orther to avoid visual artifacts, the developer SHOULD NOT call this +2058 * method directly. +2059 * +2060 * If the container has addingHint as CAAT.ActorContainer.AddHint.CONFORM, new continer size will be +2061 * calculated by summing up the union of every client actor bounding box. +2062 * This method will not take into acount actor's affine transformations, so the bounding box will be +2063 * AABB. +2064 * +2065 * @param child a CAAT.Actor object instance. +2066 * @return this +2067 */ +2068 addChild : function(child) { +2069 +2070 if ( child.parent!=null ) { +2071 throw('adding to a container an element with parent.'); +2072 } +2073 +2074 child.parent= this; +2075 this.childrenList.push(child); +2076 child.dirty= true; +2077 +2078 /** +2079 * if Conforming size, recalc new bountainer size. +2080 */ +2081 if ( this.addHint===CAAT.ActorContainer.AddHint.CONFORM ) { +2082 this.recalcSize(); +2083 } +2084 +2085 return this; +2086 }, +2087 +2088 /** +2089 * Recalc this container size by computin the union of every children bounding box. +2090 */ +2091 recalcSize : function() { +2092 var bb= this.boundingBox; +2093 bb.setEmpty(); +2094 var cl= this.childrenList; +2095 var ac; +2096 for( var i=0; i<cl.length; i++ ) { +2097 ac= cl[i]; +2098 this.runion.setBounds( +2099 ac.x<0 ? 0 : ac.x, +2100 ac.y<0 ? 0 : ac.y, +2101 ac.width, +2102 ac.height ); +2103 bb.unionRectangle( this.runion ); +2104 } +2105 this.setSize( bb.x1, bb.y1 ); +2106 +2107 return this; +2108 }, +2109 +2110 /** +2111 * Add a child element and make it active in the next frame. +2112 * @param child {CAAT.Actor} +2113 */ +2114 addChildDelayed : function(child) { +2115 this.pendingChildrenList.push(child); +2116 return this; +2117 }, +2118 /** +2119 * Adds an Actor to this ActorContainer. +2120 * +2121 * @param child a CAAT.Actor object instance. +2122 * +2123 * @return this +2124 */ +2125 addChildAt : function(child, index) { +2126 +2127 if( index <= 0 ) { +2128 child.parent= this; +2129 child.dirty= true; +2130 //this.childrenList.unshift(child); // unshift unsupported on IE +2131 this.childrenList.splice( 0, 0, child ); +2132 return this; +2133 } else { +2134 if ( index>=this.childrenList.length ) { +2135 index= this.childrenList.length; +2136 } +2137 } +2138 +2139 child.parent= this; +2140 child.dirty= true; +2141 this.childrenList.splice(index, 0, child); +2142 +2143 return this; +2144 }, +2145 /** +2146 * Find the first actor with the supplied ID. +2147 * This method is not recommended to be used since executes a linear search. +2148 * @param id +2149 */ +2150 findActorById : function(id) { +2151 var cl= this.childrenList; +2152 for( var i=0, l=cl.length; i<l; i++ ) { +2153 if ( cl[i].id===id ) { +2154 return cl[i]; +2155 } +2156 } +2157 +2158 return null; +2159 }, +2160 /** +2161 * Private +2162 * Gets a contained Actor z-index on this ActorContainer. +2163 * +2164 * @param child a CAAT.Actor object instance. +2165 * +2166 * @return an integer indicating the Actor's z-order. +2167 */ +2168 findChild : function(child) { +2169 var cl= this.childrenList; +2170 var i=0; +2171 var len = cl.length; +2172 +2173 for( i=0; i<len; i++ ) { +2174 if ( cl[i]===child ) { +2175 return i; +2176 } +2177 } +2178 return -1; +2179 }, +2180 /** +2181 * Removed an Actor form this ActorContainer. +2182 * If the Actor is not contained into this Container, nothing happends. +2183 * +2184 * @param child a CAAT.Actor object instance. +2185 * +2186 * @return this +2187 */ +2188 removeChild : function(child) { +2189 var pos= this.findChild(child); +2190 var cl= this.childrenList; +2191 if ( -1!==pos ) { +2192 cl[pos].setParent(null); +2193 cl.splice(pos,1); +2194 } +2195 +2196 return this; +2197 }, +2198 removeFirstChild : function() { +2199 var first= this.childrenList.shift(); +2200 first.parent= null; +2201 return first; +2202 }, +2203 /** +2204 * @private 2205 * -2206 * @return the Actor contained inside this ActorContainer if found, or the ActorContainer itself. -2207 */ -2208 findActorAtPosition : function(point) { -2209 -2210 if( null===CAAT.ActorContainer.superclass.findActorAtPosition.call(this,point) ) { -2211 return null; -2212 } +2206 * Gets the Actor inside this ActorContainer at a given Screen coordinate. +2207 * +2208 * @param point an object of the form { x: float, y: float } +2209 * +2210 * @return the Actor contained inside this ActorContainer if found, or the ActorContainer itself. +2211 */ +2212 findActorAtPosition : function(point) { 2213 -2214 // z-order -2215 var cl= this.childrenList; -2216 for( var i=cl.length-1; i>=0; i-- ) { -2217 var child= this.childrenList[i]; -2218 -2219 var np= new CAAT.Point( point.x, point.y, 0 ); -2220 var contained= child.findActorAtPosition( np ); -2221 if ( null!==contained ) { -2222 return contained; -2223 } -2224 } -2225 -2226 return this; -2227 }, -2228 /** -2229 * Destroys this ActorContainer. -2230 * The process falls down recursively for each contained Actor into this ActorContainer. -2231 * -2232 * @return this -2233 */ -2234 destroy : function() { -2235 var cl= this.childrenList; -2236 for( var i=cl.length-1; i>=0; i-- ) { -2237 cl[i].destroy(); -2238 } -2239 CAAT.ActorContainer.superclass.destroy.call(this); -2240 -2241 return this; -2242 }, -2243 /** -2244 * Get number of Actors into this container. -2245 * @return integer indicating the number of children. -2246 */ -2247 getNumChildren : function() { -2248 return this.childrenList.length; -2249 }, -2250 getNumActiveChildren : function() { -2251 return this.activeChildren.length; -2252 }, -2253 /** -2254 * Returns the Actor at the iPosition(th) position. -2255 * @param iPosition an integer indicating the position array. -2256 * @return the CAAT.Actor object at position. -2257 */ -2258 getChildAt : function( iPosition ) { -2259 return this.childrenList[ iPosition ]; -2260 }, -2261 /** -2262 * Changes an actor's ZOrder. -2263 * @param actor the actor to change ZOrder for -2264 * @param index an integer indicating the new ZOrder. a value greater than children list size means to be the -2265 * last ZOrder Actor. -2266 */ -2267 setZOrder : function( actor, index ) { -2268 var actorPos= this.findChild(actor); -2269 // the actor is present -2270 if ( -1!==actorPos ) { -2271 var cl= this.childrenList; -2272 // trivial reject. -2273 if ( index===actorPos ) { -2274 return; -2275 } -2276 -2277 if ( index>=cl.length ) { -2278 cl.splice(actorPos,1); -2279 cl.push(actor); -2280 } else { -2281 var nActor= cl.splice(actorPos,1); -2282 if ( index<0 ) { -2283 index=0; -2284 } else if ( index>cl.length ) { -2285 index= cl.length; -2286 } -2287 -2288 //cl.splice( index, 1, nActor ); -2289 cl.splice( index, 0, nActor[0] ); -2290 } -2291 } -2292 } -2293 }; -2294 -2295 if ( CAAT.NO_PERF ) { -2296 CAAT.ActorContainer.prototype.paintActor= CAAT.ActorContainer.prototype.__paintActor; -2297 } -2298 -2299 extend( CAAT.ActorContainer, CAAT.Actor, null); -2300 -2301 })(); -2302 -2303 -2304 (function() { -2305 -2306 /** -2307 * TextActor draws text on screen. The text can be drawn directly on screen or make if follow a -2308 * path defined by an instance of <code>CAAT.Path</code>. -2309 * -2310 * @constructor -2311 * @extends CAAT.ActorContainer -2312 * -2313 */ -2314 CAAT.TextActor = function() { -2315 CAAT.TextActor.superclass.constructor.call(this); -2316 this.font= "10px sans-serif"; -2317 this.textAlign= "left"; -2318 this.textBaseline= "top"; -2319 this.outlineColor= "black"; -2320 this.clip= false; -2321 -2322 return this; -2323 }; -2324 -2325 CAAT.TextActor.TRAVERSE_PATH_FORWARD= 1; -2326 CAAT.TextActor.TRAVERSE_PATH_BACKWARD= -1; -2327 -2328 CAAT.TextActor.prototype= { -2329 font: null, // a valid canvas rendering context font description. Default font -2330 // will be "10px sans-serif". -2331 textAlign: null, // a valid canvas rendering context textAlign string. Any of: -2332 // start, end, left, right, center. -2333 // defaults to "left". -2334 textBaseline: null, // a valid canvas rendering context textBaseLine string. Any of: -2335 // top, hanging, middle, alphabetic, ideographic, bottom. -2336 // defaults to "top". -2337 fill: true, // a boolean indicating whether the text should be filled. -2338 textFillStyle : '#eee', // text fill color -2339 text: null, // a string with the text to draw. -2340 textWidth: 0, // an integer indicating text width in pixels. -2341 textHeight: 0, // an integer indicating text height in pixels. -2342 outline: false, // a boolean indicating whether the text should be outlined. -2343 // not all browsers support it. -2344 outlineColor: null, // a valid color description string. -2345 -2346 path: null, // a CAAT.Path which will be traversed by the text. [Optional] -2347 pathInterpolator: null, // a CAAT.Interpolator to apply to the path traversing. -2348 pathDuration: 10000, // an integer indicating the time to be taken to traverse the path. ms. -2349 sign: 1, // traverse the path forward or backwards. -2350 -2351 /** -2352 * Set the text to be filled. The default Filling style will be set by calling setFillStyle method. -2353 * Default value is true. -2354 * @param fill {boolean} a boolean indicating whether the text will be filled. -2355 * @return this; -2356 */ -2357 setFill : function( fill ) { -2358 this.fill= fill; -2359 return this; -2360 }, -2361 setTextFillStyle : function( style ) { -2362 this.textFillStyle= style; +2214 if( null===CAAT.ActorContainer.superclass.findActorAtPosition.call(this,point) ) { +2215 return null; +2216 } +2217 +2218 // z-order +2219 var cl= this.childrenList; +2220 for( var i=cl.length-1; i>=0; i-- ) { +2221 var child= this.childrenList[i]; +2222 +2223 var np= new CAAT.Point( point.x, point.y, 0 ); +2224 var contained= child.findActorAtPosition( np ); +2225 if ( null!==contained ) { +2226 return contained; +2227 } +2228 } +2229 +2230 return this; +2231 }, +2232 /** +2233 * Destroys this ActorContainer. +2234 * The process falls down recursively for each contained Actor into this ActorContainer. +2235 * +2236 * @return this +2237 */ +2238 destroy : function() { +2239 var cl= this.childrenList; +2240 for( var i=cl.length-1; i>=0; i-- ) { +2241 cl[i].destroy(); +2242 } +2243 CAAT.ActorContainer.superclass.destroy.call(this); +2244 +2245 return this; +2246 }, +2247 /** +2248 * Get number of Actors into this container. +2249 * @return integer indicating the number of children. +2250 */ +2251 getNumChildren : function() { +2252 return this.childrenList.length; +2253 }, +2254 getNumActiveChildren : function() { +2255 return this.activeChildren.length; +2256 }, +2257 /** +2258 * Returns the Actor at the iPosition(th) position. +2259 * @param iPosition an integer indicating the position array. +2260 * @return the CAAT.Actor object at position. +2261 */ +2262 getChildAt : function( iPosition ) { +2263 return this.childrenList[ iPosition ]; +2264 }, +2265 /** +2266 * Changes an actor's ZOrder. +2267 * @param actor the actor to change ZOrder for +2268 * @param index an integer indicating the new ZOrder. a value greater than children list size means to be the +2269 * last ZOrder Actor. +2270 */ +2271 setZOrder : function( actor, index ) { +2272 var actorPos= this.findChild(actor); +2273 // the actor is present +2274 if ( -1!==actorPos ) { +2275 var cl= this.childrenList; +2276 // trivial reject. +2277 if ( index===actorPos ) { +2278 return; +2279 } +2280 +2281 if ( index>=cl.length ) { +2282 cl.splice(actorPos,1); +2283 cl.push(actor); +2284 } else { +2285 var nActor= cl.splice(actorPos,1); +2286 if ( index<0 ) { +2287 index=0; +2288 } else if ( index>cl.length ) { +2289 index= cl.length; +2290 } +2291 +2292 //cl.splice( index, 1, nActor ); +2293 cl.splice( index, 0, nActor[0] ); +2294 } +2295 } +2296 } +2297 }; +2298 +2299 if ( CAAT.NO_PERF ) { +2300 CAAT.ActorContainer.prototype.paintActor= CAAT.ActorContainer.prototype.__paintActor; +2301 } +2302 +2303 extend( CAAT.ActorContainer, CAAT.Actor, null); +2304 +2305 })(); +2306 +2307 +2308 (function() { +2309 +2310 /** +2311 * TextActor draws text on screen. The text can be drawn directly on screen or make if follow a +2312 * path defined by an instance of <code>CAAT.Path</code>. +2313 * +2314 * @constructor +2315 * @extends CAAT.ActorContainer +2316 * +2317 */ +2318 CAAT.TextActor = function() { +2319 CAAT.TextActor.superclass.constructor.call(this); +2320 this.font= "10px sans-serif"; +2321 this.textAlign= "left"; +2322 this.textBaseline= "top"; +2323 this.outlineColor= "black"; +2324 this.clip= false; +2325 +2326 return this; +2327 }; +2328 +2329 CAAT.TextActor.TRAVERSE_PATH_FORWARD= 1; +2330 CAAT.TextActor.TRAVERSE_PATH_BACKWARD= -1; +2331 +2332 CAAT.TextActor.prototype= { +2333 font: null, // a valid canvas rendering context font description. Default font +2334 // will be "10px sans-serif". +2335 textAlign: null, // a valid canvas rendering context textAlign string. Any of: +2336 // start, end, left, right, center. +2337 // defaults to "left". +2338 textBaseline: null, // a valid canvas rendering context textBaseLine string. Any of: +2339 // top, hanging, middle, alphabetic, ideographic, bottom. +2340 // defaults to "top". +2341 fill: true, // a boolean indicating whether the text should be filled. +2342 textFillStyle : '#eee', // text fill color +2343 text: null, // a string with the text to draw. +2344 textWidth: 0, // an integer indicating text width in pixels. +2345 textHeight: 0, // an integer indicating text height in pixels. +2346 outline: false, // a boolean indicating whether the text should be outlined. +2347 // not all browsers support it. +2348 outlineColor: null, // a valid color description string. +2349 +2350 path: null, // a CAAT.Path which will be traversed by the text. [Optional] +2351 pathInterpolator: null, // a CAAT.Interpolator to apply to the path traversing. +2352 pathDuration: 10000, // an integer indicating the time to be taken to traverse the path. ms. +2353 sign: 1, // traverse the path forward or backwards. +2354 +2355 /** +2356 * Set the text to be filled. The default Filling style will be set by calling setFillStyle method. +2357 * Default value is true. +2358 * @param fill {boolean} a boolean indicating whether the text will be filled. +2359 * @return this; +2360 */ +2361 setFill : function( fill ) { +2362 this.fill= fill; 2363 return this; 2364 }, -2365 /** -2366 * Sets whether the text will be outlined. -2367 * @param outline {boolean} a boolean indicating whether the text will be outlined. -2368 * @return this; -2369 */ -2370 setOutline : function( outline ) { -2371 this.outline= outline; -2372 return this; -2373 }, -2374 setPathTraverseDirection : function(direction) { -2375 this.sign= direction; +2365 setTextFillStyle : function( style ) { +2366 this.textFillStyle= style; +2367 return this; +2368 }, +2369 /** +2370 * Sets whether the text will be outlined. +2371 * @param outline {boolean} a boolean indicating whether the text will be outlined. +2372 * @return this; +2373 */ +2374 setOutline : function( outline ) { +2375 this.outline= outline; 2376 return this; 2377 }, -2378 /** -2379 * Defines text's outline color. -2380 * -2381 * @param color {string} sets a valid canvas context color. -2382 * @return this. -2383 */ -2384 setOutlineColor : function( color ) { -2385 this.outlineColor= color; -2386 return this; -2387 }, -2388 /** -2389 * Set the text to be shown by the actor. -2390 * @param sText a string with the text to be shwon. -2391 * @return this -2392 */ -2393 setText : function( sText ) { -2394 this.text= sText; -2395 if ( null===this.text || this.text==="" ) { -2396 this.width= this.height= 0; -2397 } -2398 this.calcTextSize( CAAT.director[0] ); -2399 -2400 return this; -2401 }, -2402 setTextAlign : function( align ) { -2403 this.textAlign= align; +2378 setPathTraverseDirection : function(direction) { +2379 this.sign= direction; +2380 return this; +2381 }, +2382 /** +2383 * Defines text's outline color. +2384 * +2385 * @param color {string} sets a valid canvas context color. +2386 * @return this. +2387 */ +2388 setOutlineColor : function( color ) { +2389 this.outlineColor= color; +2390 return this; +2391 }, +2392 /** +2393 * Set the text to be shown by the actor. +2394 * @param sText a string with the text to be shwon. +2395 * @return this +2396 */ +2397 setText : function( sText ) { +2398 this.text= sText; +2399 if ( null===this.text || this.text==="" ) { +2400 this.width= this.height= 0; +2401 } +2402 this.calcTextSize( CAAT.director[0] ); +2403 2404 return this; 2405 }, -2406 /** -2407 * Sets text alignment -2408 * @param align -2409 * @deprecated use setTextAlign -2410 */ -2411 setAlign : function( align ) { -2412 return this.setTextAlign(align); -2413 }, -2414 /** -2415 * Set text baseline. -2416 * @param baseline -2417 */ -2418 setTextBaseline : function( baseline ) { -2419 this.textBaseline= baseline; -2420 return this; -2421 -2422 }, -2423 setBaseline : function( baseline ) { -2424 return this.setTextBaseline(baseline); -2425 }, -2426 /** -2427 * Sets the font to be applied for the text. -2428 * @param font a string with a valid canvas rendering context font description. -2429 * @return this -2430 */ -2431 setFont : function(font) { -2432 -2433 if ( !font ) { -2434 font= "10px sans-serif"; -2435 } +2406 setTextAlign : function( align ) { +2407 this.textAlign= align; +2408 return this; +2409 }, +2410 /** +2411 * Sets text alignment +2412 * @param align +2413 * @deprecated use setTextAlign +2414 */ +2415 setAlign : function( align ) { +2416 return this.setTextAlign(align); +2417 }, +2418 /** +2419 * Set text baseline. +2420 * @param baseline +2421 */ +2422 setTextBaseline : function( baseline ) { +2423 this.textBaseline= baseline; +2424 return this; +2425 +2426 }, +2427 setBaseline : function( baseline ) { +2428 return this.setTextBaseline(baseline); +2429 }, +2430 /** +2431 * Sets the font to be applied for the text. +2432 * @param font a string with a valid canvas rendering context font description. +2433 * @return this +2434 */ +2435 setFont : function(font) { 2436 -2437 this.font= font; -2438 this.calcTextSize( CAAT.director[0] ); -2439 -2440 return this; -2441 }, -2442 -2443 /** -2444 * Calculates the text dimension in pixels and stores the values in textWidth and textHeight -2445 * attributes. -2446 * If Actor's width and height were not set, the Actor's dimension will be set to these values. -2447 * @param director a CAAT.Director instance. -2448 * @return this -2449 */ -2450 calcTextSize : function(director) { -2451 -2452 if ( typeof this.text==='undefined' || null===this.text || ""===this.text ) { -2453 this.textWidth= 0; -2454 this.textHeight= 0; -2455 return this; -2456 } -2457 -2458 if ( director.glEnabled ) { +2437 if ( !font ) { +2438 font= "10px sans-serif"; +2439 } +2440 +2441 this.font= font; +2442 this.calcTextSize( CAAT.director[0] ); +2443 +2444 return this; +2445 }, +2446 +2447 /** +2448 * Calculates the text dimension in pixels and stores the values in textWidth and textHeight +2449 * attributes. +2450 * If Actor's width and height were not set, the Actor's dimension will be set to these values. +2451 * @param director a CAAT.Director instance. +2452 * @return this +2453 */ +2454 calcTextSize : function(director) { +2455 +2456 if ( typeof this.text==='undefined' || null===this.text || ""===this.text ) { +2457 this.textWidth= 0; +2458 this.textHeight= 0; 2459 return this; 2460 } 2461 -2462 if ( this.font instanceof CAAT.SpriteImage ) { -2463 this.textWidth= this.font.stringWidth( this.text ); -2464 this.textHeight=this.font.stringHeight(); -2465 this.width= this.textWidth; -2466 this.height= this.textHeight; -2467 return this; -2468 } -2469 -2470 var ctx= director.ctx; -2471 -2472 ctx.save(); -2473 ctx.font= this.font; -2474 -2475 this.textWidth= ctx.measureText( this.text ).width; -2476 if (this.width===0) { -2477 this.width= this.textWidth; -2478 } -2479 -2480 try { -2481 var pos= this.font.indexOf("px"); -2482 var s = this.font.substring(0, pos ); -2483 this.textHeight= parseInt(s,10); -2484 -2485 // needed to calculate the descent. -2486 // no context.getDescent(font) WTF !!! -2487 this.textHeight+= (this.textHeight/4)>>0; -2488 } catch(e) { -2489 this.textHeight=20; // default height; -2490 } -2491 -2492 if ( this.height===0 ) { -2493 this.height= this.textHeight; +2462 if ( director.glEnabled ) { +2463 return this; +2464 } +2465 +2466 if ( this.font instanceof CAAT.SpriteImage ) { +2467 this.textWidth= this.font.stringWidth( this.text ); +2468 this.textHeight=this.font.stringHeight(); +2469 this.width= this.textWidth; +2470 this.height= this.textHeight; +2471 return this; +2472 } +2473 +2474 var ctx= director.ctx; +2475 +2476 ctx.save(); +2477 ctx.font= this.font; +2478 +2479 this.textWidth= ctx.measureText( this.text ).width; +2480 if (this.width===0) { +2481 this.width= this.textWidth; +2482 } +2483 +2484 try { +2485 var pos= this.font.indexOf("px"); +2486 var s = this.font.substring(0, pos ); +2487 this.textHeight= parseInt(s,10); +2488 +2489 // needed to calculate the descent. +2490 // no context.getDescent(font) WTF !!! +2491 this.textHeight+= (this.textHeight/4)>>0; +2492 } catch(e) { +2493 this.textHeight=20; // default height; 2494 } 2495 -2496 ctx.restore(); -2497 -2498 return this; -2499 }, -2500 /** -2501 * Custom paint method for TextActor instances. -2502 * If the path attribute is set, the text will be drawn traversing the path. -2503 * -2504 * @param director a valid CAAT.Director instance. -2505 * @param time an integer with the Scene time the Actor is being drawn. -2506 */ -2507 paint : function(director, time) { -2508 -2509 CAAT.TextActor.superclass.paint.call(this, director, time ); -2510 -2511 if ( this.cached ) { -2512 // cacheAsBitmap sets this actor's background image as a representation of itself. -2513 // So if after drawing the background it was cached, we're done. -2514 return; -2515 } -2516 -2517 if ( null===this.text) { -2518 return; -2519 } +2496 if ( this.height===0 ) { +2497 this.height= this.textHeight; +2498 } +2499 +2500 ctx.restore(); +2501 +2502 return this; +2503 }, +2504 /** +2505 * Custom paint method for TextActor instances. +2506 * If the path attribute is set, the text will be drawn traversing the path. +2507 * +2508 * @param director a valid CAAT.Director instance. +2509 * @param time an integer with the Scene time the Actor is being drawn. +2510 */ +2511 paint : function(director, time) { +2512 +2513 CAAT.TextActor.superclass.paint.call(this, director, time ); +2514 +2515 if ( this.cached ) { +2516 // cacheAsBitmap sets this actor's background image as a representation of itself. +2517 // So if after drawing the background it was cached, we're done. +2518 return; +2519 } 2520 -2521 if ( this.textWidth===0 || this.textHeight===0 ) { -2522 this.calcTextSize(director); -2523 } +2521 if ( null===this.text) { +2522 return; +2523 } 2524 -2525 var ctx= director.ctx; -2526 -2527 if ( this.font instanceof CAAT.SpriteImage ) { -2528 return this.drawSpriteText(director,time); -2529 } -2530 -2531 if( null!==this.font ) { -2532 ctx.font= this.font; +2525 if ( this.textWidth===0 || this.textHeight===0 ) { +2526 this.calcTextSize(director); +2527 } +2528 +2529 var ctx= director.ctx; +2530 +2531 if ( this.font instanceof CAAT.SpriteImage ) { +2532 return this.drawSpriteText(director,time); 2533 } -2534 if ( null!==this.textAlign ) { -2535 ctx.textAlign= this.textAlign; -2536 } -2537 if ( null!==this.textBaseline ) { -2538 ctx.textBaseline= this.textBaseline; -2539 } -2540 if ( this.fill && null!==this.textFillStyle ) { -2541 ctx.fillStyle= this.textFillStyle; -2542 } -2543 if ( this.outline && null!==this.outlineColor ) { -2544 ctx.strokeStyle= this.outlineColor; -2545 } -2546 -2547 if (null===this.path) { -2548 -2549 var tx=0; -2550 if ( this.textAlign==='center') { -2551 tx= (this.width/2)|0; -2552 } else if ( this.textAlign==='right' ) { -2553 tx= this.width; -2554 } -2555 -2556 if ( this.fill ) { -2557 ctx.fillText( this.text, tx, 0 ); -2558 if ( this.outline ) { +2534 +2535 if( null!==this.font ) { +2536 ctx.font= this.font; +2537 } +2538 if ( null!==this.textAlign ) { +2539 ctx.textAlign= this.textAlign; +2540 } +2541 if ( null!==this.textBaseline ) { +2542 ctx.textBaseline= this.textBaseline; +2543 } +2544 if ( this.fill && null!==this.textFillStyle ) { +2545 ctx.fillStyle= this.textFillStyle; +2546 } +2547 if ( this.outline && null!==this.outlineColor ) { +2548 ctx.strokeStyle= this.outlineColor; +2549 } +2550 +2551 if (null===this.path) { +2552 +2553 var tx=0; +2554 if ( this.textAlign==='center') { +2555 tx= (this.width/2)|0; +2556 } else if ( this.textAlign==='right' ) { +2557 tx= this.width; +2558 } 2559 -2560 // firefox necesita beginPath, si no, dibujara ademas el cuadrado del -2561 // contenedor de los textos. -2562 // if ( null!==this.outlineColor ) { -2563 // ctx.strokeStyle= this.outlineColor; -2564 // } -2565 ctx.beginPath(); -2566 ctx.strokeText( this.text, tx, 0 ); -2567 } -2568 } else { -2569 if ( null!==this.outlineColor ) { -2570 ctx.strokeStyle= this.outlineColor; +2560 if ( this.fill ) { +2561 ctx.fillText( this.text, tx, 0 ); +2562 if ( this.outline ) { +2563 +2564 // firefox necesita beginPath, si no, dibujara ademas el cuadrado del +2565 // contenedor de los textos. +2566 // if ( null!==this.outlineColor ) { +2567 // ctx.strokeStyle= this.outlineColor; +2568 // } +2569 ctx.beginPath(); +2570 ctx.strokeText( this.text, tx, 0 ); 2571 } -2572 ctx.beginPath(); -2573 ctx.strokeText( this.text, tx, 0 ); -2574 } -2575 } -2576 else { -2577 this.drawOnPath(director,time); -2578 } -2579 }, -2580 /** -2581 * Private. -2582 * Draw the text traversing a path. -2583 * @param director a valid CAAT.Director instance. -2584 * @param time an integer with the Scene time the Actor is being drawn. -2585 */ -2586 drawOnPath : function(director, time) { -2587 -2588 var ctx= director.ctx; -2589 -2590 var textWidth=this.sign * this.pathInterpolator.getPosition( -2591 (time%this.pathDuration)/this.pathDuration ).y * this.path.getLength() ; -2592 var p0= new CAAT.Point(0,0,0); -2593 var p1= new CAAT.Point(0,0,0); -2594 -2595 for( var i=0; i<this.text.length; i++ ) { -2596 var caracter= this.text[i].toString(); -2597 var charWidth= ctx.measureText( caracter ).width; -2598 var currentCurveLength= charWidth/2 + textWidth; -2599 -2600 p0= this.path.getPositionFromLength(currentCurveLength).clone(); -2601 p1= this.path.getPositionFromLength(currentCurveLength-0.1).clone(); -2602 -2603 var angle= Math.atan2( p0.y-p1.y, p0.x-p1.x ); -2604 -2605 ctx.save(); +2572 } else { +2573 if ( null!==this.outlineColor ) { +2574 ctx.strokeStyle= this.outlineColor; +2575 } +2576 ctx.beginPath(); +2577 ctx.strokeText( this.text, tx, 0 ); +2578 } +2579 } +2580 else { +2581 this.drawOnPath(director,time); +2582 } +2583 }, +2584 /** +2585 * Private. +2586 * Draw the text traversing a path. +2587 * @param director a valid CAAT.Director instance. +2588 * @param time an integer with the Scene time the Actor is being drawn. +2589 */ +2590 drawOnPath : function(director, time) { +2591 +2592 var ctx= director.ctx; +2593 +2594 var textWidth=this.sign * this.pathInterpolator.getPosition( +2595 (time%this.pathDuration)/this.pathDuration ).y * this.path.getLength() ; +2596 var p0= new CAAT.Point(0,0,0); +2597 var p1= new CAAT.Point(0,0,0); +2598 +2599 for( var i=0; i<this.text.length; i++ ) { +2600 var caracter= this.text[i].toString(); +2601 var charWidth= ctx.measureText( caracter ).width; +2602 var currentCurveLength= charWidth/2 + textWidth; +2603 +2604 p0= this.path.getPositionFromLength(currentCurveLength).clone(); +2605 p1= this.path.getPositionFromLength(currentCurveLength-0.1).clone(); 2606 -2607 ctx.translate( (0.5+p0.x)|0, (0.5+p0.y)|0 ); -2608 ctx.rotate( angle ); -2609 if ( this.fill ) { -2610 ctx.fillText(caracter,0,0); -2611 } -2612 if ( this.outline ) { -2613 // ctx.strokeStyle= this.outlineColor; -2614 ctx.strokeText(caracter,0,0); +2607 var angle= Math.atan2( p0.y-p1.y, p0.x-p1.x ); +2608 +2609 ctx.save(); +2610 +2611 ctx.translate( (0.5+p0.x)|0, (0.5+p0.y)|0 ); +2612 ctx.rotate( angle ); +2613 if ( this.fill ) { +2614 ctx.fillText(caracter,0,0); 2615 } -2616 -2617 ctx.restore(); -2618 -2619 textWidth+= charWidth; -2620 } -2621 }, -2622 -2623 /** -2624 * Private. -2625 * Draw the text using a sprited font instead of a canvas font. -2626 * @param director a valid CAAT.Director instance. -2627 * @param time an integer with the Scene time the Actor is being drawn. -2628 */ -2629 drawSpriteText: function(director, time) { -2630 if (null===this.path) { -2631 this.font.drawString( director.ctx, this.text, 0, 0); -2632 } else { -2633 this.drawSpriteTextOnPath(director, time); -2634 } -2635 }, -2636 -2637 /** -2638 * Private. -2639 * Draw the text traversing a path using a sprited font. -2640 * @param director a valid CAAT.Director instance. -2641 * @param time an integer with the Scene time the Actor is being drawn. -2642 */ -2643 drawSpriteTextOnPath: function(director, time) { -2644 var context= director.ctx; -2645 -2646 var textWidth=this.sign * this.pathInterpolator.getPosition( -2647 (time%this.pathDuration)/this.pathDuration ).y * this.path.getLength() ; -2648 var p0= new CAAT.Point(0,0,0); -2649 var p1= new CAAT.Point(0,0,0); -2650 -2651 for( var i=0; i<this.text.length; i++ ) { -2652 var character= this.text[i].toString(); -2653 var charWidth= this.font.stringWidth(character); //context.measureText( caracter ).width; +2616 if ( this.outline ) { +2617 // ctx.strokeStyle= this.outlineColor; +2618 ctx.strokeText(caracter,0,0); +2619 } +2620 +2621 ctx.restore(); +2622 +2623 textWidth+= charWidth; +2624 } +2625 }, +2626 +2627 /** +2628 * Private. +2629 * Draw the text using a sprited font instead of a canvas font. +2630 * @param director a valid CAAT.Director instance. +2631 * @param time an integer with the Scene time the Actor is being drawn. +2632 */ +2633 drawSpriteText: function(director, time) { +2634 if (null===this.path) { +2635 this.font.drawString( director.ctx, this.text, 0, 0); +2636 } else { +2637 this.drawSpriteTextOnPath(director, time); +2638 } +2639 }, +2640 +2641 /** +2642 * Private. +2643 * Draw the text traversing a path using a sprited font. +2644 * @param director a valid CAAT.Director instance. +2645 * @param time an integer with the Scene time the Actor is being drawn. +2646 */ +2647 drawSpriteTextOnPath: function(director, time) { +2648 var context= director.ctx; +2649 +2650 var textWidth=this.sign * this.pathInterpolator.getPosition( +2651 (time%this.pathDuration)/this.pathDuration ).y * this.path.getLength() ; +2652 var p0= new CAAT.Point(0,0,0); +2653 var p1= new CAAT.Point(0,0,0); 2654 -2655 var pathLength= this.path.getLength(); -2656 -2657 var currentCurveLength= charWidth/2 + textWidth; +2655 for( var i=0; i<this.text.length; i++ ) { +2656 var character= this.text[i].toString(); +2657 var charWidth= this.font.stringWidth(character); //context.measureText( caracter ).width; 2658 -2659 p0= this.path.getPositionFromLength(currentCurveLength).clone(); -2660 p1= this.path.getPositionFromLength(currentCurveLength-0.1).clone(); -2661 -2662 var angle= Math.atan2( p0.y-p1.y, p0.x-p1.x ); -2663 -2664 context.save(); +2659 var pathLength= this.path.getLength(); +2660 +2661 var currentCurveLength= charWidth/2 + textWidth; +2662 +2663 p0= this.path.getPositionFromLength(currentCurveLength).clone(); +2664 p1= this.path.getPositionFromLength(currentCurveLength-0.1).clone(); 2665 -2666 context.translate( (0.5+p0.x)|0, (0.5+p0.y)|0 ); -2667 context.rotate( angle ); -2668 -2669 var y = this.textBaseline === "bottom" ? 0 - this.font.height : 0; -2670 -2671 this.font.drawString(context,character, 0, y); -2672 -2673 context.restore(); -2674 -2675 textWidth+= charWidth; -2676 } -2677 }, -2678 -2679 /** -2680 * Set the path, interpolator and duration to draw the text on. -2681 * @param path a valid CAAT.Path instance. -2682 * @param interpolator a CAAT.Interpolator object. If not set, a Linear Interpolator will be used. -2683 * @param duration an integer indicating the time to take to traverse the path. Optional. 10000 ms -2684 * by default. -2685 */ -2686 setPath : function( path, interpolator, duration ) { -2687 this.path= path; -2688 this.pathInterpolator= interpolator || new CAAT.Interpolator().createLinearInterpolator(); -2689 this.pathDuration= duration || 10000; -2690 -2691 /* -2692 parent could not be set by the time this method is called. -2693 so the actors bounds set is removed. -2694 the developer must ensure to call setbounds properly on actor. -2695 */ -2696 this.mouseEnabled= false; -2697 -2698 return this; -2699 } -2700 }; +2666 var angle= Math.atan2( p0.y-p1.y, p0.x-p1.x ); +2667 +2668 context.save(); +2669 +2670 context.translate( p0.x|0, p0.y|0 ); +2671 context.rotate( angle ); +2672 +2673 var y = this.textBaseline === "bottom" ? 0 - this.font.height : 0; +2674 +2675 this.font.drawString(context,character, 0, y); +2676 +2677 context.restore(); +2678 +2679 textWidth+= charWidth; +2680 } +2681 }, +2682 +2683 /** +2684 * Set the path, interpolator and duration to draw the text on. +2685 * @param path a valid CAAT.Path instance. +2686 * @param interpolator a CAAT.Interpolator object. If not set, a Linear Interpolator will be used. +2687 * @param duration an integer indicating the time to take to traverse the path. Optional. 10000 ms +2688 * by default. +2689 */ +2690 setPath : function( path, interpolator, duration ) { +2691 this.path= path; +2692 this.pathInterpolator= interpolator || new CAAT.Interpolator().createLinearInterpolator(); +2693 this.pathDuration= duration || 10000; +2694 +2695 /* +2696 parent could not be set by the time this method is called. +2697 so the actors bounds set is removed. +2698 the developer must ensure to call setbounds properly on actor. +2699 */ +2700 this.mouseEnabled= false; 2701 -2702 extend( CAAT.TextActor, CAAT.Actor, null); -2703 })(); -2704 -2705 (function() { -2706 -2707 /** -2708 * This Actor draws common shapes, concretely Circles and rectangles. -2709 * -2710 * @constructor -2711 * @extends CAAT.ActorContainer -2712 */ -2713 CAAT.ShapeActor = function() { -2714 CAAT.ShapeActor.superclass.constructor.call(this); -2715 this.compositeOp= 'source-over'; -2716 -2717 /** -2718 * Thanks Svend Dutz and Thomas Karolski for noticing this call was not performed by default, -2719 * so if no explicit call to setShape was made, nothing would be drawn. -2720 */ -2721 this.setShape( this.SHAPE_CIRCLE ); -2722 return this; -2723 }; -2724 -2725 CAAT.ShapeActor.prototype= { -2726 -2727 shape: 0, // shape type. One of the constant SHAPE_* values -2728 compositeOp: null, // a valid canvas rendering context string describing compositeOps. -2729 lineWidth: 1, -2730 lineCap: null, -2731 lineJoin: null, -2732 miterLimit: null, -2733 -2734 SHAPE_CIRCLE: 0, // Constants to describe different shapes. -2735 SHAPE_RECTANGLE:1, -2736 -2737 /** -2738 * -2739 * @param l {number>0} -2740 */ -2741 setLineWidth : function(l) { -2742 this.lineWidth= l; -2743 return this; -2744 }, -2745 /** -2746 * -2747 * @param lc {string{butt|round|square}} -2748 */ -2749 setLineCap : function(lc) { -2750 this.lineCap= lc; -2751 return this; -2752 }, -2753 /** -2754 * -2755 * @param lj {string{bevel|round|miter}} -2756 */ -2757 setLineJoin : function(lj) { -2758 this.lineJoin= lj; -2759 return this; -2760 }, -2761 /** -2762 * -2763 * @param ml {integer>0} -2764 */ -2765 setMiterLimit : function(ml) { -2766 this.miterLimit= ml; -2767 return this; -2768 }, -2769 getLineCap : function() { -2770 return this.lineCap; -2771 }, -2772 getLineJoin : function() { -2773 return this.lineJoin; -2774 }, -2775 getMiterLimit : function() { -2776 return this.miterLimit; -2777 }, -2778 getLineWidth : function() { -2779 return this.lineWidth; -2780 }, -2781 /** -2782 * Sets shape type. -2783 * No check for parameter validity is performed. -2784 * Set paint method according to the shape. -2785 * @param iShape an integer with any of the SHAPE_* constants. -2786 * @return this -2787 */ -2788 setShape : function(iShape) { -2789 this.shape= iShape; -2790 this.paint= this.shape===this.SHAPE_CIRCLE ? -2791 this.paintCircle : -2792 this.paintRectangle; -2793 return this; -2794 }, -2795 /** -2796 * Sets the composite operation to apply on shape drawing. -2797 * @param compositeOp an string with a valid canvas rendering context string describing compositeOps. -2798 * @return this -2799 */ -2800 setCompositeOp : function(compositeOp){ -2801 this.compositeOp= compositeOp; -2802 return this; -2803 }, -2804 /** -2805 * Draws the shape. -2806 * Applies the values of fillStype, strokeStyle, compositeOp, etc. -2807 * -2808 * @param director a valid CAAT.Director instance. -2809 * @param time an integer with the Scene time the Actor is being drawn. -2810 */ -2811 paint : function(director,time) { -2812 }, -2813 /** -2814 * @private -2815 * Draws a circle. -2816 * @param director a valid CAAT.Director instance. -2817 * @param time an integer with the Scene time the Actor is being drawn. -2818 */ -2819 paintCircle : function(director,time) { -2820 var ctx= director.crc; -2821 -2822 ctx.lineWidth= this.lineWidth; -2823 -2824 ctx.globalCompositeOperation= this.compositeOp; -2825 if ( null!==this.fillStyle ) { -2826 ctx.fillStyle= this.fillStyle; -2827 ctx.beginPath(); -2828 ctx.arc( this.width/2, this.height/2, Math.min(this.width,this.height)/2, 0, 2*Math.PI, false ); -2829 ctx.fill(); -2830 } -2831 -2832 if ( null!==this.strokeStyle ) { -2833 ctx.strokeStyle= this.strokeStyle; -2834 ctx.beginPath(); -2835 ctx.arc( this.width/2, this.height/2, Math.min(this.width,this.height)/2, 0, 2*Math.PI, false ); -2836 ctx.stroke(); -2837 } -2838 }, -2839 /** -2840 * -2841 * Private -2842 * Draws a Rectangle. -2843 * -2844 * @param director a valid CAAT.Director instance. -2845 * @param time an integer with the Scene time the Actor is being drawn. -2846 */ -2847 paintRectangle : function(director,time) { -2848 var ctx= director.crc; -2849 -2850 ctx.lineWidth= this.lineWidth; -2851 -2852 if ( this.lineCap ) { -2853 ctx.lineCap= this.lineCap; -2854 } -2855 if ( this.lineJoin ) { -2856 ctx.lineJoin= this.lineJoin; -2857 } -2858 if ( this.miterLimit ) { -2859 ctx.miterLimit= this.miterLimit; -2860 } -2861 -2862 ctx.globalCompositeOperation= this.compositeOp; -2863 if ( null!==this.fillStyle ) { -2864 ctx.fillStyle= this.fillStyle; -2865 ctx.beginPath(); -2866 ctx.fillRect(0,0,this.width,this.height); -2867 ctx.fill(); -2868 } -2869 -2870 if ( null!==this.strokeStyle ) { -2871 ctx.strokeStyle= this.strokeStyle; -2872 ctx.beginPath(); -2873 ctx.strokeRect(0,0,this.width,this.height); -2874 ctx.stroke(); -2875 } -2876 } -2877 }; -2878 -2879 extend( CAAT.ShapeActor, CAAT.ActorContainer, null); -2880 })(); -2881 -2882 (function() { -2883 -2884 /** -2885 * This actor draws stars. -2886 * -2887 * @constructor -2888 * @extends CAAT.ActorContainer -2889 */ -2890 CAAT.StarActor= function() { -2891 CAAT.StarActor.superclass.constructor.call(this); -2892 this.compositeOp= 'source-over'; -2893 return this; -2894 }; -2895 -2896 CAAT.StarActor.prototype= { -2897 nPeaks: 0, -2898 maxRadius: 0, -2899 minRadius: 0, -2900 initialAngle: 0, -2901 compositeOp: null, -2902 lineWidth: 1, -2903 lineCap: null, -2904 lineJoin: null, -2905 miterLimit: null, -2906 -2907 /** -2908 * -2909 * @param l {number>0} -2910 */ -2911 setLineWidth : function(l) { -2912 this.lineWidth= l; -2913 return this; -2914 }, -2915 /** -2916 * -2917 * @param lc {string{butt|round|square}} -2918 */ -2919 setLineCap : function(lc) { -2920 this.lineCap= lc; -2921 return this; -2922 }, -2923 /** -2924 * -2925 * @param lj {string{bevel|round|miter}} -2926 */ -2927 setLineJoin : function(lj) { -2928 this.lineJoin= lj; -2929 return this; -2930 }, -2931 /** -2932 * -2933 * @param ml {integer>0} -2934 */ -2935 setMiterLimit : function(ml) { -2936 this.miterLimit= ml; -2937 return this; -2938 }, -2939 getLineCap : function() { -2940 return this.lineCap; -2941 }, -2942 getLineJoin : function() { -2943 return this.lineJoin; -2944 }, -2945 getMiterLimit : function() { -2946 return this.miterLimit; -2947 }, -2948 getLineWidth : function() { -2949 return this.lineWidth; -2950 }, -2951 /** -2952 * Sets whether the star will be color filled. -2953 * @param filled {boolean} -2954 * @deprecated -2955 */ -2956 setFilled : function( filled ) { -2957 return this; -2958 }, -2959 /** -2960 * Sets whether the star will be outlined. -2961 * @param outlined {boolean} -2962 * @deprecated -2963 */ -2964 setOutlined : function( outlined ) { -2965 return this; -2966 }, -2967 /** -2968 * Sets the composite operation to apply on shape drawing. -2969 * @param compositeOp an string with a valid canvas rendering context string describing compositeOps. -2970 * @return this -2971 */ -2972 setCompositeOp : function(compositeOp){ -2973 this.compositeOp= compositeOp; -2974 return this; -2975 }, -2976 /** -2977 * -2978 * @param angle {number} number in radians. -2979 */ -2980 setInitialAngle : function(angle) { -2981 this.initialAngle= angle; -2982 return this; -2983 }, -2984 /** -2985 * Initialize the star values. -2986 * <p> -2987 * The star actor will be of size 2*maxRadius. -2988 * -2989 * @param nPeaks {number} number of star points. -2990 * @param maxRadius {number} maximum star radius -2991 * @param minRadius {number} minimum star radius +2702 return this; +2703 } +2704 }; +2705 +2706 extend( CAAT.TextActor, CAAT.Actor, null); +2707 })(); +2708 +2709 (function() { +2710 +2711 /** +2712 * This Actor draws common shapes, concretely Circles and rectangles. +2713 * +2714 * @constructor +2715 * @extends CAAT.ActorContainer +2716 */ +2717 CAAT.ShapeActor = function() { +2718 CAAT.ShapeActor.superclass.constructor.call(this); +2719 this.compositeOp= 'source-over'; +2720 +2721 /** +2722 * Thanks Svend Dutz and Thomas Karolski for noticing this call was not performed by default, +2723 * so if no explicit call to setShape was made, nothing would be drawn. +2724 */ +2725 this.setShape( this.SHAPE_CIRCLE ); +2726 return this; +2727 }; +2728 +2729 CAAT.ShapeActor.prototype= { +2730 +2731 shape: 0, // shape type. One of the constant SHAPE_* values +2732 compositeOp: null, // a valid canvas rendering context string describing compositeOps. +2733 lineWidth: 1, +2734 lineCap: null, +2735 lineJoin: null, +2736 miterLimit: null, +2737 +2738 SHAPE_CIRCLE: 0, // Constants to describe different shapes. +2739 SHAPE_RECTANGLE:1, +2740 +2741 /** +2742 * +2743 * @param l {number>0} +2744 */ +2745 setLineWidth : function(l) { +2746 this.lineWidth= l; +2747 return this; +2748 }, +2749 /** +2750 * +2751 * @param lc {string{butt|round|square}} +2752 */ +2753 setLineCap : function(lc) { +2754 this.lineCap= lc; +2755 return this; +2756 }, +2757 /** +2758 * +2759 * @param lj {string{bevel|round|miter}} +2760 */ +2761 setLineJoin : function(lj) { +2762 this.lineJoin= lj; +2763 return this; +2764 }, +2765 /** +2766 * +2767 * @param ml {integer>0} +2768 */ +2769 setMiterLimit : function(ml) { +2770 this.miterLimit= ml; +2771 return this; +2772 }, +2773 getLineCap : function() { +2774 return this.lineCap; +2775 }, +2776 getLineJoin : function() { +2777 return this.lineJoin; +2778 }, +2779 getMiterLimit : function() { +2780 return this.miterLimit; +2781 }, +2782 getLineWidth : function() { +2783 return this.lineWidth; +2784 }, +2785 /** +2786 * Sets shape type. +2787 * No check for parameter validity is performed. +2788 * Set paint method according to the shape. +2789 * @param iShape an integer with any of the SHAPE_* constants. +2790 * @return this +2791 */ +2792 setShape : function(iShape) { +2793 this.shape= iShape; +2794 this.paint= this.shape===this.SHAPE_CIRCLE ? +2795 this.paintCircle : +2796 this.paintRectangle; +2797 return this; +2798 }, +2799 /** +2800 * Sets the composite operation to apply on shape drawing. +2801 * @param compositeOp an string with a valid canvas rendering context string describing compositeOps. +2802 * @return this +2803 */ +2804 setCompositeOp : function(compositeOp){ +2805 this.compositeOp= compositeOp; +2806 return this; +2807 }, +2808 /** +2809 * Draws the shape. +2810 * Applies the values of fillStype, strokeStyle, compositeOp, etc. +2811 * +2812 * @param director a valid CAAT.Director instance. +2813 * @param time an integer with the Scene time the Actor is being drawn. +2814 */ +2815 paint : function(director,time) { +2816 }, +2817 /** +2818 * @private +2819 * Draws a circle. +2820 * @param director a valid CAAT.Director instance. +2821 * @param time an integer with the Scene time the Actor is being drawn. +2822 */ +2823 paintCircle : function(director,time) { +2824 var ctx= director.crc; +2825 +2826 ctx.lineWidth= this.lineWidth; +2827 +2828 ctx.globalCompositeOperation= this.compositeOp; +2829 if ( null!==this.fillStyle ) { +2830 ctx.fillStyle= this.fillStyle; +2831 ctx.beginPath(); +2832 ctx.arc( this.width/2, this.height/2, Math.min(this.width,this.height)/2, 0, 2*Math.PI, false ); +2833 ctx.fill(); +2834 } +2835 +2836 if ( null!==this.strokeStyle ) { +2837 ctx.strokeStyle= this.strokeStyle; +2838 ctx.beginPath(); +2839 ctx.arc( this.width/2, this.height/2, Math.min(this.width,this.height)/2, 0, 2*Math.PI, false ); +2840 ctx.stroke(); +2841 } +2842 }, +2843 /** +2844 * +2845 * Private +2846 * Draws a Rectangle. +2847 * +2848 * @param director a valid CAAT.Director instance. +2849 * @param time an integer with the Scene time the Actor is being drawn. +2850 */ +2851 paintRectangle : function(director,time) { +2852 var ctx= director.crc; +2853 +2854 ctx.lineWidth= this.lineWidth; +2855 +2856 if ( this.lineCap ) { +2857 ctx.lineCap= this.lineCap; +2858 } +2859 if ( this.lineJoin ) { +2860 ctx.lineJoin= this.lineJoin; +2861 } +2862 if ( this.miterLimit ) { +2863 ctx.miterLimit= this.miterLimit; +2864 } +2865 +2866 ctx.globalCompositeOperation= this.compositeOp; +2867 if ( null!==this.fillStyle ) { +2868 ctx.fillStyle= this.fillStyle; +2869 ctx.beginPath(); +2870 ctx.fillRect(0,0,this.width,this.height); +2871 ctx.fill(); +2872 } +2873 +2874 if ( null!==this.strokeStyle ) { +2875 ctx.strokeStyle= this.strokeStyle; +2876 ctx.beginPath(); +2877 ctx.strokeRect(0,0,this.width,this.height); +2878 ctx.stroke(); +2879 } +2880 } +2881 }; +2882 +2883 extend( CAAT.ShapeActor, CAAT.ActorContainer, null); +2884 })(); +2885 +2886 (function() { +2887 +2888 /** +2889 * This actor draws stars. +2890 * +2891 * @constructor +2892 * @extends CAAT.ActorContainer +2893 */ +2894 CAAT.StarActor= function() { +2895 CAAT.StarActor.superclass.constructor.call(this); +2896 this.compositeOp= 'source-over'; +2897 return this; +2898 }; +2899 +2900 CAAT.StarActor.prototype= { +2901 nPeaks: 0, +2902 maxRadius: 0, +2903 minRadius: 0, +2904 initialAngle: 0, +2905 compositeOp: null, +2906 lineWidth: 1, +2907 lineCap: null, +2908 lineJoin: null, +2909 miterLimit: null, +2910 +2911 /** +2912 * +2913 * @param l {number>0} +2914 */ +2915 setLineWidth : function(l) { +2916 this.lineWidth= l; +2917 return this; +2918 }, +2919 /** +2920 * +2921 * @param lc {string{butt|round|square}} +2922 */ +2923 setLineCap : function(lc) { +2924 this.lineCap= lc; +2925 return this; +2926 }, +2927 /** +2928 * +2929 * @param lj {string{bevel|round|miter}} +2930 */ +2931 setLineJoin : function(lj) { +2932 this.lineJoin= lj; +2933 return this; +2934 }, +2935 /** +2936 * +2937 * @param ml {integer>0} +2938 */ +2939 setMiterLimit : function(ml) { +2940 this.miterLimit= ml; +2941 return this; +2942 }, +2943 getLineCap : function() { +2944 return this.lineCap; +2945 }, +2946 getLineJoin : function() { +2947 return this.lineJoin; +2948 }, +2949 getMiterLimit : function() { +2950 return this.miterLimit; +2951 }, +2952 getLineWidth : function() { +2953 return this.lineWidth; +2954 }, +2955 /** +2956 * Sets whether the star will be color filled. +2957 * @param filled {boolean} +2958 * @deprecated +2959 */ +2960 setFilled : function( filled ) { +2961 return this; +2962 }, +2963 /** +2964 * Sets whether the star will be outlined. +2965 * @param outlined {boolean} +2966 * @deprecated +2967 */ +2968 setOutlined : function( outlined ) { +2969 return this; +2970 }, +2971 /** +2972 * Sets the composite operation to apply on shape drawing. +2973 * @param compositeOp an string with a valid canvas rendering context string describing compositeOps. +2974 * @return this +2975 */ +2976 setCompositeOp : function(compositeOp){ +2977 this.compositeOp= compositeOp; +2978 return this; +2979 }, +2980 /** +2981 * +2982 * @param angle {number} number in radians. +2983 */ +2984 setInitialAngle : function(angle) { +2985 this.initialAngle= angle; +2986 return this; +2987 }, +2988 /** +2989 * Initialize the star values. +2990 * <p> +2991 * The star actor will be of size 2*maxRadius. 2992 * -2993 * @return this -2994 */ -2995 initialize : function(nPeaks, maxRadius, minRadius) { -2996 this.setSize( 2*maxRadius, 2*maxRadius ); -2997 -2998 this.nPeaks= nPeaks; -2999 this.maxRadius= maxRadius; -3000 this.minRadius= minRadius; +2993 * @param nPeaks {number} number of star points. +2994 * @param maxRadius {number} maximum star radius +2995 * @param minRadius {number} minimum star radius +2996 * +2997 * @return this +2998 */ +2999 initialize : function(nPeaks, maxRadius, minRadius) { +3000 this.setSize( 2*maxRadius, 2*maxRadius ); 3001 -3002 return this; -3003 }, -3004 /** -3005 * Paint the star. -3006 * -3007 * @param director {CAAT.Director} -3008 * @param timer {number} -3009 */ -3010 paint : function(director, timer) { -3011 -3012 var ctx= director.ctx; -3013 var centerX= this.width/2; -3014 var centerY= this.height/2; -3015 var r1= this.maxRadius; -3016 var r2= this.minRadius; -3017 var ix= centerX + r1*Math.cos(this.initialAngle); -3018 var iy= centerY + r1*Math.sin(this.initialAngle); -3019 -3020 ctx.lineWidth= this.lineWidth; -3021 if ( this.lineCap ) { -3022 ctx.lineCap= this.lineCap; -3023 } -3024 if ( this.lineJoin ) { -3025 ctx.lineJoin= this.lineJoin; -3026 } -3027 if ( this.miterLimit ) { -3028 ctx.miterLimit= this.miterLimit; -3029 } -3030 -3031 ctx.globalCompositeOperation= this.compositeOp; -3032 -3033 ctx.beginPath(); -3034 ctx.moveTo(ix,iy); -3035 -3036 for( var i=1; i<this.nPeaks*2; i++ ) { -3037 var angleStar= Math.PI/this.nPeaks * i + this.initialAngle; -3038 var rr= (i%2===0) ? r1 : r2; -3039 var x= centerX + rr*Math.cos(angleStar); -3040 var y= centerY + rr*Math.sin(angleStar); -3041 ctx.lineTo(x,y); -3042 } -3043 -3044 ctx.lineTo( -3045 centerX + r1*Math.cos(this.initialAngle), -3046 centerY + r1*Math.sin(this.initialAngle) ); +3002 this.nPeaks= nPeaks; +3003 this.maxRadius= maxRadius; +3004 this.minRadius= minRadius; +3005 +3006 return this; +3007 }, +3008 /** +3009 * Paint the star. +3010 * +3011 * @param director {CAAT.Director} +3012 * @param timer {number} +3013 */ +3014 paint : function(director, timer) { +3015 +3016 var ctx= director.ctx; +3017 var centerX= this.width/2; +3018 var centerY= this.height/2; +3019 var r1= this.maxRadius; +3020 var r2= this.minRadius; +3021 var ix= centerX + r1*Math.cos(this.initialAngle); +3022 var iy= centerY + r1*Math.sin(this.initialAngle); +3023 +3024 ctx.lineWidth= this.lineWidth; +3025 if ( this.lineCap ) { +3026 ctx.lineCap= this.lineCap; +3027 } +3028 if ( this.lineJoin ) { +3029 ctx.lineJoin= this.lineJoin; +3030 } +3031 if ( this.miterLimit ) { +3032 ctx.miterLimit= this.miterLimit; +3033 } +3034 +3035 ctx.globalCompositeOperation= this.compositeOp; +3036 +3037 ctx.beginPath(); +3038 ctx.moveTo(ix,iy); +3039 +3040 for( var i=1; i<this.nPeaks*2; i++ ) { +3041 var angleStar= Math.PI/this.nPeaks * i + this.initialAngle; +3042 var rr= (i%2===0) ? r1 : r2; +3043 var x= centerX + rr*Math.cos(angleStar); +3044 var y= centerY + rr*Math.sin(angleStar); +3045 ctx.lineTo(x,y); +3046 } 3047 -3048 ctx.closePath(); -3049 -3050 if ( this.fillStyle ) { -3051 ctx.fillStyle= this.fillStyle; -3052 ctx.fill(); -3053 } -3054 -3055 if ( this.strokeStyle ) { -3056 ctx.strokeStyle= this.strokeStyle; -3057 ctx.stroke(); -3058 } -3059 -3060 } -3061 }; -3062 -3063 extend(CAAT.StarActor, CAAT.ActorContainer, null); -3064 -3065 })(); +3048 ctx.lineTo( +3049 centerX + r1*Math.cos(this.initialAngle), +3050 centerY + r1*Math.sin(this.initialAngle) ); +3051 +3052 ctx.closePath(); +3053 +3054 if ( this.fillStyle ) { +3055 ctx.fillStyle= this.fillStyle; +3056 ctx.fill(); +3057 } +3058 +3059 if ( this.strokeStyle ) { +3060 ctx.strokeStyle= this.strokeStyle; +3061 ctx.stroke(); +3062 } +3063 +3064 } +3065 }; 3066 -3067 /** -3068 * An actor suitable to draw an ImageProcessor instance. -3069 */ -3070 (function() { -3071 -3072 /** -3073 * This Actor will show the result of an image processing operation. -3074 * -3075 * @constructor -3076 * @extends CAAT.ActorContainer -3077 */ -3078 CAAT.IMActor= function() { -3079 CAAT.IMActor.superclass.constructor.call(this); -3080 return this; -3081 }; -3082 -3083 CAAT.IMActor.prototype= { -3084 -3085 imageProcessor: null, -3086 changeTime: 100, -3087 lastApplicationTime: -1, +3067 extend(CAAT.StarActor, CAAT.ActorContainer, null); +3068 +3069 })(); +3070 +3071 /** +3072 * An actor suitable to draw an ImageProcessor instance. +3073 */ +3074 (function() { +3075 +3076 /** +3077 * This Actor will show the result of an image processing operation. +3078 * +3079 * @constructor +3080 * @extends CAAT.ActorContainer +3081 */ +3082 CAAT.IMActor= function() { +3083 CAAT.IMActor.superclass.constructor.call(this); +3084 return this; +3085 }; +3086 +3087 CAAT.IMActor.prototype= { 3088 -3089 /** -3090 * Set the image processor. -3091 * -3092 * @param im {CAAT.ImageProcessor} a CAAT.ImageProcessor instance. -3093 */ -3094 setImageProcessor : function(im) { -3095 this.imageProcessor= im; -3096 return this; -3097 }, -3098 /** -3099 * Call image processor to update image every time milliseconds. -3100 * @param time an integer indicating milliseconds to elapse before updating the frame. -3101 */ -3102 setImageProcessingTime : function( time ) { -3103 this.changeTime= time; -3104 return this; -3105 }, -3106 paint : function( director, time ) { -3107 if ( time-this.lastApplicationTime>this.changeTime ) { -3108 this.imageProcessor.apply( director, time ); -3109 this.lastApplicationTime= time; -3110 } -3111 -3112 var ctx= director.ctx; -3113 this.imageProcessor.paint( director, time ); -3114 } -3115 }; -3116 -3117 extend( CAAT.IMActor, CAAT.ActorContainer, null); -3118 })(); \ No newline at end of file +3089 imageProcessor: null, +3090 changeTime: 100, +3091 lastApplicationTime: -1, +3092 +3093 /** +3094 * Set the image processor. +3095 * +3096 * @param im {CAAT.ImageProcessor} a CAAT.ImageProcessor instance. +3097 */ +3098 setImageProcessor : function(im) { +3099 this.imageProcessor= im; +3100 return this; +3101 }, +3102 /** +3103 * Call image processor to update image every time milliseconds. +3104 * @param time an integer indicating milliseconds to elapse before updating the frame. +3105 */ +3106 setImageProcessingTime : function( time ) { +3107 this.changeTime= time; +3108 return this; +3109 }, +3110 paint : function( director, time ) { +3111 if ( time-this.lastApplicationTime>this.changeTime ) { +3112 this.imageProcessor.apply( director, time ); +3113 this.lastApplicationTime= time; +3114 } +3115 +3116 var ctx= director.ctx; +3117 this.imageProcessor.paint( director, time ); +3118 } +3119 }; +3120 +3121 extend( CAAT.IMActor, CAAT.ActorContainer, null); +3122 })(); \ No newline at end of file diff --git a/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_path_path.js.html b/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_path_path.js.html index 18c27d25..f0958e68 100644 --- a/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_path_path.js.html +++ b/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_path_path.js.html @@ -38,7 +38,7 @@ 31 }; 32 33 CAAT.PathSegment.prototype = { - 34 color: 'black', + 34 color: '#000', 35 length: 0, 36 bbox: null, 37 parent: null, @@ -156,1618 +156,1714 @@ 149 * Transform this path with the given affinetransform matrix. 150 * @param matrix 151 */ -152 transform : function(matrix) {} -153 }; -154 -155 })(); -156 -157 (function() { -158 -159 /** -160 * Straight line segment path between two given points. -161 * -162 * @constructor -163 * @extends CAAT.PathSegment -164 */ -165 CAAT.LinearPath = function() { -166 CAAT.LinearPath.superclass.constructor.call(this); -167 -168 this.points= []; -169 this.points.push( new CAAT.Point() ); -170 this.points.push( new CAAT.Point() ); -171 -172 this.newPosition= new CAAT.Point(0,0,0); -173 return this; -174 }; -175 -176 CAAT.LinearPath.prototype= { -177 points: null, -178 newPosition: null, // spare holder for getPosition coordinate return. -179 -180 applyAsPath : function(director) { -181 director.ctx.lineTo( this.points[0].x, this.points[1].y ); -182 }, -183 setPoint : function( point, index ) { -184 if ( index===0 ) { -185 this.points[0]= point; -186 } else if ( index===1 ) { -187 this.points[1]= point; -188 } -189 }, -190 /** -191 * Update this segments length and bounding box info. -192 */ -193 updatePath : function(point) { -194 var x= this.points[1].x - this.points[0].x; -195 var y= this.points[1].y - this.points[0].y; -196 this.length= Math.sqrt( x*x+y*y ); -197 -198 this.bbox.setEmpty(); -199 this.bbox.union( this.points[0].x, this.points[0].y ); -200 this.bbox.union( this.points[1].x, this.points[1].y ); -201 -202 return this; +152 transform : function(matrix) {}, +153 +154 drawHandle : function( ctx, x, y ) { +155 var w= CAAT.Curve.prototype.HANDLE_SIZE/2; +156 ctx.fillRect( x-w, y-w, w*2, w*2 ); +157 /* +158 ctx.arc( +159 this.points[0].x, +160 this.points[0].y, +161 CAAT.Curve.prototype.HANDLE_SIZE/2, +162 0, +163 2*Math.PI, +164 false) ; +165 */ +166 } +167 }; +168 +169 })(); +170 +171 (function() { +172 +173 /** +174 * Straight line segment path between two given points. +175 * +176 * @constructor +177 * @extends CAAT.PathSegment +178 */ +179 CAAT.LinearPath = function() { +180 CAAT.LinearPath.superclass.constructor.call(this); +181 +182 this.points= []; +183 this.points.push( new CAAT.Point() ); +184 this.points.push( new CAAT.Point() ); +185 +186 this.newPosition= new CAAT.Point(0,0,0); +187 return this; +188 }; +189 +190 CAAT.LinearPath.prototype= { +191 points: null, +192 newPosition: null, // spare holder for getPosition coordinate return. +193 +194 applyAsPath : function(director) { +195 director.ctx.lineTo( this.points[0].x, this.points[1].y ); +196 }, +197 setPoint : function( point, index ) { +198 if ( index===0 ) { +199 this.points[0]= point; +200 } else if ( index===1 ) { +201 this.points[1]= point; +202 } 203 }, -204 setPoints : function( points ) { -205 this.points[0]= points[0]; -206 this.points[1]= points[1]; -207 this.updatePath(); -208 return this; -209 }, -210 /** -211 * Set this path segment's starting position. -212 * @param x {number} -213 * @param y {number} -214 */ -215 setInitialPosition : function( x, y ) { -216 this.points[0].x= x; -217 this.points[0].y= y; -218 this.newPosition.set(x,y); -219 return this; -220 }, -221 /** -222 * Set this path segment's ending position. -223 * @param finalX {number} -224 * @param finalY {number} -225 */ -226 setFinalPosition : function( finalX, finalY ) { -227 this.points[1].x= finalX; -228 this.points[1].y= finalY; -229 return this; -230 }, -231 /** -232 * @inheritDoc -233 */ -234 endCurvePosition : function() { -235 return this.points[1]; -236 }, -237 /** -238 * @inheritsDoc +204 /** +205 * Update this segments length and bounding box info. +206 */ +207 updatePath : function(point) { +208 var x= this.points[1].x - this.points[0].x; +209 var y= this.points[1].y - this.points[0].y; +210 this.length= Math.sqrt( x*x+y*y ); +211 +212 this.bbox.setEmpty(); +213 this.bbox.union( this.points[0].x, this.points[0].y ); +214 this.bbox.union( this.points[1].x, this.points[1].y ); +215 +216 return this; +217 }, +218 setPoints : function( points ) { +219 this.points[0]= points[0]; +220 this.points[1]= points[1]; +221 this.updatePath(); +222 return this; +223 }, +224 /** +225 * Set this path segment's starting position. +226 * @param x {number} +227 * @param y {number} +228 */ +229 setInitialPosition : function( x, y ) { +230 this.points[0].x= x; +231 this.points[0].y= y; +232 this.newPosition.set(x,y); +233 return this; +234 }, +235 /** +236 * Set this path segment's ending position. +237 * @param finalX {number} +238 * @param finalY {number} 239 */ -240 startCurvePosition : function() { -241 return this.points[0]; -242 }, -243 /** -244 * @inheritsDoc -245 */ -246 getPosition : function(time) { -247 -248 if ( time>1 || time<0 ) { -249 time%=1; -250 } -251 if ( time<0 ) { -252 time= 1+time; -253 } -254 -255 this.newPosition.set( -256 (this.points[0].x+(this.points[1].x-this.points[0].x)*time), -257 (this.points[0].y+(this.points[1].y-this.points[0].y)*time) ); -258 -259 return this.newPosition; -260 }, -261 /** -262 * Returns initial path segment point's x coordinate. -263 * @return {number} -264 */ -265 initialPositionX : function() { -266 return this.points[0].x; -267 }, -268 /** -269 * Returns final path segment point's x coordinate. -270 * @return {number} -271 */ -272 finalPositionX : function() { -273 return this.points[1].x; +240 setFinalPosition : function( finalX, finalY ) { +241 this.points[1].x= finalX; +242 this.points[1].y= finalY; +243 return this; +244 }, +245 /** +246 * @inheritDoc +247 */ +248 endCurvePosition : function() { +249 return this.points[1]; +250 }, +251 /** +252 * @inheritsDoc +253 */ +254 startCurvePosition : function() { +255 return this.points[0]; +256 }, +257 /** +258 * @inheritsDoc +259 */ +260 getPosition : function(time) { +261 +262 if ( time>1 || time<0 ) { +263 time%=1; +264 } +265 if ( time<0 ) { +266 time= 1+time; +267 } +268 +269 this.newPosition.set( +270 (this.points[0].x+(this.points[1].x-this.points[0].x)*time), +271 (this.points[0].y+(this.points[1].y-this.points[0].y)*time) ); +272 +273 return this.newPosition; 274 }, -275 /** -276 * Draws this path segment on screen. Optionally it can draw handles for every control point, in -277 * this case, start and ending path segment points. -278 * @param director {CAAT.Director} -279 * @param bDrawHandles {boolean} -280 */ -281 paint : function(director, bDrawHandles) { -282 -283 var canvas= director.crc; -284 -285 canvas.save(); -286 -287 canvas.strokeStyle= this.color; -288 canvas.beginPath(); -289 canvas.moveTo( this.points[0].x, this.points[0].y ); -290 canvas.lineTo( this.points[1].x, this.points[1].y ); -291 canvas.stroke(); -292 -293 if ( bDrawHandles ) { -294 canvas.globalAlpha=0.5; -295 canvas.fillStyle='#7f7f00'; -296 canvas.beginPath(); -297 canvas.arc( -298 this.points[0].x, -299 this.points[0].y, -300 CAAT.Curve.prototype.HANDLE_SIZE/2, -301 0, -302 2*Math.PI, -303 false) ; -304 canvas.arc( -305 this.points[1].x, -306 this.points[1].y, -307 CAAT.Curve.prototype.HANDLE_SIZE/2, -308 0, -309 2*Math.PI, -310 false) ; -311 canvas.fill(); -312 } -313 -314 canvas.restore(); -315 }, -316 /** -317 * Get the number of control points. For this type of path segment, start and -318 * ending path segment points. Defaults to 2. -319 * @return {number} -320 */ -321 numControlPoints : function() { -322 return 2; -323 }, -324 /** -325 * @inheritsDoc -326 */ -327 getControlPoint: function(index) { -328 if ( 0===index ) { -329 return this.points[0]; -330 } else if (1===index) { -331 return this.points[1]; -332 } -333 }, -334 /** -335 * @inheritsDoc -336 */ -337 getContour : function(iSize) { -338 var contour= []; -339 -340 contour.push( this.getPosition(0).clone() ); -341 contour.push( this.getPosition(1).clone() ); -342 -343 return contour; -344 } -345 }; -346 -347 extend( CAAT.LinearPath, CAAT.PathSegment ); -348 })(); -349 -350 (function() { -351 /** -352 * This class defines a Bezier cubic or quadric path segment. -353 * -354 * @constructor -355 * @extends CAAT.PathSegment -356 */ -357 CAAT.CurvePath = function() { -358 CAAT.CurvePath.superclass.constructor.call(this); -359 this.newPosition= new CAAT.Point(0,0,0); -360 return this; -361 }; -362 -363 CAAT.CurvePath.prototype= { -364 curve: null, // a CAAT.Bezier instance. -365 newPosition: null, // spare holder for getPosition coordinate return. -366 -367 applyAsPath : function(director) { -368 this.curve.applyAsPath(director); -369 return this; -370 }, -371 setPoint : function( point, index ) { -372 if ( this.curve ) { -373 this.curve.setPoint(point,index); -374 } -375 }, -376 /** -377 * Set this curve segment's points. -378 * @param points {Array<CAAT.Point>} -379 */ -380 setPoints : function( points ) { -381 var curve = new CAAT.Bezier(); -382 curve.setPoints(points); -383 this.curve = curve; -384 return this; -385 }, -386 /** -387 * Set the pathSegment as a CAAT.Bezier quadric instance. -388 * Parameters are quadric coordinates control points. -389 * -390 * @param p0x {number} -391 * @param p0y {number} -392 * @param p1x {number} -393 * @param p1y {number} -394 * @param p2x {number} -395 * @param p2y {number} -396 * @return this -397 */ -398 setQuadric : function(p0x,p0y, p1x,p1y, p2x,p2y) { -399 var curve = new CAAT.Bezier(); -400 curve.setQuadric(p0x,p0y, p1x,p1y, p2x,p2y); -401 this.curve = curve; -402 this.updatePath(); -403 -404 return this; -405 }, -406 /** -407 * Set the pathSegment as a CAAT.Bezier cubic instance. -408 * Parameters are cubic coordinates control points. -409 * @param p0x {number} -410 * @param p0y {number} -411 * @param p1x {number} -412 * @param p1y {number} -413 * @param p2x {number} -414 * @param p2y {number} -415 * @param p3x {number} -416 * @param p3y {number} +275 getPositionFromLength : function( len ) { +276 return this.getPosition( len/this.length ); +277 }, +278 /** +279 * Returns initial path segment point's x coordinate. +280 * @return {number} +281 */ +282 initialPositionX : function() { +283 return this.points[0].x; +284 }, +285 /** +286 * Returns final path segment point's x coordinate. +287 * @return {number} +288 */ +289 finalPositionX : function() { +290 return this.points[1].x; +291 }, +292 /** +293 * Draws this path segment on screen. Optionally it can draw handles for every control point, in +294 * this case, start and ending path segment points. +295 * @param director {CAAT.Director} +296 * @param bDrawHandles {boolean} +297 */ +298 paint : function(director, bDrawHandles) { +299 +300 var ctx= director.ctx; +301 +302 ctx.save(); +303 +304 ctx.strokeStyle= this.color; +305 ctx.beginPath(); +306 ctx.moveTo( this.points[0].x, this.points[0].y ); +307 ctx.lineTo( this.points[1].x, this.points[1].y ); +308 ctx.stroke(); +309 +310 if ( bDrawHandles ) { +311 ctx.globalAlpha=0.5; +312 ctx.fillStyle='#7f7f00'; +313 ctx.beginPath(); +314 this.drawHandle( ctx, this.points[0].x, this.points[0].y ); +315 this.drawHandle( ctx, this.points[1].x, this.points[1].y ); +316 /* +317 canvas.arc( +318 this.points[0].x, +319 this.points[0].y, +320 CAAT.Curve.prototype.HANDLE_SIZE/2, +321 0, +322 2*Math.PI, +323 false) ; +324 canvas.arc( +325 this.points[1].x, +326 this.points[1].y, +327 CAAT.Curve.prototype.HANDLE_SIZE/2, +328 0, +329 2*Math.PI, +330 false) ; +331 canvas.fill(); +332 */ +333 } +334 +335 ctx.restore(); +336 }, +337 /** +338 * Get the number of control points. For this type of path segment, start and +339 * ending path segment points. Defaults to 2. +340 * @return {number} +341 */ +342 numControlPoints : function() { +343 return 2; +344 }, +345 /** +346 * @inheritsDoc +347 */ +348 getControlPoint: function(index) { +349 if ( 0===index ) { +350 return this.points[0]; +351 } else if (1===index) { +352 return this.points[1]; +353 } +354 }, +355 /** +356 * @inheritsDoc +357 */ +358 getContour : function(iSize) { +359 var contour= []; +360 +361 contour.push( this.getPosition(0).clone() ); +362 contour.push( this.getPosition(1).clone() ); +363 +364 return contour; +365 } +366 }; +367 +368 extend( CAAT.LinearPath, CAAT.PathSegment ); +369 })(); +370 +371 (function() { +372 /** +373 * This class defines a Bezier cubic or quadric path segment. +374 * +375 * @constructor +376 * @extends CAAT.PathSegment +377 */ +378 CAAT.CurvePath = function() { +379 CAAT.CurvePath.superclass.constructor.call(this); +380 this.newPosition= new CAAT.Point(0,0,0); +381 return this; +382 }; +383 +384 CAAT.CurvePath.prototype= { +385 curve: null, // a CAAT.Bezier instance. +386 newPosition: null, // spare holder for getPosition coordinate return. +387 +388 applyAsPath : function(director) { +389 this.curve.applyAsPath(director); +390 return this; +391 }, +392 setPoint : function( point, index ) { +393 if ( this.curve ) { +394 this.curve.setPoint(point,index); +395 } +396 }, +397 /** +398 * Set this curve segment's points. +399 * @param points {Array<CAAT.Point>} +400 */ +401 setPoints : function( points ) { +402 var curve = new CAAT.Bezier(); +403 curve.setPoints(points); +404 this.curve = curve; +405 return this; +406 }, +407 /** +408 * Set the pathSegment as a CAAT.Bezier quadric instance. +409 * Parameters are quadric coordinates control points. +410 * +411 * @param p0x {number} +412 * @param p0y {number} +413 * @param p1x {number} +414 * @param p1y {number} +415 * @param p2x {number} +416 * @param p2y {number} 417 * @return this 418 */ -419 setCubic : function(p0x,p0y, p1x,p1y, p2x,p2y, p3x,p3y) { +419 setQuadric : function(p0x,p0y, p1x,p1y, p2x,p2y) { 420 var curve = new CAAT.Bezier(); -421 curve.setCubic(p0x,p0y, p1x,p1y, p2x,p2y, p3x,p3y); +421 curve.setQuadric(p0x,p0y, p1x,p1y, p2x,p2y); 422 this.curve = curve; 423 this.updatePath(); 424 425 return this; 426 }, 427 /** -428 * @inheritDoc -429 */ -430 updatePath : function(point) { -431 this.curve.update(); -432 this.length= this.curve.getLength(); -433 this.curve.getBoundingBox(this.bbox); -434 return this; -435 }, -436 /** -437 * @inheritDoc -438 */ -439 getPosition : function(time) { -440 -441 if ( time>1 || time<0 ) { -442 time%=1; -443 } -444 if ( time<0 ) { -445 time= 1+time; -446 } -447 -448 this.curve.solve(this.newPosition, time); -449 -450 return this.newPosition; -451 }, -452 /** -453 * Gets the coordinate on the path relative to the path length. -454 * @param iLength {number} the length at which the coordinate will be taken from. -455 * @return {CAAT.Point} a CAAT.Point instance with the coordinate on the path corresponding to the -456 * iLenght parameter relative to segment's length. -457 */ -458 getPositionFromLength : function(iLength) { -459 this.curve.solve( this.newPosition, iLength/this.length ); -460 return this.newPosition; -461 }, -462 /** -463 * Get path segment's first point's x coordinate. -464 * @return {number} -465 */ -466 initialPositionX : function() { -467 return this.curve.coordlist[0].x; -468 }, -469 /** -470 * Get path segment's last point's y coordinate. -471 * @return {number} -472 */ -473 finalPositionX : function() { -474 return this.curve.coordlist[this.curve.coordlist.length-1].x; -475 }, -476 /** -477 * @inheritDoc -478 * @param director {CAAT.Director} -479 * @param bDrawHandles {boolean} -480 */ -481 paint : function( director,bDrawHandles ) { -482 this.curve.drawHandles= bDrawHandles; -483 director.ctx.strokeStyle= this.color; -484 this.curve.paint(director); -485 }, -486 /** -487 * @inheritDoc -488 */ -489 numControlPoints : function() { -490 return this.curve.coordlist.length; -491 }, -492 /** -493 * @inheritDoc -494 * @param index -495 */ -496 getControlPoint : function(index) { -497 return this.curve.coordlist[index]; -498 }, -499 /** -500 * @inheritDoc +428 * Set the pathSegment as a CAAT.Bezier cubic instance. +429 * Parameters are cubic coordinates control points. +430 * @param p0x {number} +431 * @param p0y {number} +432 * @param p1x {number} +433 * @param p1y {number} +434 * @param p2x {number} +435 * @param p2y {number} +436 * @param p3x {number} +437 * @param p3y {number} +438 * @return this +439 */ +440 setCubic : function(p0x,p0y, p1x,p1y, p2x,p2y, p3x,p3y) { +441 var curve = new CAAT.Bezier(); +442 curve.setCubic(p0x,p0y, p1x,p1y, p2x,p2y, p3x,p3y); +443 this.curve = curve; +444 this.updatePath(); +445 +446 return this; +447 }, +448 /** +449 * @inheritDoc +450 */ +451 updatePath : function(point) { +452 this.curve.update(); +453 this.length= this.curve.getLength(); +454 this.curve.getBoundingBox(this.bbox); +455 return this; +456 }, +457 /** +458 * @inheritDoc +459 */ +460 getPosition : function(time) { +461 +462 if ( time>1 || time<0 ) { +463 time%=1; +464 } +465 if ( time<0 ) { +466 time= 1+time; +467 } +468 +469 this.curve.solve(this.newPosition, time); +470 +471 return this.newPosition; +472 }, +473 /** +474 * Gets the coordinate on the path relative to the path length. +475 * @param iLength {number} the length at which the coordinate will be taken from. +476 * @return {CAAT.Point} a CAAT.Point instance with the coordinate on the path corresponding to the +477 * iLenght parameter relative to segment's length. +478 */ +479 getPositionFromLength : function(iLength) { +480 this.curve.solve( this.newPosition, iLength/this.length ); +481 return this.newPosition; +482 }, +483 /** +484 * Get path segment's first point's x coordinate. +485 * @return {number} +486 */ +487 initialPositionX : function() { +488 return this.curve.coordlist[0].x; +489 }, +490 /** +491 * Get path segment's last point's y coordinate. +492 * @return {number} +493 */ +494 finalPositionX : function() { +495 return this.curve.coordlist[this.curve.coordlist.length-1].x; +496 }, +497 /** +498 * @inheritDoc +499 * @param director {CAAT.Director} +500 * @param bDrawHandles {boolean} 501 */ -502 endCurvePosition : function() { -503 return this.curve.endCurvePosition(); -504 }, -505 /** -506 * @inheritDoc -507 */ -508 startCurvePosition : function() { -509 return this.curve.startCurvePosition(); -510 }, -511 /** -512 * @inheritDoc -513 * @param iSize -514 */ -515 getContour : function(iSize) { -516 var contour=[]; -517 for( var i=0; i<=iSize; i++ ) { -518 contour.push( {x: i/iSize, y: this.getPosition(i/iSize).y} ); -519 } -520 -521 return contour; -522 } -523 }; -524 -525 extend( CAAT.CurvePath, CAAT.PathSegment, null); -526 -527 })(); -528 -529 (function() { -530 -531 CAAT.ShapePath= function() { -532 CAAT.ShapePath.superclass.constructor.call(this); -533 -534 this.points= []; -535 this.points.push( new CAAT.Point() ); -536 this.points.push( new CAAT.Point() ); -537 this.points.push( new CAAT.Point() ); -538 this.points.push( new CAAT.Point() ); -539 this.points.push( new CAAT.Point() ); -540 -541 this.newPosition= new CAAT.Point(); -542 -543 return this; -544 }; +502 paint : function( director,bDrawHandles ) { +503 this.curve.drawHandles= bDrawHandles; +504 director.ctx.strokeStyle= this.color; +505 this.curve.paint(director,bDrawHandles); +506 }, +507 /** +508 * @inheritDoc +509 */ +510 numControlPoints : function() { +511 return this.curve.coordlist.length; +512 }, +513 /** +514 * @inheritDoc +515 * @param index +516 */ +517 getControlPoint : function(index) { +518 return this.curve.coordlist[index]; +519 }, +520 /** +521 * @inheritDoc +522 */ +523 endCurvePosition : function() { +524 return this.curve.endCurvePosition(); +525 }, +526 /** +527 * @inheritDoc +528 */ +529 startCurvePosition : function() { +530 return this.curve.startCurvePosition(); +531 }, +532 /** +533 * @inheritDoc +534 * @param iSize +535 */ +536 getContour : function(iSize) { +537 var contour=[]; +538 for( var i=0; i<=iSize; i++ ) { +539 contour.push( {x: i/iSize, y: this.getPosition(i/iSize).y} ); +540 } +541 +542 return contour; +543 } +544 }; 545 -546 CAAT.ShapePath.prototype= { -547 points: null, -548 length: -1, -549 cw: true, // should be clock wise traversed ? -550 bbox: null, -551 newPosition: null, // spare point for calculations -552 -553 applyAsPath : function(director) { -554 var ctx= director.ctx; -555 //ctx.rect( this.bbox.x, this.bbox.y, this.bbox.width, this.bbox.height ); -556 if ( this.cw ) { -557 ctx.lineTo( this.points[0].x, this.points[0].y ); -558 ctx.lineTo( this.points[1].x, this.points[1].y ); -559 ctx.lineTo( this.points[2].x, this.points[2].y ); -560 ctx.lineTo( this.points[3].x, this.points[3].y ); -561 ctx.lineTo( this.points[4].x, this.points[4].y ); -562 } else { -563 ctx.lineTo( this.points[4].x, this.points[4].y ); -564 ctx.lineTo( this.points[3].x, this.points[3].y ); -565 ctx.lineTo( this.points[2].x, this.points[2].y ); -566 ctx.lineTo( this.points[1].x, this.points[1].y ); -567 ctx.lineTo( this.points[0].x, this.points[0].y ); -568 } -569 return this; -570 }, -571 setPoint : function( point, index ) { -572 if ( index>=0 && index<this.points.length ) { -573 this.points[index]= point; -574 } -575 }, -576 /** -577 * An array of {CAAT.Point} composed of two points. -578 * @param points {Array<CAAT.Point>} -579 */ -580 setPoints : function( points ) { -581 this.points= []; -582 this.points.push( points[0] ); -583 this.points.push( new CAAT.Point().set(points[1].x, points[0].y) ); -584 this.points.push( points[1] ); -585 this.points.push( new CAAT.Point().set(points[0].x, points[1].y) ); -586 this.points.push( points[0].clone() ); -587 this.updatePath(); -588 -589 return this; -590 }, -591 setClockWise : function(cw) { -592 this.cw= cw!==undefined ? cw : true; -593 return this; -594 }, -595 isClockWise : function() { -596 return this.cw; -597 }, -598 /** -599 * Set this path segment's starting position. -600 * This method should not be called again after setFinalPosition has been called. -601 * @param x {number} -602 * @param y {number} -603 */ -604 setInitialPosition : function( x, y ) { -605 for( var i=0, l= this.points.length; i<l; i++ ) { -606 this.points[i].x= x; -607 this.points[i].y= y; -608 } -609 return this; -610 }, -611 /** -612 * Set a rectangle from points[0] to (finalX, finalY) -613 * @param finalX {number} -614 * @param finalY {number} -615 */ -616 setFinalPosition : function( finalX, finalY ) { -617 this.points[2].x= finalX; -618 this.points[2].y= finalY; -619 -620 this.points[1].x= finalX; -621 this.points[1].y= this.points[0].y; -622 -623 this.points[3].x= this.points[0].x; -624 this.points[3].y= finalY; -625 -626 this.points[4].x= this.points[0].x; -627 this.points[4].y= this.points[0].y; -628 -629 this.updatePath(); +546 extend( CAAT.CurvePath, CAAT.PathSegment, null); +547 +548 })(); +549 +550 (function() { +551 +552 CAAT.ShapePath= function() { +553 CAAT.ShapePath.superclass.constructor.call(this); +554 +555 this.points= []; +556 this.points.push( new CAAT.Point() ); +557 this.points.push( new CAAT.Point() ); +558 this.points.push( new CAAT.Point() ); +559 this.points.push( new CAAT.Point() ); +560 this.points.push( new CAAT.Point() ); +561 +562 this.newPosition= new CAAT.Point(); +563 +564 return this; +565 }; +566 +567 CAAT.ShapePath.prototype= { +568 points: null, +569 length: -1, +570 cw: true, // should be clock wise traversed ? +571 bbox: null, +572 newPosition: null, // spare point for calculations +573 +574 applyAsPath : function(director) { +575 var ctx= director.ctx; +576 //ctx.rect( this.bbox.x, this.bbox.y, this.bbox.width, this.bbox.height ); +577 if ( this.cw ) { +578 ctx.lineTo( this.points[0].x, this.points[0].y ); +579 ctx.lineTo( this.points[1].x, this.points[1].y ); +580 ctx.lineTo( this.points[2].x, this.points[2].y ); +581 ctx.lineTo( this.points[3].x, this.points[3].y ); +582 ctx.lineTo( this.points[4].x, this.points[4].y ); +583 } else { +584 ctx.lineTo( this.points[4].x, this.points[4].y ); +585 ctx.lineTo( this.points[3].x, this.points[3].y ); +586 ctx.lineTo( this.points[2].x, this.points[2].y ); +587 ctx.lineTo( this.points[1].x, this.points[1].y ); +588 ctx.lineTo( this.points[0].x, this.points[0].y ); +589 } +590 return this; +591 }, +592 setPoint : function( point, index ) { +593 if ( index>=0 && index<this.points.length ) { +594 this.points[index]= point; +595 } +596 }, +597 /** +598 * An array of {CAAT.Point} composed of two points. +599 * @param points {Array<CAAT.Point>} +600 */ +601 setPoints : function( points ) { +602 this.points= []; +603 this.points.push( points[0] ); +604 this.points.push( new CAAT.Point().set(points[1].x, points[0].y) ); +605 this.points.push( points[1] ); +606 this.points.push( new CAAT.Point().set(points[0].x, points[1].y) ); +607 this.points.push( points[0].clone() ); +608 this.updatePath(); +609 +610 return this; +611 }, +612 setClockWise : function(cw) { +613 this.cw= cw!==undefined ? cw : true; +614 return this; +615 }, +616 isClockWise : function() { +617 return this.cw; +618 }, +619 /** +620 * Set this path segment's starting position. +621 * This method should not be called again after setFinalPosition has been called. +622 * @param x {number} +623 * @param y {number} +624 */ +625 setInitialPosition : function( x, y ) { +626 for( var i=0, l= this.points.length; i<l; i++ ) { +627 this.points[i].x= x; +628 this.points[i].y= y; +629 } 630 return this; 631 }, 632 /** -633 * @inheritDoc -634 */ -635 endCurvePosition : function() { -636 return this.points[4]; -637 }, -638 /** -639 * @inheritsDoc -640 */ -641 startCurvePosition : function() { -642 return this.points[0]; -643 }, -644 /** -645 * @inheritsDoc -646 */ -647 getPosition : function(time) { -648 -649 if ( time>1 || time<0 ) { -650 time%=1; -651 } -652 if ( time<0 ) { -653 time= 1+time; -654 } -655 -656 if ( -1===this.length ) { -657 this.newPosition.set(0,0); -658 } else { -659 var w= this.bbox.width / this.length; -660 var h= this.bbox.height / this.length; -661 var accTime= 0; -662 var times; -663 var segments; -664 var index= 0; -665 -666 if ( this.cw ) { -667 segments= [0,1,2,3,4]; -668 times= [w,h,w,h]; -669 } else { -670 segments= [4,3,2,1,0]; -671 times= [h,w,h,w]; -672 } -673 -674 while( index<times.length ) { -675 if ( accTime+times[index]<time ) { -676 accTime+= times[index]; -677 index++; -678 } else { -679 break; -680 } -681 } -682 time-=accTime; -683 -684 var p0= segments[index]; -685 var p1= segments[index+1]; +633 * Set a rectangle from points[0] to (finalX, finalY) +634 * @param finalX {number} +635 * @param finalY {number} +636 */ +637 setFinalPosition : function( finalX, finalY ) { +638 this.points[2].x= finalX; +639 this.points[2].y= finalY; +640 +641 this.points[1].x= finalX; +642 this.points[1].y= this.points[0].y; +643 +644 this.points[3].x= this.points[0].x; +645 this.points[3].y= finalY; +646 +647 this.points[4].x= this.points[0].x; +648 this.points[4].y= this.points[0].y; +649 +650 this.updatePath(); +651 return this; +652 }, +653 /** +654 * @inheritDoc +655 */ +656 endCurvePosition : function() { +657 return this.points[4]; +658 }, +659 /** +660 * @inheritsDoc +661 */ +662 startCurvePosition : function() { +663 return this.points[0]; +664 }, +665 /** +666 * @inheritsDoc +667 */ +668 getPosition : function(time) { +669 +670 if ( time>1 || time<0 ) { +671 time%=1; +672 } +673 if ( time<0 ) { +674 time= 1+time; +675 } +676 +677 if ( -1===this.length ) { +678 this.newPosition.set(0,0); +679 } else { +680 var w= this.bbox.width / this.length; +681 var h= this.bbox.height / this.length; +682 var accTime= 0; +683 var times; +684 var segments; +685 var index= 0; 686 -687 // index tiene el indice del segmento en tiempo. -688 this.newPosition.set( -689 (this.points[p0].x + (this.points[p1].x - this.points[p0].x)*time/times[index]), -690 (this.points[p0].y + (this.points[p1].y - this.points[p0].y)*time/times[index]) ); -691 } -692 -693 return this.newPosition; -694 }, -695 /** -696 * Returns initial path segment point's x coordinate. -697 * @return {number} -698 */ -699 initialPositionX : function() { -700 return this.points[0].x; -701 }, -702 /** -703 * Returns final path segment point's x coordinate. -704 * @return {number} -705 */ -706 finalPositionX : function() { -707 return this.points[2].x; -708 }, -709 /** -710 * Draws this path segment on screen. Optionally it can draw handles for every control point, in -711 * this case, start and ending path segment points. -712 * @param director {CAAT.Director} -713 * @param bDrawHandles {boolean} -714 */ -715 paint : function(director, bDrawHandles) { -716 -717 var canvas= director.crc; -718 -719 canvas.save(); -720 -721 canvas.strokeStyle= this.color; -722 canvas.beginPath(); -723 canvas.strokeRect( -724 this.bbox.x, this.bbox.y, -725 this.bbox.width, this.bbox.height ); -726 -727 if ( bDrawHandles ) { -728 canvas.globalAlpha=0.5; -729 canvas.fillStyle='#7f7f00'; -730 -731 for( var i=0; i<this.points.length; i++ ) { -732 canvas.beginPath(); -733 canvas.arc( -734 this.points[i].x, -735 this.points[i].y, -736 CAAT.Curve.prototype.HANDLE_SIZE/2, -737 0, -738 2*Math.PI, -739 false) ; -740 canvas.fill(); -741 } -742 -743 } -744 -745 canvas.restore(); -746 }, -747 /** -748 * Get the number of control points. For this type of path segment, start and -749 * ending path segment points. Defaults to 2. -750 * @return {number} -751 */ -752 numControlPoints : function() { -753 return this.points.length; -754 }, -755 /** -756 * @inheritsDoc -757 */ -758 getControlPoint: function(index) { -759 return this.points[index]; -760 }, -761 /** -762 * @inheritsDoc -763 */ -764 getContour : function(iSize) { -765 var contour= []; +687 if ( this.cw ) { +688 segments= [0,1,2,3,4]; +689 times= [w,h,w,h]; +690 } else { +691 segments= [4,3,2,1,0]; +692 times= [h,w,h,w]; +693 } +694 +695 while( index<times.length ) { +696 if ( accTime+times[index]<time ) { +697 accTime+= times[index]; +698 index++; +699 } else { +700 break; +701 } +702 } +703 time-=accTime; +704 +705 var p0= segments[index]; +706 var p1= segments[index+1]; +707 +708 // index tiene el indice del segmento en tiempo. +709 this.newPosition.set( +710 (this.points[p0].x + (this.points[p1].x - this.points[p0].x)*time/times[index]), +711 (this.points[p0].y + (this.points[p1].y - this.points[p0].y)*time/times[index]) ); +712 } +713 +714 return this.newPosition; +715 }, +716 /** +717 * Returns initial path segment point's x coordinate. +718 * @return {number} +719 */ +720 initialPositionX : function() { +721 return this.points[0].x; +722 }, +723 /** +724 * Returns final path segment point's x coordinate. +725 * @return {number} +726 */ +727 finalPositionX : function() { +728 return this.points[2].x; +729 }, +730 /** +731 * Draws this path segment on screen. Optionally it can draw handles for every control point, in +732 * this case, start and ending path segment points. +733 * @param director {CAAT.Director} +734 * @param bDrawHandles {boolean} +735 */ +736 paint : function(director, bDrawHandles) { +737 +738 var ctx= director.ctx; +739 +740 ctx.save(); +741 +742 ctx.strokeStyle= this.color; +743 ctx.beginPath(); +744 ctx.strokeRect( +745 this.bbox.x, this.bbox.y, +746 this.bbox.width, this.bbox.height ); +747 +748 if ( bDrawHandles ) { +749 ctx.globalAlpha=0.5; +750 ctx.fillStyle='#7f7f00'; +751 +752 for( var i=0; i<this.points.length; i++ ) { +753 this.drawHandle( ctx, this.points[i].x, this.points[i].y ); +754 /* +755 canvas.beginPath(); +756 canvas.arc( +757 this.points[i].x, +758 this.points[i].y, +759 CAAT.Curve.prototype.HANDLE_SIZE/2, +760 0, +761 2*Math.PI, +762 false) ; +763 canvas.fill(); +764 */ +765 } 766 -767 for( var i=0; i<this.points.length; i++ ) { -768 contour.push( this.points[i] ); -769 } -770 -771 return contour; -772 }, -773 updatePath : function(point) { -774 -775 if ( point ) { -776 if ( point===this.points[0] ) { -777 this.points[1].y= point.y; -778 this.points[3].x= point.x; -779 } else if ( point===this.points[1] ) { -780 this.points[0].y= point.y; -781 this.points[2].x= point.x; -782 } else if ( point===this.points[2] ) { -783 this.points[3].y= point.y; -784 this.points[1].x= point.x; -785 } else if ( point===this.points[3] ) { -786 this.points[0].x= point.x; -787 this.points[2].y= point.y; -788 } -789 this.points[4].x= this.points[0].x; -790 this.points[4].y= this.points[0].y; -791 } -792 -793 this.bbox.setEmpty(); -794 var minx= Number.MAX_VALUE, miny= Number.MAX_VALUE, maxx= -Number.MAX_VALUE, maxy= -Number.MAX_VALUE; -795 for( var i=0; i<4; i++ ) { -796 this.bbox.union( this.points[i].x, this.points[i].y ); -797 } +767 } +768 +769 ctx.restore(); +770 }, +771 /** +772 * Get the number of control points. For this type of path segment, start and +773 * ending path segment points. Defaults to 2. +774 * @return {number} +775 */ +776 numControlPoints : function() { +777 return this.points.length; +778 }, +779 /** +780 * @inheritsDoc +781 */ +782 getControlPoint: function(index) { +783 return this.points[index]; +784 }, +785 /** +786 * @inheritsDoc +787 */ +788 getContour : function(iSize) { +789 var contour= []; +790 +791 for( var i=0; i<this.points.length; i++ ) { +792 contour.push( this.points[i] ); +793 } +794 +795 return contour; +796 }, +797 updatePath : function(point) { 798 -799 this.length= 2*this.bbox.width + 2*this.bbox.height; -800 -801 this.points[0].x= this.bbox.x; -802 this.points[0].y= this.bbox.y; -803 -804 this.points[1].x= this.bbox.x+this.bbox.width; -805 this.points[1].y= this.bbox.y; -806 -807 this.points[2].x= this.bbox.x + this.bbox.width; -808 this.points[2].y= this.bbox.y + this.bbox.height; -809 -810 this.points[3].x= this.bbox.x; -811 this.points[3].y= this.bbox.y + this.bbox.height; -812 -813 this.points[4].x= this.bbox.x; -814 this.points[4].y= this.bbox.y; -815 -816 return this; -817 } -818 } -819 -820 extend( CAAT.ShapePath, CAAT.PathSegment ); -821 -822 })(); -823 -824 (function() { -825 -826 /** -827 * This class the top most abstraction of path related classes in CAAT. It defines a path composes un -828 * an unlimited number of path segments including CAAT.Path instances. -829 * <p> -830 * Every operation of the CAAT.PathSegment interface is performed for every path segment. In example, -831 * the method <code>getLength</code> will contain the sum of every path segment's length. -832 * <p> -833 * An example of CAAT.Path will be as follows: -834 -835 * <code> -836 * path.beginPath(x,y).<br> -837 *   addLineTo(x1,y1).<br> -838 *   addLineTo(x2,y2).<br> -839 *   addQuadricTo(...).<br> -840 *   addCubicTo(...).<br> -841 *   endPath();<br> -842 * </code> -843 * <p> -844 * This code creates a path composed of four chained segments, starting at (x,y) and having each -845 * segment starting where the previous one ended. -846 * <p> -847 * This class is intended to wrap the other kind of path segment classes when just a one segmented -848 * path is to be defined. The methods <code>setLinear, setCubic and setQuadrid</code> will make -849 * a CAAT.Path instance to be defined by just one segment. -850 * -851 * @constructor -852 * @extends CAAT.PathSegment -853 */ -854 CAAT.Path= function() { -855 CAAT.Path.superclass.constructor.call(this); -856 -857 this.newPosition= new CAAT.Point(0,0,0); -858 this.pathSegments= []; -859 -860 this.behaviorList= []; -861 this.matrix= new CAAT.Matrix(); -862 this.tmpMatrix= new CAAT.Matrix(); -863 -864 return this; -865 }; -866 -867 CAAT.Path.prototype= { -868 -869 pathSegments: null, // a collection of CAAT.PathSegment instances. -870 pathSegmentDurationTime: null, // precomputed segment duration relative to segment legnth/path length -871 pathSegmentStartTime: null, // precomputed segment start time relative to segment legnth/path length and duration. -872 -873 newPosition: null, // spare CAAT.Point. -874 -875 pathLength: -1, // path length (sum of every segment length) -876 -877 /* -878 starting path position -879 */ -880 beginPathX: -1, -881 beginPathY: -1, -882 -883 /* -884 last path coordinates position (using when building the path). -885 */ -886 trackPathX: -1, -887 trackPathY: -1, -888 -889 /* -890 needed to drag control points. -891 */ -892 ax: -1, -893 ay: -1, -894 point: [], -895 -896 interactive: true, -897 -898 behaviorList: null, -899 -900 /** rotation behavior info **/ -901 rb_angle: 0, -902 rb_rotateAnchorX: .5, -903 rb_rotateAnchorY: .5, -904 -905 /** scale behavior info **/ -906 sb_scaleX: 1, -907 sb_scaleY: 1, -908 sb_scaleAnchorX: .5, -909 sb_scaleAnchorY: .5, -910 -911 tAnchorX: 0, -912 tAnchorY: 0, -913 -914 /** translate behavior info **/ -915 tb_x: 0, -916 tb_y: 0, -917 -918 /** behavior affine transformation matrix **/ -919 matrix: null, -920 tmpMatrix: null, +799 if ( point ) { +800 if ( point===this.points[0] ) { +801 this.points[1].y= point.y; +802 this.points[3].x= point.x; +803 } else if ( point===this.points[1] ) { +804 this.points[0].y= point.y; +805 this.points[2].x= point.x; +806 } else if ( point===this.points[2] ) { +807 this.points[3].y= point.y; +808 this.points[1].x= point.x; +809 } else if ( point===this.points[3] ) { +810 this.points[0].x= point.x; +811 this.points[2].y= point.y; +812 } +813 this.points[4].x= this.points[0].x; +814 this.points[4].y= this.points[0].y; +815 } +816 +817 this.bbox.setEmpty(); +818 var minx= Number.MAX_VALUE, miny= Number.MAX_VALUE, maxx= -Number.MAX_VALUE, maxy= -Number.MAX_VALUE; +819 for( var i=0; i<4; i++ ) { +820 this.bbox.union( this.points[i].x, this.points[i].y ); +821 } +822 +823 this.length= 2*this.bbox.width + 2*this.bbox.height; +824 +825 this.points[0].x= this.bbox.x; +826 this.points[0].y= this.bbox.y; +827 +828 this.points[1].x= this.bbox.x+this.bbox.width; +829 this.points[1].y= this.bbox.y; +830 +831 this.points[2].x= this.bbox.x + this.bbox.width; +832 this.points[2].y= this.bbox.y + this.bbox.height; +833 +834 this.points[3].x= this.bbox.x; +835 this.points[3].y= this.bbox.y + this.bbox.height; +836 +837 this.points[4].x= this.bbox.x; +838 this.points[4].y= this.bbox.y; +839 +840 return this; +841 } +842 } +843 +844 extend( CAAT.ShapePath, CAAT.PathSegment ); +845 +846 })(); +847 +848 (function() { +849 +850 /** +851 * This class the top most abstraction of path related classes in CAAT. It defines a path composes un +852 * an unlimited number of path segments including CAAT.Path instances. +853 * <p> +854 * Every operation of the CAAT.PathSegment interface is performed for every path segment. In example, +855 * the method <code>getLength</code> will contain the sum of every path segment's length. +856 * <p> +857 * An example of CAAT.Path will be as follows: +858 +859 * <code> +860 * path.beginPath(x,y).<br> +861 *   addLineTo(x1,y1).<br> +862 *   addLineTo(x2,y2).<br> +863 *   addQuadricTo(...).<br> +864 *   addCubicTo(...).<br> +865 *   endPath();<br> +866 * </code> +867 * <p> +868 * This code creates a path composed of four chained segments, starting at (x,y) and having each +869 * segment starting where the previous one ended. +870 * <p> +871 * This class is intended to wrap the other kind of path segment classes when just a one segmented +872 * path is to be defined. The methods <code>setLinear, setCubic and setQuadrid</code> will make +873 * a CAAT.Path instance to be defined by just one segment. +874 * +875 * @constructor +876 * @extends CAAT.PathSegment +877 */ +878 CAAT.Path= function() { +879 CAAT.Path.superclass.constructor.call(this); +880 +881 this.newPosition= new CAAT.Point(0,0,0); +882 this.pathSegments= []; +883 +884 this.behaviorList= []; +885 this.matrix= new CAAT.Matrix(); +886 this.tmpMatrix= new CAAT.Matrix(); +887 +888 return this; +889 }; +890 +891 CAAT.Path.prototype= { +892 +893 pathSegments: null, // a collection of CAAT.PathSegment instances. +894 pathSegmentDurationTime: null, // precomputed segment duration relative to segment legnth/path length +895 pathSegmentStartTime: null, // precomputed segment start time relative to segment legnth/path length and duration. +896 +897 newPosition: null, // spare CAAT.Point. +898 +899 pathLength: -1, // path length (sum of every segment length) +900 +901 /* +902 starting path position +903 */ +904 beginPathX: -1, +905 beginPathY: -1, +906 +907 /* +908 last path coordinates position (using when building the path). +909 */ +910 trackPathX: -1, +911 trackPathY: -1, +912 +913 /* +914 needed to drag control points. +915 */ +916 ax: -1, +917 ay: -1, +918 point: [], +919 +920 interactive: true, 921 -922 /** if behaviors are to be applied, save original path points **/ -923 pathPoints: null, -924 -925 /** path width and height **/ -926 width: 0, -927 height: 0, +922 behaviorList: null, +923 +924 /** rotation behavior info **/ +925 rb_angle: 0, +926 rb_rotateAnchorX: .5, +927 rb_rotateAnchorY: .5, 928 -929 clipOffsetX : 0, -930 clipOffsetY : 0, -931 -932 applyAsPath : function(director) { -933 var ctx= director.ctx; +929 /** scale behavior info **/ +930 sb_scaleX: 1, +931 sb_scaleY: 1, +932 sb_scaleAnchorX: .5, +933 sb_scaleAnchorY: .5, 934 -935 director.modelViewMatrix.transformRenderingContext( ctx ); -936 ctx.beginPath(); -937 ctx.globalCompositeOperation= 'source-out'; -938 ctx.moveTo( -939 this.getFirstPathSegment().startCurvePosition().x, -940 this.getFirstPathSegment().startCurvePosition().y -941 ); -942 for( var i=0; i<this.pathSegments.length; i++ ) { -943 this.pathSegments[i].applyAsPath(director); -944 } -945 ctx.globalCompositeOperation= 'source-over'; -946 return this; -947 }, -948 /** -949 * Set whether this path should paint handles for every control point. -950 * @param interactive {boolean}. -951 */ -952 setInteractive : function(interactive) { -953 this.interactive= interactive; -954 return this; -955 }, -956 getFirstPathSegment : function() { -957 return this.pathSegments.length ? -958 this.pathSegments[0] : -959 null; -960 }, -961 getLastPathSegment : function() { -962 return this.pathSegments.length ? -963 this.pathSegments[ this.pathSegments.length-1 ] : -964 null; -965 }, -966 /** -967 * Return the last point of the last path segment of this compound path. -968 * @return {CAAT.Point} -969 */ -970 endCurvePosition : function() { -971 if ( this.pathSegments.length ) { -972 return this.pathSegments[ this.pathSegments.length-1 ].endCurvePosition(); -973 } else { -974 return new CAAT.Point().set( this.beginPathX, this.beginPathY ); -975 } -976 }, -977 /** -978 * Return the first point of the first path segment of this compound path. -979 * @return {CAAT.Point} -980 */ -981 startCurvePosition : function() { -982 return this.pathSegments[ 0 ].startCurvePosition(); -983 }, -984 /** -985 * Return the last path segment added to this path. -986 * @return {CAAT.PathSegment} -987 */ -988 getCurrentPathSegment : function() { -989 return this.pathSegments[ this.pathSegments.length-1 ]; -990 }, -991 /** -992 * Set the path to be composed by a single LinearPath segment. -993 * @param x0 {number} -994 * @param y0 {number} -995 * @param x1 {number} -996 * @param y1 {number} -997 * @return this -998 */ -999 setLinear : function(x0,y0,x1,y1) { -1000 this.beginPath(x0,y0); -1001 this.addLineTo(x1,y1); -1002 this.endPath(); -1003 -1004 return this; -1005 }, -1006 /** -1007 * Set this path to be composed by a single Quadric Bezier path segment. -1008 * @param x0 {number} -1009 * @param y0 {number} -1010 * @param x1 {number} -1011 * @param y1 {number} -1012 * @param x2 {number} -1013 * @param y2 {number} -1014 * @return this -1015 */ -1016 setQuadric : function(x0,y0,x1,y1,x2,y2) { -1017 this.beginPath(x0,y0); -1018 this.addQuadricTo(x1,y1,x2,y2); -1019 this.endPath(); -1020 -1021 return this; -1022 }, -1023 /** -1024 * Sets this path to be composed by a single Cubic Bezier path segment. -1025 * @param x0 {number} -1026 * @param y0 {number} -1027 * @param x1 {number} -1028 * @param y1 {number} -1029 * @param x2 {number} -1030 * @param y2 {number} -1031 * @param x3 {number} -1032 * @param y3 {number} -1033 * -1034 * @return this -1035 */ -1036 setCubic : function(x0,y0,x1,y1,x2,y2,x3,y3) { -1037 this.beginPath(x0,y0); -1038 this.addCubicTo(x1,y1,x2,y2,x3,y3); -1039 this.endPath(); -1040 -1041 return this; -1042 }, -1043 setRectangle : function(x0,y0, x1,y1) { -1044 this.beginPath(x0,y0); -1045 this.addRectangleTo(x1,y1); -1046 this.endPath(); -1047 -1048 return this; -1049 }, -1050 /** -1051 * Add a CAAT.PathSegment instance to this path. -1052 * @param pathSegment {CAAT.PathSegment} -1053 * @return this -1054 * -1055 * @deprecated -1056 */ -1057 addSegment : function(pathSegment) { -1058 pathSegment.setParent(this); -1059 this.pathSegments.push(pathSegment); -1060 return this; -1061 }, -1062 addRectangleTo : function( x1,y1, cw, color ) { -1063 var r= new CAAT.ShapePath(); -1064 r.setPoints([ -1065 this.endCurvePosition(), -1066 new CAAT.Point().set(x1,y1) -1067 ]); -1068 -1069 r.setClockWise(cw); -1070 r.setColor(color); -1071 r.setParent(this); -1072 -1073 this.pathSegments.push(r); -1074 -1075 return this; -1076 }, -1077 /** -1078 * Add a Quadric Bezier path segment to this path. -1079 * The segment starts in the current last path coordinate. -1080 * @param px1 {number} -1081 * @param py1 {number} -1082 * @param px2 {number} -1083 * @param py2 {number} -1084 * @param color {color=}. optional parameter. determines the color to draw the segment with (if -1085 * being drawn by a CAAT.PathActor). -1086 * -1087 * @return this -1088 */ -1089 addQuadricTo : function( px1,py1, px2,py2, color ) { -1090 var bezier= new CAAT.Bezier(); -1091 -1092 bezier.setPoints( -1093 [ -1094 this.endCurvePosition(), -1095 new CAAT.Point().set(px1,py1), -1096 new CAAT.Point().set(px2,py2) -1097 ]); -1098 -1099 this.trackPathX= px2; -1100 this.trackPathY= py2; -1101 -1102 var segment= new CAAT.CurvePath().setColor(color).setParent(this); -1103 segment.curve= bezier; -1104 -1105 this.pathSegments.push(segment); -1106 -1107 return this; -1108 }, -1109 /** -1110 * Add a Cubic Bezier segment to this path. -1111 * The segment starts in the current last path coordinate. -1112 * @param px1 {number} -1113 * @param py1 {number} -1114 * @param px2 {number} -1115 * @param py2 {number} -1116 * @param px3 {number} -1117 * @param py3 {number} -1118 * @param color {color=}. optional parameter. determines the color to draw the segment with (if -1119 * being drawn by a CAAT.PathActor). -1120 * -1121 * @return this -1122 */ -1123 addCubicTo : function( px1,py1, px2,py2, px3,py3, color ) { -1124 var bezier= new CAAT.Bezier(); -1125 -1126 bezier.setPoints( -1127 [ -1128 this.endCurvePosition(), -1129 new CAAT.Point().set(px1,py1), -1130 new CAAT.Point().set(px2,py2), -1131 new CAAT.Point().set(px3,py3) -1132 ]); -1133 -1134 this.trackPathX= px3; -1135 this.trackPathY= py3; -1136 -1137 var segment= new CAAT.CurvePath().setColor(color).setParent(this); -1138 segment.curve= bezier; -1139 -1140 this.pathSegments.push(segment); -1141 return this; -1142 }, -1143 /** -1144 * Add a Catmull-Rom segment to this path. -1145 * The segment starts in the current last path coordinate. -1146 * @param px1 {number} -1147 * @param py1 {number} -1148 * @param px2 {number} -1149 * @param py2 {number} -1150 * @param px3 {number} -1151 * @param py3 {number} -1152 * @param color {color=}. optional parameter. determines the color to draw the segment with (if -1153 * being drawn by a CAAT.PathActor). -1154 * -1155 * @return this -1156 */ -1157 addCatmullTo : function( px1,py1, px2,py2, px3,py3, color ) { -1158 var curve= new CAAT.CatmullRom().setColor(color); -1159 curve.setCurve(this.trackPathX,this.trackPathY, px1,py1, px2,py2, px3,py3); -1160 this.trackPathX= px3; -1161 this.trackPathY= py3; -1162 -1163 var segment= new CAAT.CurvePath().setParent(this); -1164 segment.curve= curve; -1165 -1166 this.pathSegments.push(segment); -1167 return this; -1168 }, -1169 /** -1170 * Adds a line segment to this path. -1171 * The segment starts in the current last path coordinate. -1172 * @param px1 {number} -1173 * @param py1 {number} -1174 * @param color {color=}. optional parameter. determines the color to draw the segment with (if -1175 * being drawn by a CAAT.PathActor). -1176 * -1177 * @return this -1178 */ -1179 addLineTo : function( px1,py1, color ) { -1180 var segment= new CAAT.LinearPath().setColor(color); -1181 segment.setPoints( [ -1182 this.endCurvePosition(), -1183 new CAAT.Point().set(px1,py1) -1184 ]); +935 tAnchorX: 0, +936 tAnchorY: 0, +937 +938 /** translate behavior info **/ +939 tb_x: 0, +940 tb_y: 0, +941 +942 /** behavior affine transformation matrix **/ +943 matrix: null, +944 tmpMatrix: null, +945 +946 /** if behaviors are to be applied, save original path points **/ +947 pathPoints: null, +948 +949 /** path width and height **/ +950 width: 0, +951 height: 0, +952 +953 clipOffsetX : 0, +954 clipOffsetY : 0, +955 +956 applyAsPath : function(director) { +957 var ctx= director.ctx; +958 +959 director.modelViewMatrix.transformRenderingContext( ctx ); +960 ctx.beginPath(); +961 ctx.globalCompositeOperation= 'source-out'; +962 ctx.moveTo( +963 this.getFirstPathSegment().startCurvePosition().x, +964 this.getFirstPathSegment().startCurvePosition().y +965 ); +966 for( var i=0; i<this.pathSegments.length; i++ ) { +967 this.pathSegments[i].applyAsPath(director); +968 } +969 ctx.globalCompositeOperation= 'source-over'; +970 return this; +971 }, +972 /** +973 * Set whether this path should paint handles for every control point. +974 * @param interactive {boolean}. +975 */ +976 setInteractive : function(interactive) { +977 this.interactive= interactive; +978 return this; +979 }, +980 getFirstPathSegment : function() { +981 return this.pathSegments.length ? +982 this.pathSegments[0] : +983 null; +984 }, +985 getLastPathSegment : function() { +986 return this.pathSegments.length ? +987 this.pathSegments[ this.pathSegments.length-1 ] : +988 null; +989 }, +990 /** +991 * Return the last point of the last path segment of this compound path. +992 * @return {CAAT.Point} +993 */ +994 endCurvePosition : function() { +995 if ( this.pathSegments.length ) { +996 return this.pathSegments[ this.pathSegments.length-1 ].endCurvePosition(); +997 } else { +998 return new CAAT.Point().set( this.beginPathX, this.beginPathY ); +999 } +1000 }, +1001 /** +1002 * Return the first point of the first path segment of this compound path. +1003 * @return {CAAT.Point} +1004 */ +1005 startCurvePosition : function() { +1006 return this.pathSegments[ 0 ].startCurvePosition(); +1007 }, +1008 /** +1009 * Return the last path segment added to this path. +1010 * @return {CAAT.PathSegment} +1011 */ +1012 getCurrentPathSegment : function() { +1013 return this.pathSegments[ this.pathSegments.length-1 ]; +1014 }, +1015 /** +1016 * Set the path to be composed by a single LinearPath segment. +1017 * @param x0 {number} +1018 * @param y0 {number} +1019 * @param x1 {number} +1020 * @param y1 {number} +1021 * @return this +1022 */ +1023 setLinear : function(x0,y0,x1,y1) { +1024 this.beginPath(x0,y0); +1025 this.addLineTo(x1,y1); +1026 this.endPath(); +1027 +1028 return this; +1029 }, +1030 /** +1031 * Set this path to be composed by a single Quadric Bezier path segment. +1032 * @param x0 {number} +1033 * @param y0 {number} +1034 * @param x1 {number} +1035 * @param y1 {number} +1036 * @param x2 {number} +1037 * @param y2 {number} +1038 * @return this +1039 */ +1040 setQuadric : function(x0,y0,x1,y1,x2,y2) { +1041 this.beginPath(x0,y0); +1042 this.addQuadricTo(x1,y1,x2,y2); +1043 this.endPath(); +1044 +1045 return this; +1046 }, +1047 /** +1048 * Sets this path to be composed by a single Cubic Bezier path segment. +1049 * @param x0 {number} +1050 * @param y0 {number} +1051 * @param x1 {number} +1052 * @param y1 {number} +1053 * @param x2 {number} +1054 * @param y2 {number} +1055 * @param x3 {number} +1056 * @param y3 {number} +1057 * +1058 * @return this +1059 */ +1060 setCubic : function(x0,y0,x1,y1,x2,y2,x3,y3) { +1061 this.beginPath(x0,y0); +1062 this.addCubicTo(x1,y1,x2,y2,x3,y3); +1063 this.endPath(); +1064 +1065 return this; +1066 }, +1067 setRectangle : function(x0,y0, x1,y1) { +1068 this.beginPath(x0,y0); +1069 this.addRectangleTo(x1,y1); +1070 this.endPath(); +1071 +1072 return this; +1073 }, +1074 setCatmullRom : function( points, closed ) { +1075 if ( closed ) { +1076 points = points.slice(0) +1077 points.unshift(points[points.length-1]) +1078 points.push(points[1]) +1079 points.push(points[2]) +1080 } +1081 +1082 for( var i=1; i<points.length-2; i++ ) { +1083 +1084 var segment= new CAAT.CurvePath().setColor("#000").setParent(this); +1085 var cm= new CAAT.CatmullRom().setCurve( +1086 points[ i-1 ], +1087 points[ i ], +1088 points[ i+1 ], +1089 points[ i+2 ] +1090 ); +1091 segment.curve= cm; +1092 this.pathSegments.push(segment); +1093 } +1094 return this; +1095 }, +1096 /** +1097 * Add a CAAT.PathSegment instance to this path. +1098 * @param pathSegment {CAAT.PathSegment} +1099 * @return this +1100 * +1101 * @deprecated +1102 */ +1103 addSegment : function(pathSegment) { +1104 pathSegment.setParent(this); +1105 this.pathSegments.push(pathSegment); +1106 return this; +1107 }, +1108 addRectangleTo : function( x1,y1, cw, color ) { +1109 var r= new CAAT.ShapePath(); +1110 r.setPoints([ +1111 this.endCurvePosition(), +1112 new CAAT.Point().set(x1,y1) +1113 ]); +1114 +1115 r.setClockWise(cw); +1116 r.setColor(color); +1117 r.setParent(this); +1118 +1119 this.pathSegments.push(r); +1120 +1121 return this; +1122 }, +1123 /** +1124 * Add a Quadric Bezier path segment to this path. +1125 * The segment starts in the current last path coordinate. +1126 * @param px1 {number} +1127 * @param py1 {number} +1128 * @param px2 {number} +1129 * @param py2 {number} +1130 * @param color {color=}. optional parameter. determines the color to draw the segment with (if +1131 * being drawn by a CAAT.PathActor). +1132 * +1133 * @return this +1134 */ +1135 addQuadricTo : function( px1,py1, px2,py2, color ) { +1136 var bezier= new CAAT.Bezier(); +1137 +1138 bezier.setPoints( +1139 [ +1140 this.endCurvePosition(), +1141 new CAAT.Point().set(px1,py1), +1142 new CAAT.Point().set(px2,py2) +1143 ]); +1144 +1145 this.trackPathX= px2; +1146 this.trackPathY= py2; +1147 +1148 var segment= new CAAT.CurvePath().setColor(color).setParent(this); +1149 segment.curve= bezier; +1150 +1151 this.pathSegments.push(segment); +1152 +1153 return this; +1154 }, +1155 /** +1156 * Add a Cubic Bezier segment to this path. +1157 * The segment starts in the current last path coordinate. +1158 * @param px1 {number} +1159 * @param py1 {number} +1160 * @param px2 {number} +1161 * @param py2 {number} +1162 * @param px3 {number} +1163 * @param py3 {number} +1164 * @param color {color=}. optional parameter. determines the color to draw the segment with (if +1165 * being drawn by a CAAT.PathActor). +1166 * +1167 * @return this +1168 */ +1169 addCubicTo : function( px1,py1, px2,py2, px3,py3, color ) { +1170 var bezier= new CAAT.Bezier(); +1171 +1172 bezier.setPoints( +1173 [ +1174 this.endCurvePosition(), +1175 new CAAT.Point().set(px1,py1), +1176 new CAAT.Point().set(px2,py2), +1177 new CAAT.Point().set(px3,py3) +1178 ]); +1179 +1180 this.trackPathX= px3; +1181 this.trackPathY= py3; +1182 +1183 var segment= new CAAT.CurvePath().setColor(color).setParent(this); +1184 segment.curve= bezier; 1185 -1186 segment.setParent(this); -1187 -1188 this.trackPathX= px1; -1189 this.trackPathY= py1; -1190 -1191 this.pathSegments.push(segment); -1192 return this; -1193 }, -1194 /** -1195 * Set the path's starting point. The method startCurvePosition will return this coordinate. -1196 * <p> -1197 * If a call to any method of the form <code>add<Segment>To</code> is called before this calling -1198 * this method, they will assume to start at -1,-1 and probably you'll get the wrong path. -1199 * @param px0 {number} -1200 * @param py0 {number} -1201 * -1202 * @return this -1203 */ -1204 beginPath : function( px0, py0 ) { -1205 this.trackPathX= px0; -1206 this.trackPathY= py0; -1207 this.beginPathX= px0; -1208 this.beginPathY= py0; -1209 return this; -1210 }, -1211 /** -1212 * <del>Close the path by adding a line path segment from the current last path -1213 * coordinate to startCurvePosition coordinate</del>. -1214 * <p> -1215 * This method closes a path by setting its last path segment's last control point -1216 * to be the first path segment's first control point. -1217 * <p> -1218 * This method also sets the path as finished, and calculates all path's information -1219 * such as length and bounding box. -1220 * -1221 * @return this -1222 */ -1223 closePath : function() { -1224 -1225 this.getLastPathSegment().setPoint( -1226 this.getFirstPathSegment().startCurvePosition(), -1227 this.getLastPathSegment().numControlPoints()-1 ); -1228 -1229 -1230 this.trackPathX= this.beginPathX; -1231 this.trackPathY= this.beginPathY; -1232 -1233 this.endPath(); -1234 return this; -1235 }, -1236 /** -1237 * Finishes the process of building the path. It involves calculating each path segments length -1238 * and proportional length related to a normalized path length of 1. -1239 * It also sets current paths length. -1240 * These calculi are needed to traverse the path appropriately. -1241 * <p> -1242 * This method must be called explicitly, except when closing a path (that is, calling the -1243 * method closePath) which calls this method as well. -1244 * -1245 * @return this -1246 */ -1247 endPath : function() { -1248 -1249 this.pathSegmentStartTime=[]; -1250 this.pathSegmentDurationTime= []; -1251 -1252 this.updatePath(); -1253 -1254 return this; -1255 }, -1256 /** -1257 * This method, returns a CAAT.Point instance indicating a coordinate in the path. -1258 * The returned coordinate is the corresponding to normalizing the path's length to 1, -1259 * and then finding what path segment and what coordinate in that path segment corresponds -1260 * for the input time parameter. -1261 * <p> -1262 * The parameter time must be a value ranging 0..1. -1263 * If not constrained to these values, the parameter will be modulus 1, and then, if less -1264 * than 0, be normalized to 1+time, so that the value always ranges from 0 to 1. -1265 * <p> -1266 * This method is needed when traversing the path throughout a CAAT.Interpolator instance. -1267 * -1268 * @param time a value between 0 and 1 both inclusive. 0 will return path's starting coordinate. -1269 * 1 will return path's end coordinate. -1270 * -1271 * @return {CAAT.Point} -1272 */ -1273 getPosition : function(time) { +1186 this.pathSegments.push(segment); +1187 return this; +1188 }, +1189 /** +1190 * Add a Catmull-Rom segment to this path. +1191 * The segment starts in the current last path coordinate. +1192 * @param px1 {number} +1193 * @param py1 {number} +1194 * @param px2 {number} +1195 * @param py2 {number} +1196 * @param px3 {number} +1197 * @param py3 {number} +1198 * @param color {color=}. optional parameter. determines the color to draw the segment with (if +1199 * being drawn by a CAAT.PathActor). +1200 * +1201 * @return this +1202 */ +1203 addCatmullTo : function( px1,py1, px2,py2, px3,py3, color ) { +1204 var curve= new CAAT.CatmullRom().setColor(color); +1205 curve.setCurve(this.trackPathX,this.trackPathY, px1,py1, px2,py2, px3,py3); +1206 this.trackPathX= px3; +1207 this.trackPathY= py3; +1208 +1209 var segment= new CAAT.CurvePath().setParent(this); +1210 segment.curve= curve; +1211 +1212 this.pathSegments.push(segment); +1213 return this; +1214 }, +1215 /** +1216 * Adds a line segment to this path. +1217 * The segment starts in the current last path coordinate. +1218 * @param px1 {number} +1219 * @param py1 {number} +1220 * @param color {color=}. optional parameter. determines the color to draw the segment with (if +1221 * being drawn by a CAAT.PathActor). +1222 * +1223 * @return this +1224 */ +1225 addLineTo : function( px1,py1, color ) { +1226 var segment= new CAAT.LinearPath().setColor(color); +1227 segment.setPoints( [ +1228 this.endCurvePosition(), +1229 new CAAT.Point().set(px1,py1) +1230 ]); +1231 +1232 segment.setParent(this); +1233 +1234 this.trackPathX= px1; +1235 this.trackPathY= py1; +1236 +1237 this.pathSegments.push(segment); +1238 return this; +1239 }, +1240 /** +1241 * Set the path's starting point. The method startCurvePosition will return this coordinate. +1242 * <p> +1243 * If a call to any method of the form <code>add<Segment>To</code> is called before this calling +1244 * this method, they will assume to start at -1,-1 and probably you'll get the wrong path. +1245 * @param px0 {number} +1246 * @param py0 {number} +1247 * +1248 * @return this +1249 */ +1250 beginPath : function( px0, py0 ) { +1251 this.trackPathX= px0; +1252 this.trackPathY= py0; +1253 this.beginPathX= px0; +1254 this.beginPathY= py0; +1255 return this; +1256 }, +1257 /** +1258 * <del>Close the path by adding a line path segment from the current last path +1259 * coordinate to startCurvePosition coordinate</del>. +1260 * <p> +1261 * This method closes a path by setting its last path segment's last control point +1262 * to be the first path segment's first control point. +1263 * <p> +1264 * This method also sets the path as finished, and calculates all path's information +1265 * such as length and bounding box. +1266 * +1267 * @return this +1268 */ +1269 closePath : function() { +1270 +1271 this.getLastPathSegment().setPoint( +1272 this.getFirstPathSegment().startCurvePosition(), +1273 this.getLastPathSegment().numControlPoints()-1 ); 1274 -1275 if ( time>1 || time<0 ) { -1276 time%=1; -1277 } -1278 if ( time<0 ) { -1279 time= 1+time; -1280 } -1281 -1282 var found= false; -1283 for( var i=0; i<this.pathSegments.length; i++ ) { -1284 if (this.pathSegmentStartTime[i]<=time && time<=this.pathSegmentStartTime[i]+this.pathSegmentDurationTime[i]) { -1285 time= this.pathSegmentDurationTime[i] ? -1286 (time-this.pathSegmentStartTime[i])/this.pathSegmentDurationTime[i] : -1287 0; -1288 var pointInPath= this.pathSegments[i].getPosition(time); -1289 this.newPosition.x= pointInPath.x; -1290 this.newPosition.y= pointInPath.y; -1291 found= true; -1292 break; -1293 } -1294 } -1295 -1296 /** -1297 * !found means surely, a linear path with overlapping start and end points. -1298 * In such case, a (0,0) point would be returned, so instead, return either start or ending point. -1299 */ -1300 return found ? this.newPosition : this.endCurvePosition(); +1275 +1276 this.trackPathX= this.beginPathX; +1277 this.trackPathY= this.beginPathY; +1278 +1279 this.endPath(); +1280 return this; +1281 }, +1282 /** +1283 * Finishes the process of building the path. It involves calculating each path segments length +1284 * and proportional length related to a normalized path length of 1. +1285 * It also sets current paths length. +1286 * These calculi are needed to traverse the path appropriately. +1287 * <p> +1288 * This method must be called explicitly, except when closing a path (that is, calling the +1289 * method closePath) which calls this method as well. +1290 * +1291 * @return this +1292 */ +1293 endPath : function() { +1294 +1295 this.pathSegmentStartTime=[]; +1296 this.pathSegmentDurationTime= []; +1297 +1298 this.updatePath(); +1299 +1300 return this; 1301 }, 1302 /** -1303 * Analogously to the method getPosition, this method returns a CAAT.Point instance with -1304 * the coordinate on the path that corresponds to the given length. The input length is -1305 * related to path's length. -1306 * -1307 * @param iLength {number} a float with the target length. -1308 * @return {CAAT.Point} -1309 */ -1310 getPositionFromLength : function(iLength) { -1311 -1312 iLength%=this.getLength(); -1313 if (iLength<0 ) { -1314 iLength+= this.getLength(); -1315 } -1316 -1317 var accLength=0; -1318 -1319 for( var i=0; i<this.pathSegments.length; i++ ) { -1320 if (accLength<=iLength && iLength<=this.pathSegments[i].getLength()+accLength) { -1321 iLength-= accLength; -1322 var pointInPath= this.pathSegments[i].getPositionFromLength(iLength); -1323 this.newPosition.x= pointInPath.x; -1324 this.newPosition.y= pointInPath.y; -1325 break; -1326 } -1327 accLength+= this.pathSegments[i].getLength(); -1328 } -1329 -1330 return this.newPosition; -1331 }, -1332 /** -1333 * Paints the path. -1334 * This method is called by CAAT.PathActor instances. -1335 * If the path is set as interactive (by default) path segment will draw curve modification -1336 * handles as well. -1337 * -1338 * @param director {CAAT.Director} a CAAT.Director instance. -1339 */ -1340 paint : function( director ) { -1341 for( var i=0; i<this.pathSegments.length; i++ ) { -1342 this.pathSegments[i].paint(director,this.interactive); -1343 } -1344 }, -1345 /** -1346 * Method invoked when a CAAT.PathActor stops dragging a control point. -1347 */ -1348 release : function() { -1349 this.ax= -1; -1350 this.ay= -1; -1351 }, -1352 /** -1353 * Returns an integer with the number of path segments that conform this path. -1354 * @return {number} -1355 */ -1356 getNumSegments : function() { -1357 return this.pathSegments.length; -1358 }, -1359 /** -1360 * Gets a CAAT.PathSegment instance. -1361 * @param index {number} the index of the desired CAAT.PathSegment. -1362 * @return CAAT.PathSegment -1363 */ -1364 getSegment : function(index) { -1365 return this.pathSegments[index]; -1366 }, -1367 -1368 numControlPoints : function() { -1369 return this.points.length; -1370 }, -1371 -1372 getControlPoint : function(index) { -1373 return this.points[index]; -1374 }, +1303 * This method, returns a CAAT.Point instance indicating a coordinate in the path. +1304 * The returned coordinate is the corresponding to normalizing the path's length to 1, +1305 * and then finding what path segment and what coordinate in that path segment corresponds +1306 * for the input time parameter. +1307 * <p> +1308 * The parameter time must be a value ranging 0..1. +1309 * If not constrained to these values, the parameter will be modulus 1, and then, if less +1310 * than 0, be normalized to 1+time, so that the value always ranges from 0 to 1. +1311 * <p> +1312 * This method is needed when traversing the path throughout a CAAT.Interpolator instance. +1313 * +1314 * @param time a value between 0 and 1 both inclusive. 0 will return path's starting coordinate. +1315 * 1 will return path's end coordinate. +1316 * +1317 * @return {CAAT.Point} +1318 */ +1319 getPosition : function(time) { +1320 +1321 if ( time>1 || time<0 ) { +1322 time%=1; +1323 } +1324 if ( time<0 ) { +1325 time= 1+time; +1326 } +1327 +1328 /* +1329 var found= false; +1330 for( var i=0; i<this.pathSegments.length; i++ ) { +1331 if (this.pathSegmentStartTime[i]<=time && time<=this.pathSegmentStartTime[i]+this.pathSegmentDurationTime[i]) { +1332 time= this.pathSegmentDurationTime[i] ? +1333 (time-this.pathSegmentStartTime[i])/this.pathSegmentDurationTime[i] : +1334 0; +1335 var pointInPath= this.pathSegments[i].getPosition(time); +1336 this.newPosition.x= pointInPath.x; +1337 this.newPosition.y= pointInPath.y; +1338 found= true; +1339 break; +1340 } +1341 } +1342 +1343 return found ? this.newPosition : this.endCurvePosition(); +1344 */ +1345 +1346 +1347 var ps= this.pathSegments; +1348 var psst= this.pathSegmentStartTime; +1349 var psdt= this.pathSegmentDurationTime; +1350 var l= 0; +1351 var r= ps.length; +1352 var m; +1353 var np= this.newPosition; +1354 var psstv; +1355 while( l!==r ) { +1356 +1357 m= ((r+l)/2)|0; +1358 psstv= psst[m]; +1359 if ( psstv<=time && time<=psstv+psdt[m]) { +1360 time= psdt[m] ? +1361 (time-psstv)/psdt[m] : +1362 0; +1363 +1364 var pointInPath= ps[m].getPosition(time); +1365 np.x= pointInPath.x; +1366 np.y= pointInPath.y; +1367 return np; +1368 } else if ( time<psstv ) { +1369 r= m; +1370 } else /*if ( time>=psstv )*/ { +1371 l= m+1; +1372 } +1373 } +1374 return this.endCurvePosition(); 1375 -1376 /** -1377 * Indicates that some path control point has changed, and that the path must recalculate -1378 * its internal data, ie: length and bbox. -1379 */ -1380 updatePath : function(point) { -1381 var i,j; -1382 -1383 this.length=0; -1384 this.bbox.setEmpty(); -1385 this.points= []; -1386 -1387 var xmin= Number.MAX_VALUE, ymin= Number.MAX_VALUE; -1388 for( i=0; i<this.pathSegments.length; i++ ) { -1389 this.pathSegments[i].updatePath(point); -1390 this.length+= this.pathSegments[i].getLength(); -1391 this.bbox.unionRectangle( this.pathSegments[i].bbox ); -1392 -1393 for( j=0; j<this.pathSegments[i].numControlPoints(); j++ ) { -1394 var pt= this.pathSegments[i].getControlPoint( j ); -1395 this.points.push( pt ); -1396 if ( pt.x < xmin ) { -1397 xmin= pt.x; -1398 } -1399 if ( pt.y < ymin ) { -1400 ymin= pt.y; -1401 } -1402 } -1403 } -1404 -1405 this.clipOffsetX= -xmin; -1406 this.clipOffsetY= -ymin; -1407 -1408 this.width= this.bbox.width; -1409 this.height= this.bbox.height; -1410 this.setLocation( this.bbox.x, this.bbox.y ); -1411 this.bbox.x= 0; -1412 this.bbox.y= 0; -1413 this.bbox.x1= this.width; -1414 this.bbox.y1= this.height; -1415 -1416 this.pathSegmentStartTime= []; -1417 this.pathSegmentDurationTime= []; -1418 -1419 var i; -1420 for( i=0; i<this.pathSegments.length; i++) { -1421 this.pathSegmentStartTime.push(0); -1422 this.pathSegmentDurationTime.push(0); -1423 } -1424 -1425 for( i=0; i<this.pathSegments.length; i++) { -1426 this.pathSegmentDurationTime[i]= this.getLength() ? this.pathSegments[i].getLength()/this.getLength() : 0; -1427 if ( i>0 ) { -1428 this.pathSegmentStartTime[i]= this.pathSegmentStartTime[i-1]+this.pathSegmentDurationTime[i-1]; -1429 } else { -1430 this.pathSegmentStartTime[0]= 0; -1431 } -1432 -1433 this.pathSegments[i].endPath(); -1434 } -1435 -1436 this.extractPathPoints(); -1437 -1438 return this; -1439 -1440 }, -1441 /** -1442 * Sent by a CAAT.PathActor instance object to try to drag a path's control point. -1443 * @param x {number} -1444 * @param y {number} -1445 */ -1446 press: function(x,y) { -1447 if (!this.interactive) { -1448 return; -1449 } -1450 -1451 var HS= CAAT.Curve.prototype.HANDLE_SIZE/2; -1452 for( var i=0; i<this.pathSegments.length; i++ ) { -1453 for( var j=0; j<this.pathSegments[i].numControlPoints(); j++ ) { -1454 var point= this.pathSegments[i].getControlPoint(j); -1455 if ( x>=point.x-HS && -1456 y>=point.y-HS && -1457 x<point.x+HS && -1458 y<point.y+HS ) { -1459 -1460 this.point= point; -1461 return; -1462 } -1463 } -1464 } -1465 this.point= null; -1466 }, -1467 /** -1468 * Drags a path's control point. -1469 * If the method press has not set needed internal data to drag a control point, this -1470 * method will do nothing, regardless the user is dragging on the CAAT.PathActor delegate. -1471 * @param x {number} -1472 * @param y {number} -1473 */ -1474 drag : function(x,y) { -1475 if (!this.interactive) { -1476 return; -1477 } -1478 -1479 if ( null===this.point ) { -1480 return; -1481 } -1482 -1483 if ( -1===this.ax || -1===this.ay ) { -1484 this.ax= x; -1485 this.ay= y; -1486 } -1487 -1488 this.point.x+= x-this.ax; -1489 this.point.y+= y-this.ay; -1490 -1491 this.ax= x; -1492 this.ay= y; -1493 -1494 this.updatePath(this.point); -1495 }, -1496 /** -1497 * Returns a collection of CAAT.Point objects which conform a path's contour. -1498 * @param iSize {number}. Number of samples for each path segment. -1499 * @return {[CAAT.Point]} -1500 */ -1501 getContour : function(iSize) { -1502 var contour=[]; -1503 for( var i=0; i<=iSize; i++ ) { -1504 contour.push( new CAAT.Point().set( i/iSize, this.getPosition(i/iSize).y, 0 ) ); -1505 } -1506 -1507 return contour; -1508 }, -1509 -1510 /** -1511 * Reposition this path points. -1512 * This operation will only take place if the supplied points array equals in size to -1513 * this path's already set points. -1514 * @param points {Array<CAAT.Point>} -1515 */ -1516 setPoints : function( points ) { -1517 if ( this.points.length===points.length ) { -1518 for( var i=0; i<points.length; i++ ) { -1519 this.points[i].x= points[i].x; -1520 this.points[i].y= points[i].y; -1521 } -1522 } -1523 return this; -1524 }, -1525 -1526 /** -1527 * Set a point from this path. -1528 * @param point {CAAT.Point} -1529 * @param index {integer} a point index. -1530 */ -1531 setPoint : function( point, index ) { -1532 if ( index>=0 && index<this.points.length ) { -1533 this.points[index].x= point.x; -1534 this.points[index].y= point.y; -1535 } -1536 return this; -1537 }, -1538 -1539 -1540 /** -1541 * Removes all behaviors from an Actor. -1542 * @return this -1543 */ -1544 emptyBehaviorList : function() { -1545 this.behaviorList=[]; -1546 return this; -1547 }, -1548 -1549 extractPathPoints : function() { -1550 if ( !this.pathPoints ) { -1551 var i; -1552 this.pathPoints= []; -1553 for ( i=0; i<this.numControlPoints(); i++ ) { -1554 this.pathPoints.push( this.getControlPoint(i).clone() ); -1555 } -1556 } -1557 -1558 return this; -1559 }, -1560 -1561 /** -1562 * Add a Behavior to the Actor. -1563 * An Actor accepts an undefined number of Behaviors. -1564 * -1565 * @param behavior {CAAT.Behavior} a CAAT.Behavior instance -1566 * @return this -1567 */ -1568 addBehavior : function( behavior ) { -1569 this.behaviorList.push(behavior); -1570 // this.extractPathPoints(); -1571 return this; -1572 }, -1573 /** -1574 * Remove a Behavior from the Actor. -1575 * If the Behavior is not present at the actor behavior collection nothing happends. -1576 * -1577 * @param behavior {CAAT.Behavior} a CAAT.Behavior instance. -1578 */ -1579 removeBehaviour : function( behavior ) { -1580 var n= this.behaviorList.length-1; -1581 while(n) { -1582 if ( this.behaviorList[n]===behavior ) { -1583 this.behaviorList.splice(n,1); -1584 return this; -1585 } -1586 } -1587 -1588 return this; -1589 }, +1376 +1377 }, +1378 /** +1379 * Analogously to the method getPosition, this method returns a CAAT.Point instance with +1380 * the coordinate on the path that corresponds to the given length. The input length is +1381 * related to path's length. +1382 * +1383 * @param iLength {number} a float with the target length. +1384 * @return {CAAT.Point} +1385 */ +1386 getPositionFromLength : function(iLength) { +1387 +1388 iLength%=this.getLength(); +1389 if (iLength<0 ) { +1390 iLength+= this.getLength(); +1391 } +1392 +1393 var accLength=0; +1394 +1395 for( var i=0; i<this.pathSegments.length; i++ ) { +1396 if (accLength<=iLength && iLength<=this.pathSegments[i].getLength()+accLength) { +1397 iLength-= accLength; +1398 var pointInPath= this.pathSegments[i].getPositionFromLength(iLength); +1399 this.newPosition.x= pointInPath.x; +1400 this.newPosition.y= pointInPath.y; +1401 break; +1402 } +1403 accLength+= this.pathSegments[i].getLength(); +1404 } +1405 +1406 return this.newPosition; +1407 }, +1408 /** +1409 * Paints the path. +1410 * This method is called by CAAT.PathActor instances. +1411 * If the path is set as interactive (by default) path segment will draw curve modification +1412 * handles as well. +1413 * +1414 * @param director {CAAT.Director} a CAAT.Director instance. +1415 */ +1416 paint : function( director ) { +1417 for( var i=0; i<this.pathSegments.length; i++ ) { +1418 this.pathSegments[i].paint(director,this.interactive); +1419 } +1420 }, +1421 /** +1422 * Method invoked when a CAAT.PathActor stops dragging a control point. +1423 */ +1424 release : function() { +1425 this.ax= -1; +1426 this.ay= -1; +1427 }, +1428 /** +1429 * Returns an integer with the number of path segments that conform this path. +1430 * @return {number} +1431 */ +1432 getNumSegments : function() { +1433 return this.pathSegments.length; +1434 }, +1435 /** +1436 * Gets a CAAT.PathSegment instance. +1437 * @param index {number} the index of the desired CAAT.PathSegment. +1438 * @return CAAT.PathSegment +1439 */ +1440 getSegment : function(index) { +1441 return this.pathSegments[index]; +1442 }, +1443 +1444 numControlPoints : function() { +1445 return this.points.length; +1446 }, +1447 +1448 getControlPoint : function(index) { +1449 return this.points[index]; +1450 }, +1451 +1452 /** +1453 * Indicates that some path control point has changed, and that the path must recalculate +1454 * its internal data, ie: length and bbox. +1455 */ +1456 updatePath : function(point, callback) { +1457 var i,j; +1458 +1459 this.length=0; +1460 this.bbox.setEmpty(); +1461 this.points= []; +1462 +1463 var xmin= Number.MAX_VALUE, ymin= Number.MAX_VALUE; +1464 for( i=0; i<this.pathSegments.length; i++ ) { +1465 this.pathSegments[i].updatePath(point); +1466 this.length+= this.pathSegments[i].getLength(); +1467 this.bbox.unionRectangle( this.pathSegments[i].bbox ); +1468 +1469 for( j=0; j<this.pathSegments[i].numControlPoints(); j++ ) { +1470 var pt= this.pathSegments[i].getControlPoint( j ); +1471 this.points.push( pt ); +1472 if ( pt.x < xmin ) { +1473 xmin= pt.x; +1474 } +1475 if ( pt.y < ymin ) { +1476 ymin= pt.y; +1477 } +1478 } +1479 } +1480 +1481 this.clipOffsetX= -xmin; +1482 this.clipOffsetY= -ymin; +1483 +1484 this.width= this.bbox.width; +1485 this.height= this.bbox.height; +1486 this.setLocation( this.bbox.x, this.bbox.y ); +1487 this.bbox.x= 0; +1488 this.bbox.y= 0; +1489 this.bbox.x1= this.width; +1490 this.bbox.y1= this.height; +1491 +1492 this.pathSegmentStartTime= []; +1493 this.pathSegmentDurationTime= []; +1494 +1495 var i; +1496 for( i=0; i<this.pathSegments.length; i++) { +1497 this.pathSegmentStartTime.push(0); +1498 this.pathSegmentDurationTime.push(0); +1499 } +1500 +1501 for( i=0; i<this.pathSegments.length; i++) { +1502 this.pathSegmentDurationTime[i]= this.getLength() ? this.pathSegments[i].getLength()/this.getLength() : 0; +1503 if ( i>0 ) { +1504 this.pathSegmentStartTime[i]= this.pathSegmentStartTime[i-1]+this.pathSegmentDurationTime[i-1]; +1505 } else { +1506 this.pathSegmentStartTime[0]= 0; +1507 } +1508 +1509 this.pathSegments[i].endPath(); +1510 } +1511 +1512 this.extractPathPoints(); +1513 +1514 if ( typeof callback!=='undefined' ) { +1515 callback(this); +1516 } +1517 +1518 return this; +1519 +1520 }, +1521 /** +1522 * Sent by a CAAT.PathActor instance object to try to drag a path's control point. +1523 * @param x {number} +1524 * @param y {number} +1525 */ +1526 press: function(x,y) { +1527 if (!this.interactive) { +1528 return; +1529 } +1530 +1531 var HS= CAAT.Curve.prototype.HANDLE_SIZE/2; +1532 for( var i=0; i<this.pathSegments.length; i++ ) { +1533 for( var j=0; j<this.pathSegments[i].numControlPoints(); j++ ) { +1534 var point= this.pathSegments[i].getControlPoint(j); +1535 if ( x>=point.x-HS && +1536 y>=point.y-HS && +1537 x<point.x+HS && +1538 y<point.y+HS ) { +1539 +1540 this.point= point; +1541 return; +1542 } +1543 } +1544 } +1545 this.point= null; +1546 }, +1547 /** +1548 * Drags a path's control point. +1549 * If the method press has not set needed internal data to drag a control point, this +1550 * method will do nothing, regardless the user is dragging on the CAAT.PathActor delegate. +1551 * @param x {number} +1552 * @param y {number} +1553 */ +1554 drag : function(x,y,callback) { +1555 if (!this.interactive) { +1556 return; +1557 } +1558 +1559 if ( null===this.point ) { +1560 return; +1561 } +1562 +1563 if ( -1===this.ax || -1===this.ay ) { +1564 this.ax= x; +1565 this.ay= y; +1566 } +1567 +1568 this.point.x+= x-this.ax; +1569 this.point.y+= y-this.ay; +1570 +1571 this.ax= x; +1572 this.ay= y; +1573 +1574 this.updatePath(this.point,callback); +1575 }, +1576 /** +1577 * Returns a collection of CAAT.Point objects which conform a path's contour. +1578 * @param iSize {number}. Number of samples for each path segment. +1579 * @return {[CAAT.Point]} +1580 */ +1581 getContour : function(iSize) { +1582 var contour=[]; +1583 for( var i=0; i<=iSize; i++ ) { +1584 contour.push( new CAAT.Point().set( i/iSize, this.getPosition(i/iSize).y, 0 ) ); +1585 } +1586 +1587 return contour; +1588 }, +1589 1590 /** -1591 * Remove a Behavior with id param as behavior identifier from this actor. -1592 * This function will remove ALL behavior instances with the given id. -1593 * -1594 * @param id {number} an integer. -1595 * return this; -1596 */ -1597 removeBehaviorById : function( id ) { -1598 for( var n=0; n<this.behaviorList.length; n++ ) { -1599 if ( this.behaviorList[n].id===id) { -1600 this.behaviorList.splice(n,1); +1591 * Reposition this path points. +1592 * This operation will only take place if the supplied points array equals in size to +1593 * this path's already set points. +1594 * @param points {Array<CAAT.Point>} +1595 */ +1596 setPoints : function( points ) { +1597 if ( this.points.length===points.length ) { +1598 for( var i=0; i<points.length; i++ ) { +1599 this.points[i].x= points[i].x; +1600 this.points[i].y= points[i].y; 1601 } 1602 } -1603 -1604 return this; +1603 return this; +1604 }, 1605 -1606 }, -1607 -1608 applyBehaviors : function(time) { -1609 // if (this.behaviorList.length) { -1610 for( var i=0; i<this.behaviorList.length; i++ ) { -1611 this.behaviorList[i].apply(time,this); -1612 } -1613 -1614 /** calculate behavior affine transform matrix **/ -1615 this.setATMatrix(); -1616 -1617 for (i = 0; i < this.numControlPoints(); i++) { -1618 this.setPoint( -1619 this.matrix.transformCoord( -1620 this.pathPoints[i].clone().translate( this.clipOffsetX, this.clipOffsetY )), i); -1621 } -1622 // } -1623 -1624 return this; -1625 }, -1626 -1627 setATMatrix : function() { -1628 this.matrix.identity(); -1629 -1630 var m= this.tmpMatrix.identity(); -1631 var mm= this.matrix.matrix; -1632 var c,s,_m00,_m01,_m10,_m11; -1633 var mm0, mm1, mm2, mm3, mm4, mm5; -1634 -1635 var bbox= this.bbox; -1636 var bbw= bbox.width ; -1637 var bbh= bbox.height ; -1638 var bbx= bbox.x; -1639 var bby= bbox.y +1606 /** +1607 * Set a point from this path. +1608 * @param point {CAAT.Point} +1609 * @param index {integer} a point index. +1610 */ +1611 setPoint : function( point, index ) { +1612 if ( index>=0 && index<this.points.length ) { +1613 this.points[index].x= point.x; +1614 this.points[index].y= point.y; +1615 } +1616 return this; +1617 }, +1618 +1619 +1620 /** +1621 * Removes all behaviors from an Actor. +1622 * @return this +1623 */ +1624 emptyBehaviorList : function() { +1625 this.behaviorList=[]; +1626 return this; +1627 }, +1628 +1629 extractPathPoints : function() { +1630 if ( !this.pathPoints ) { +1631 var i; +1632 this.pathPoints= []; +1633 for ( i=0; i<this.numControlPoints(); i++ ) { +1634 this.pathPoints.push( this.getControlPoint(i).clone() ); +1635 } +1636 } +1637 +1638 return this; +1639 }, 1640 -1641 mm0= 1; -1642 mm1= 0; -1643 mm3= 0; -1644 mm4= 1; -1645 -1646 mm2= this.tb_x - bbx - this.tAnchorX * bbw; -1647 mm5= this.tb_y - bby - this.tAnchorY * bbh; -1648 -1649 if ( this.rb_angle ) { -1650 -1651 var rbx= (this.rb_rotateAnchorX*bbw + bbx); -1652 var rby= (this.rb_rotateAnchorY*bbh + bby); -1653 -1654 mm2+= mm0*rbx + mm1*rby; -1655 mm5+= mm3*rbx + mm4*rby; -1656 -1657 c= Math.cos( this.rb_angle ); -1658 s= Math.sin( this.rb_angle); -1659 _m00= mm0; -1660 _m01= mm1; -1661 _m10= mm3; -1662 _m11= mm4; -1663 mm0= _m00*c + _m01*s; -1664 mm1= -_m00*s + _m01*c; -1665 mm3= _m10*c + _m11*s; -1666 mm4= -_m10*s + _m11*c; +1641 /** +1642 * Add a Behavior to the Actor. +1643 * An Actor accepts an undefined number of Behaviors. +1644 * +1645 * @param behavior {CAAT.Behavior} a CAAT.Behavior instance +1646 * @return this +1647 */ +1648 addBehavior : function( behavior ) { +1649 this.behaviorList.push(behavior); +1650 // this.extractPathPoints(); +1651 return this; +1652 }, +1653 /** +1654 * Remove a Behavior from the Actor. +1655 * If the Behavior is not present at the actor behavior collection nothing happends. +1656 * +1657 * @param behavior {CAAT.Behavior} a CAAT.Behavior instance. +1658 */ +1659 removeBehaviour : function( behavior ) { +1660 var n= this.behaviorList.length-1; +1661 while(n) { +1662 if ( this.behaviorList[n]===behavior ) { +1663 this.behaviorList.splice(n,1); +1664 return this; +1665 } +1666 } 1667 -1668 mm2+= -mm0*rbx - mm1*rby; -1669 mm5+= -mm3*rbx - mm4*rby; -1670 } -1671 -1672 if ( this.sb_scaleX!=1 || this.sb_scaleY!=1 ) { -1673 -1674 var sbx= (this.sb_scaleAnchorX*bbw + bbx); -1675 var sby= (this.sb_scaleAnchorY*bbh + bby); -1676 -1677 mm2+= mm0*sbx + mm1*sby; -1678 mm5+= mm3*sbx + mm4*sby; -1679 -1680 mm0= mm0*this.sb_scaleX; -1681 mm1= mm1*this.sb_scaleY; -1682 mm3= mm3*this.sb_scaleX; -1683 mm4= mm4*this.sb_scaleY; -1684 -1685 mm2+= -mm0*sbx - mm1*sby; -1686 mm5+= -mm3*sbx - mm4*sby; -1687 } -1688 -1689 mm[0]= mm0; -1690 mm[1]= mm1; -1691 mm[2]= mm2; -1692 mm[3]= mm3; -1693 mm[4]= mm4; -1694 mm[5]= mm5; -1695 -1696 return this; -1697 -1698 }, -1699 -1700 setRotationAnchored : function( angle, rx, ry ) { -1701 this.rb_angle= angle; -1702 this.rb_rotateAnchorX= rx; -1703 this.rb_rotateAnchorY= ry; +1668 return this; +1669 }, +1670 /** +1671 * Remove a Behavior with id param as behavior identifier from this actor. +1672 * This function will remove ALL behavior instances with the given id. +1673 * +1674 * @param id {number} an integer. +1675 * return this; +1676 */ +1677 removeBehaviorById : function( id ) { +1678 for( var n=0; n<this.behaviorList.length; n++ ) { +1679 if ( this.behaviorList[n].id===id) { +1680 this.behaviorList.splice(n,1); +1681 } +1682 } +1683 +1684 return this; +1685 +1686 }, +1687 +1688 applyBehaviors : function(time) { +1689 // if (this.behaviorList.length) { +1690 for( var i=0; i<this.behaviorList.length; i++ ) { +1691 this.behaviorList[i].apply(time,this); +1692 } +1693 +1694 /** calculate behavior affine transform matrix **/ +1695 this.setATMatrix(); +1696 +1697 for (i = 0; i < this.numControlPoints(); i++) { +1698 this.setPoint( +1699 this.matrix.transformCoord( +1700 this.pathPoints[i].clone().translate( this.clipOffsetX, this.clipOffsetY )), i); +1701 } +1702 // } +1703 1704 return this; 1705 }, 1706 -1707 setRotationAnchor : function( ax, ay ) { -1708 this.rb_rotateAnchorX= ax; -1709 this.rb_rotateAnchorY= ay; -1710 }, -1711 -1712 setRotation : function( angle ) { -1713 this.rb_angle= angle; -1714 }, -1715 -1716 setScaleAnchored : function( scaleX, scaleY, sx, sy ) { -1717 this.sb_scaleX= scaleX; -1718 this.sb_scaleAnchorX= sx; -1719 this.sb_scaleY= scaleY; -1720 this.sb_scaleAnchorY= sy; -1721 return this; -1722 }, -1723 -1724 setScale : function( sx, sy ) { -1725 this.sb_scaleX= sx; -1726 this.sb_scaleY= sy; -1727 return this; -1728 }, -1729 -1730 setScaleAnchor : function( ax, ay ) { -1731 this.sb_scaleAnchorX= ax; -1732 this.sb_scaleAnchorY= ay; -1733 return this; -1734 }, -1735 -1736 setPositionAnchor : function( ax, ay ) { -1737 this.tAnchorX= ax; -1738 this.tAnchorY= ay; -1739 return this; -1740 }, -1741 -1742 setPositionAnchored : function( x,y,ax,ay ) { -1743 this.tb_x= x; -1744 this.tb_y= y; -1745 this.tAnchorX= ax; -1746 this.tAnchorY= ay; -1747 return this; -1748 }, -1749 -1750 setPosition : function( x,y ) { -1751 this.tb_x= x; -1752 this.tb_y= y; -1753 return this; -1754 }, -1755 -1756 setLocation : function( x, y ) { -1757 this.tb_x= x; -1758 this.tb_y= y; -1759 return this; -1760 } -1761 -1762 }; -1763 -1764 extend( CAAT.Path, CAAT.PathSegment, null); -1765 -1766 })(); \ No newline at end of file +1707 setATMatrix : function() { +1708 this.matrix.identity(); +1709 +1710 var m= this.tmpMatrix.identity(); +1711 var mm= this.matrix.matrix; +1712 var c,s,_m00,_m01,_m10,_m11; +1713 var mm0, mm1, mm2, mm3, mm4, mm5; +1714 +1715 var bbox= this.bbox; +1716 var bbw= bbox.width ; +1717 var bbh= bbox.height ; +1718 var bbx= bbox.x; +1719 var bby= bbox.y +1720 +1721 mm0= 1; +1722 mm1= 0; +1723 mm3= 0; +1724 mm4= 1; +1725 +1726 mm2= this.tb_x - bbx - this.tAnchorX * bbw; +1727 mm5= this.tb_y - bby - this.tAnchorY * bbh; +1728 +1729 if ( this.rb_angle ) { +1730 +1731 var rbx= (this.rb_rotateAnchorX*bbw + bbx); +1732 var rby= (this.rb_rotateAnchorY*bbh + bby); +1733 +1734 mm2+= mm0*rbx + mm1*rby; +1735 mm5+= mm3*rbx + mm4*rby; +1736 +1737 c= Math.cos( this.rb_angle ); +1738 s= Math.sin( this.rb_angle); +1739 _m00= mm0; +1740 _m01= mm1; +1741 _m10= mm3; +1742 _m11= mm4; +1743 mm0= _m00*c + _m01*s; +1744 mm1= -_m00*s + _m01*c; +1745 mm3= _m10*c + _m11*s; +1746 mm4= -_m10*s + _m11*c; +1747 +1748 mm2+= -mm0*rbx - mm1*rby; +1749 mm5+= -mm3*rbx - mm4*rby; +1750 } +1751 +1752 if ( this.sb_scaleX!=1 || this.sb_scaleY!=1 ) { +1753 +1754 var sbx= (this.sb_scaleAnchorX*bbw + bbx); +1755 var sby= (this.sb_scaleAnchorY*bbh + bby); +1756 +1757 mm2+= mm0*sbx + mm1*sby; +1758 mm5+= mm3*sbx + mm4*sby; +1759 +1760 mm0= mm0*this.sb_scaleX; +1761 mm1= mm1*this.sb_scaleY; +1762 mm3= mm3*this.sb_scaleX; +1763 mm4= mm4*this.sb_scaleY; +1764 +1765 mm2+= -mm0*sbx - mm1*sby; +1766 mm5+= -mm3*sbx - mm4*sby; +1767 } +1768 +1769 mm[0]= mm0; +1770 mm[1]= mm1; +1771 mm[2]= mm2; +1772 mm[3]= mm3; +1773 mm[4]= mm4; +1774 mm[5]= mm5; +1775 +1776 return this; +1777 +1778 }, +1779 +1780 setRotationAnchored : function( angle, rx, ry ) { +1781 this.rb_angle= angle; +1782 this.rb_rotateAnchorX= rx; +1783 this.rb_rotateAnchorY= ry; +1784 return this; +1785 }, +1786 +1787 setRotationAnchor : function( ax, ay ) { +1788 this.rb_rotateAnchorX= ax; +1789 this.rb_rotateAnchorY= ay; +1790 }, +1791 +1792 setRotation : function( angle ) { +1793 this.rb_angle= angle; +1794 }, +1795 +1796 setScaleAnchored : function( scaleX, scaleY, sx, sy ) { +1797 this.sb_scaleX= scaleX; +1798 this.sb_scaleAnchorX= sx; +1799 this.sb_scaleY= scaleY; +1800 this.sb_scaleAnchorY= sy; +1801 return this; +1802 }, +1803 +1804 setScale : function( sx, sy ) { +1805 this.sb_scaleX= sx; +1806 this.sb_scaleY= sy; +1807 return this; +1808 }, +1809 +1810 setScaleAnchor : function( ax, ay ) { +1811 this.sb_scaleAnchorX= ax; +1812 this.sb_scaleAnchorY= ay; +1813 return this; +1814 }, +1815 +1816 setPositionAnchor : function( ax, ay ) { +1817 this.tAnchorX= ax; +1818 this.tAnchorY= ay; +1819 return this; +1820 }, +1821 +1822 setPositionAnchored : function( x,y,ax,ay ) { +1823 this.tb_x= x; +1824 this.tb_y= y; +1825 this.tAnchorX= ax; +1826 this.tAnchorY= ay; +1827 return this; +1828 }, +1829 +1830 setPosition : function( x,y ) { +1831 this.tb_x= x; +1832 this.tb_y= y; +1833 return this; +1834 }, +1835 +1836 setLocation : function( x, y ) { +1837 this.tb_x= x; +1838 this.tb_y= y; +1839 return this; +1840 }, +1841 +1842 flatten : function( npatches, closed ) { +1843 var point= this.getPositionFromLength(0); +1844 var path= new CAAT.Path().beginPath( point.x, point.y ); +1845 for( var i=0; i<npatches; i++ ) { +1846 point= this.getPositionFromLength(i/npatches*this.length); +1847 path.addLineTo( point.x, point.y ); +1848 } +1849 if ( closed) { +1850 path.closePath(); +1851 } else { +1852 path.endPath(); +1853 } +1854 +1855 return path; +1856 } +1857 +1858 }; +1859 +1860 extend( CAAT.Path, CAAT.PathSegment, null); +1861 +1862 })(); \ No newline at end of file diff --git a/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_path_pathactor.js.html b/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_path_pathactor.js.html index bc5aab4a..d0aa6974 100644 --- a/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_path_pathactor.js.html +++ b/documentation/jsdoc/symbols/src/_Users_ibon_js_CAAT_src_path_pathactor.js.html @@ -24,91 +24,105 @@ 17 }; 18 19 CAAT.PathActor.prototype= { - 20 path: null, - 21 pathBoundingRectangle: null, - 22 bOutline: false, - 23 outlineColor: 'black', - 24 - 25 /** - 26 * Return the contained path. - 27 * @return {CAAT.Path} - 28 */ - 29 getPath : function() { - 30 return this.path; - 31 }, - 32 /** - 33 * Sets the path to manage. - 34 * @param path {CAAT.PathSegment} - 35 * @return this - 36 */ - 37 setPath : function(path) { - 38 this.path= path; - 39 this.pathBoundingRectangle= path.getBoundingBox(); - 40 return this; - 41 }, - 42 /** - 43 * Paint this actor. - 44 * @param director {CAAT.Director} - 45 * @param time {number}. Scene time. - 46 */ - 47 paint : function(director, time) { - 48 - 49 CAAT.PathActor.superclass.paint.call( this, director, time ); - 50 - 51 var canvas= director.crc; - 52 - 53 canvas.strokeStyle='black'; - 54 this.path.paint(director); + 20 path : null, + 21 pathBoundingRectangle : null, + 22 bOutline : false, + 23 outlineColor : 'black', + 24 onUpdateCallback : null, + 25 interactive : false, + 26 + 27 /** + 28 * Return the contained path. + 29 * @return {CAAT.Path} + 30 */ + 31 getPath : function() { + 32 return this.path; + 33 }, + 34 /** + 35 * Sets the path to manage. + 36 * @param path {CAAT.PathSegment} + 37 * @return this + 38 */ + 39 setPath : function(path) { + 40 this.path= path; + 41 if ( path!=null ) { + 42 this.pathBoundingRectangle= path.getBoundingBox(); + 43 this.setInteractive( this.interactive ); + 44 } + 45 return this; + 46 }, + 47 /** + 48 * Paint this actor. + 49 * @param director {CAAT.Director} + 50 * @param time {number}. Scene time. + 51 */ + 52 paint : function(director, time) { + 53 + 54 CAAT.PathActor.superclass.paint.call( this, director, time ); 55 - 56 if ( this.bOutline ) { - 57 canvas.strokeStyle= this.outlineColor; - 58 canvas.strokeRect(0,0,this.width,this.height); - 59 } - 60 }, - 61 /** - 62 * Enables/disables drawing of the contained path's bounding box. - 63 * @param show {boolean} whether to show the bounding box - 64 * @param color {=string} optional parameter defining the path's bounding box stroke style. - 65 */ - 66 showBoundingBox : function(show, color) { - 67 this.bOutline= show; - 68 if ( show && color ) { - 69 this.outlineColor= color; - 70 } - 71 }, - 72 /** - 73 * Set the contained path as interactive. This means it can be changed on the fly by manipulation - 74 * of its control points. - 75 * @param interactive - 76 */ - 77 setInteractive : function(interactive) { - 78 if ( this.path ) { - 79 this.path.setInteractive(interactive); - 80 } - 81 return this; - 82 }, - 83 /** - 84 * Route mouse dragging functionality to the contained path. - 85 * @param mouseEvent {CAAT.MouseEvent} - 86 */ - 87 mouseDrag : function(mouseEvent) { - 88 this.path.drag(mouseEvent.point.x, mouseEvent.point.y); - 89 }, - 90 /** - 91 * Route mouse down functionality to the contained path. - 92 * @param mouseEvent {CAAT.MouseEvent} - 93 */ - 94 mouseDown : function(mouseEvent) { - 95 this.path.press(mouseEvent.point.x, mouseEvent.point.y); - 96 }, + 56 if ( !this.path ) { + 57 return; + 58 } + 59 + 60 var ctx= director.ctx; + 61 + 62 ctx.strokeStyle='#000'; + 63 this.path.paint(director, this.interactive); + 64 + 65 if ( this.bOutline ) { + 66 ctx.strokeStyle= this.outlineColor; + 67 ctx.strokeRect(0,0,this.width,this.height); + 68 } + 69 }, + 70 /** + 71 * Enables/disables drawing of the contained path's bounding box. + 72 * @param show {boolean} whether to show the bounding box + 73 * @param color {=string} optional parameter defining the path's bounding box stroke style. + 74 */ + 75 showBoundingBox : function(show, color) { + 76 this.bOutline= show; + 77 if ( show && color ) { + 78 this.outlineColor= color; + 79 } + 80 }, + 81 /** + 82 * Set the contained path as interactive. This means it can be changed on the fly by manipulation + 83 * of its control points. + 84 * @param interactive + 85 */ + 86 setInteractive : function(interactive) { + 87 this.interactive= interactive; + 88 if ( this.path ) { + 89 this.path.setInteractive(interactive); + 90 } + 91 return this; + 92 }, + 93 setOnUpdateCallback : function( fn ) { + 94 this.onUpdateCallback= fn; + 95 return this; + 96 }, 97 /** - 98 * Route mouse up functionality to the contained path. + 98 * Route mouse dragging functionality to the contained path. 99 * @param mouseEvent {CAAT.MouseEvent} 100 */ -101 mouseUp : function(mouseEvent) { -102 this.path.release(); -103 } -104 }; -105 -106 extend( CAAT.PathActor, CAAT.ActorContainer, null); -107 })(); \ No newline at end of file +101 mouseDrag : function(mouseEvent) { +102 this.path.drag(mouseEvent.point.x, mouseEvent.point.y, this.onUpdateCallback); +103 }, +104 /** +105 * Route mouse down functionality to the contained path. +106 * @param mouseEvent {CAAT.MouseEvent} +107 */ +108 mouseDown : function(mouseEvent) { +109 this.path.press(mouseEvent.point.x, mouseEvent.point.y); +110 }, +111 /** +112 * Route mouse up functionality to the contained path. +113 * @param mouseEvent {CAAT.MouseEvent} +114 */ +115 mouseUp : function(mouseEvent) { +116 this.path.release(); +117 } +118 }; +119 +120 extend( CAAT.PathActor, CAAT.ActorContainer, null); +121 })(); \ No newline at end of file diff --git a/src/model/actor.js b/src/model/actor.js index 5c426654..fd6eb3f2 100644 --- a/src/model/actor.js +++ b/src/model/actor.js @@ -928,7 +928,7 @@ * @return null if the point is not inside the Actor. The Actor otherwise. */ findActorAtPosition : function(point) { - if ( !this.mouseEnabled || !this.isInAnimationFrame(this.time) ) { + if ( !this.visible || !this.mouseEnabled || !this.isInAnimationFrame(this.time) ) { return null; } @@ -1876,7 +1876,6 @@ cl[i].drawScreenBoundingBox(director,time); } CAAT.ActorContainer.superclass.drawScreenBoundingBox.call(this,director,time); - }, /** * Removes all children from this ActorContainer. diff --git a/src/model/conpoundimage.js b/src/model/conpoundimage.js index f9574af2..46bba4a3 100644 --- a/src/model/conpoundimage.js +++ b/src/model/conpoundimage.js @@ -269,29 +269,32 @@ this.setSpriteIndexAtTime(time); var el= this.mapInfo[this.spriteIndex]; + var r= new CAAT.Rectangle(); + this.ownerActor.AABB.intersect( director.AABB, r ); + var w= this.getWidth(); var h= this.getHeight(); - var xoff= this.offsetX % w; + var xoff= (this.offsetX-this.ownerActor.x) % w; if ( xoff> 0 ) { xoff= xoff-w; } - var yoff= this.offsetY % h; + var yoff= (this.offsetY-this.ownerActor.y) % h; if ( yoff> 0 ) { yoff= yoff-h; } - var nw= (((this.ownerActor.width-xoff)/w)>>0)+1; - var nh= (((this.ownerActor.height-yoff)/h)>>0)+1; + var nw= (((r.width-xoff)/w)>>0)+1; + var nh= (((r.height-yoff)/h)>>0)+1; var i,j; var ctx= director.ctx; for( i=0; i>0, (y+yoff+i*el.height)>>0, + (r.x-this.ownerActor.x+xoff+j*el.width)>>0, (r.y-this.ownerActor.y+yoff+i*el.height)>>0, el.width, el.height); } } diff --git a/src/model/director.js b/src/model/director.js index 0e6ea14d..8fff17a7 100644 --- a/src/model/director.js +++ b/src/model/director.js @@ -696,6 +696,7 @@ */ animate : function(director, time) { this.setModelViewMatrix(this); + this.modelViewMatrixI= this.modelViewMatrix.getInverse(); this.setScreenBounds(); this.dirty= false; @@ -1494,7 +1495,6 @@ // transformar coordenada inversamente con affine transform de director. var pt= new CAAT.Point( posx, posy ); - this.modelViewMatrixI= this.modelViewMatrix.getInverse(); this.modelViewMatrixI.transformCoord(pt); posx= pt.x; posy= pt.y diff --git a/src/model/scene.js b/src/model/scene.js index 57bcdd2f..fc5f1602 100644 --- a/src/model/scene.js +++ b/src/model/scene.js @@ -490,6 +490,122 @@ ctx.fillStyle= this.fillStyle; ctx.fillRect(0,0,this.width,this.height ); } + }, + /** + * Find a pointed actor at position point. + * This method tries lo find the correctly pointed actor in two different ways. + * + first of all, if inputList is defined, it will look for an actor in it. + * + if no inputList is defined, it will traverse the scene graph trying to find a pointed actor. + * @param point + */ + findActorAtPosition : function(point) { + var i,j; + + var p= new CAAT.Point(); + + if ( this.inputList ) { + var il= this.inputList; + for( i=0; i number of lists. + */ + enableInputList : function( size ) { + this.inputList= []; + for( var i=0; i an actor instance + * @param index the inputList index to add the actor to. This value will be clamped to the number of + * available lists. + * @param position the position on the selected inputList to add the actor at. This value will be + * clamped to the number of available lists. + */ + addActorToInputList : function( actor, index, position ) { + if ( index<0 ) index=0; else if ( index>=this.inputList.length ) index= this.inputList.length-1; + var il= this.inputList[index]; + + if ( typeof position==="undefined" || position>=il.length ) { + il.push( actor ); + } else if (position<=0) { + il.unshift( actor ); + } else { + il.splice( position, 0, actor ); + } + + return this; + }, + + /** + * Remove all elements from an input list. + * @param index the inputList index to add the actor to. This value will be clamped to the number of + * available lists so take care when emptying a non existant inputList index since you could end up emptying + * an undesired input list. + */ + emptyInputList : function( index ) { + if ( index<0 ) index=0; else if ( index>=this.inputList.length ) index= this.inputList.length-1; + this.inputList[index]= []; + return this; + }, + + /** + * remove an actor from a given input list index. + * If no index is supplied, the actor will be removed from every input list. + * @param actor + * @param index an optional input list index. This value will be clamped to the number of + * available lists. + */ + removeActorFromInputList : function( actor, index ) { + if ( typeof index==="undefined" ) { + var i,j; + for( i=0; i=this.inputList.length ) index= this.inputList.length-1; + var il= this.inputList[index]; + for( j=0; j