summaryrefslogtreecommitdiff
path: root/includes/js/dojox/gfx
diff options
context:
space:
mode:
authormensonge <mensonge@b3834d28-1941-0410-a4f8-b48e95affb8f>2008-11-13 09:49:11 +0000
committermensonge <mensonge@b3834d28-1941-0410-a4f8-b48e95affb8f>2008-11-13 09:49:11 +0000
commite44a7e37b6c7b5961adaffc62b9042b8d442938e (patch)
tree95b67c356e93163467db2451f2b8cce84ed5d582 /includes/js/dojox/gfx
parenta62b9742ee5e28bcec6872d88f50f25b820914f6 (diff)
downloadsemanticscuttle-e44a7e37b6c7b5961adaffc62b9042b8d442938e.tar.gz
semanticscuttle-e44a7e37b6c7b5961adaffc62b9042b8d442938e.tar.bz2
New feature: basic Ajax suggestion for tags and implementation of Dojo toolkit
git-svn-id: https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/trunk@151 b3834d28-1941-0410-a4f8-b48e95affb8f
Diffstat (limited to 'includes/js/dojox/gfx')
-rw-r--r--includes/js/dojox/gfx/Moveable.js101
-rw-r--r--includes/js/dojox/gfx/Mover.js62
-rw-r--r--includes/js/dojox/gfx/README102
-rw-r--r--includes/js/dojox/gfx/_base.js288
-rw-r--r--includes/js/dojox/gfx/arc.js122
-rw-r--r--includes/js/dojox/gfx/attach.js7
-rw-r--r--includes/js/dojox/gfx/canvas.js687
-rw-r--r--includes/js/dojox/gfx/canvas_attach.js8
-rw-r--r--includes/js/dojox/gfx/decompose.js139
-rw-r--r--includes/js/dojox/gfx/demos/beautify.html48
-rw-r--r--includes/js/dojox/gfx/demos/butterfly.html88
-rw-r--r--includes/js/dojox/gfx/demos/career_test.html467
-rw-r--r--includes/js/dojox/gfx/demos/circles.html90
-rw-r--r--includes/js/dojox/gfx/demos/clock.html253
-rw-r--r--includes/js/dojox/gfx/demos/clockWidget.html332
-rw-r--r--includes/js/dojox/gfx/demos/clock_black.html253
-rw-r--r--includes/js/dojox/gfx/demos/creator.html123
-rw-r--r--includes/js/dojox/gfx/demos/data/Lars.json1823
-rw-r--r--includes/js/dojox/gfx/demos/data/Lars.svg531
-rw-r--r--includes/js/dojox/gfx/demos/data/LarsDreaming.json1823
-rw-r--r--includes/js/dojox/gfx/demos/data/LarsDreaming.svg536
-rw-r--r--includes/js/dojox/gfx/demos/data/Nils.json717
-rw-r--r--includes/js/dojox/gfx/demos/data/Nils.svg188
-rw-r--r--includes/js/dojox/gfx/demos/data/buratino-bg.pngbin0 -> 27507 bytes
-rw-r--r--includes/js/dojox/gfx/demos/data/buratino-head.pngbin0 -> 30696 bytes
-rw-r--r--includes/js/dojox/gfx/demos/data/buratino-left-arm.pngbin0 -> 9631 bytes
-rw-r--r--includes/js/dojox/gfx/demos/data/buratino-left-leg.pngbin0 -> 21682 bytes
-rw-r--r--includes/js/dojox/gfx/demos/data/buratino-lollipop.pngbin0 -> 21976 bytes
-rw-r--r--includes/js/dojox/gfx/demos/data/buratino-nose-large.pngbin0 -> 4182 bytes
-rw-r--r--includes/js/dojox/gfx/demos/data/buratino-nose-medium.pngbin0 -> 2587 bytes
-rw-r--r--includes/js/dojox/gfx/demos/data/buratino-right-arm.pngbin0 -> 13033 bytes
-rw-r--r--includes/js/dojox/gfx/demos/data/buratino-right-leg.pngbin0 -> 23025 bytes
-rw-r--r--includes/js/dojox/gfx/demos/data/buratino-torso.pngbin0 -> 23405 bytes
-rw-r--r--includes/js/dojox/gfx/demos/data/buratino.jpgbin0 -> 33344 bytes
-rw-r--r--includes/js/dojox/gfx/demos/data/buratino.json12
-rw-r--r--includes/js/dojox/gfx/demos/data/svg2gfx.xsl72
-rw-r--r--includes/js/dojox/gfx/demos/data/transform.json1567
-rw-r--r--includes/js/dojox/gfx/demos/images/clock_face.jpgbin0 -> 31088 bytes
-rw-r--r--includes/js/dojox/gfx/demos/images/clock_face_black.jpgbin0 -> 17347 bytes
-rw-r--r--includes/js/dojox/gfx/demos/inspector.html165
-rw-r--r--includes/js/dojox/gfx/demos/lion.html235
-rw-r--r--includes/js/dojox/gfx/demos/roundedPane.html191
-rw-r--r--includes/js/dojox/gfx/demos/tiger.html566
-rw-r--r--includes/js/dojox/gfx/demos/tooltip.html238
-rw-r--r--includes/js/dojox/gfx/fx.js281
-rw-r--r--includes/js/dojox/gfx/matrix.js444
-rw-r--r--includes/js/dojox/gfx/move.js8
-rw-r--r--includes/js/dojox/gfx/path.js361
-rw-r--r--includes/js/dojox/gfx/shape.js691
-rw-r--r--includes/js/dojox/gfx/silverlight.js693
-rw-r--r--includes/js/dojox/gfx/silverlight_attach.js87
-rw-r--r--includes/js/dojox/gfx/svg.js638
-rw-r--r--includes/js/dojox/gfx/svg_attach.js224
-rw-r--r--includes/js/dojox/gfx/tests/decompose.js114
-rw-r--r--includes/js/dojox/gfx/tests/matrix.js228
-rw-r--r--includes/js/dojox/gfx/tests/module.js13
-rw-r--r--includes/js/dojox/gfx/tests/runTests.html9
-rw-r--r--includes/js/dojox/gfx/tests/test_arc.html71
-rw-r--r--includes/js/dojox/gfx/tests/test_bezier.html85
-rw-r--r--includes/js/dojox/gfx/tests/test_decompose.html54
-rw-r--r--includes/js/dojox/gfx/tests/test_fill.html47
-rw-r--r--includes/js/dojox/gfx/tests/test_fx.html113
-rw-r--r--includes/js/dojox/gfx/tests/test_gfx.html489
-rw-r--r--includes/js/dojox/gfx/tests/test_gradient.html70
-rw-r--r--includes/js/dojox/gfx/tests/test_group.html73
-rw-r--r--includes/js/dojox/gfx/tests/test_image1.html74
-rw-r--r--includes/js/dojox/gfx/tests/test_image2.html50
-rw-r--r--includes/js/dojox/gfx/tests/test_linearGradient.html80
-rw-r--r--includes/js/dojox/gfx/tests/test_linestyle.html45
-rw-r--r--includes/js/dojox/gfx/tests/test_pattern.html44
-rw-r--r--includes/js/dojox/gfx/tests/test_poly.html53
-rw-r--r--includes/js/dojox/gfx/tests/test_resize.html61
-rw-r--r--includes/js/dojox/gfx/tests/test_setPath.html76
-rw-r--r--includes/js/dojox/gfx/tests/test_tbbox.html117
-rw-r--r--includes/js/dojox/gfx/tests/test_text.html88
-rw-r--r--includes/js/dojox/gfx/tests/test_textpath.html76
-rw-r--r--includes/js/dojox/gfx/tests/test_transform.html98
-rw-r--r--includes/js/dojox/gfx/utils.js87
-rw-r--r--includes/js/dojox/gfx/vml.js1165
-rw-r--r--includes/js/dojox/gfx/vml_attach.js362
80 files changed, 19103 insertions, 0 deletions
diff --git a/includes/js/dojox/gfx/Moveable.js b/includes/js/dojox/gfx/Moveable.js
new file mode 100644
index 0000000..2717043
--- /dev/null
+++ b/includes/js/dojox/gfx/Moveable.js
@@ -0,0 +1,101 @@
+if(!dojo._hasResource["dojox.gfx.Moveable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.Moveable"] = true;
+dojo.provide("dojox.gfx.Moveable");
+
+dojo.require("dojox.gfx.Mover");
+
+dojo.declare("dojox.gfx.Moveable", null, {
+ constructor: function(shape, params){
+ // summary: an object, which makes a shape moveable
+ // shape: dojox.gfx.Shape: a shape object to be moved
+ // params: Object: an optional object with additional parameters;
+ // following parameters are recognized:
+ // delay: Number: delay move by this number of pixels
+ // mover: Object: a constructor of custom Mover
+ this.shape = shape;
+ this.delay = (params && params.delay > 0) ? params.delay : 0;
+ this.mover = (params && params.mover) ? params.mover : dojox.gfx.Mover;
+ this.events = [
+ this.shape.connect("onmousedown", this, "onMouseDown"),
+ // cancel text selection and text dragging
+ //dojo.connect(this.handle, "ondragstart", dojo, "stopEvent"),
+ //dojo.connect(this.handle, "onselectstart", dojo, "stopEvent")
+ ];
+ },
+
+ // methods
+ destroy: function(){
+ // summary: stops watching for possible move, deletes all references, so the object can be garbage-collected
+ dojo.forEach(this.events, this.shape.disconnect, this.shape);
+ this.events = this.shape = null;
+ },
+
+ // mouse event processors
+ onMouseDown: function(e){
+ // summary: event processor for onmousedown, creates a Mover for the shape
+ // e: Event: mouse event
+ if(this.delay){
+ this.events.push(this.shape.connect("onmousemove", this, "onMouseMove"));
+ this.events.push(this.shape.connect("onmouseup", this, "onMouseUp"));
+ this._lastX = e.clientX;
+ this._lastY = e.clientY;
+ }else{
+ new this.mover(this.shape, e, this);
+ }
+ dojo.stopEvent(e);
+ },
+ onMouseMove: function(e){
+ // summary: event processor for onmousemove, used only for delayed drags
+ // e: Event: mouse event
+ if(Math.abs(e.clientX - this._lastX) > this.delay || Math.abs(e.clientY - this._lastY) > this.delay){
+ this.onMouseUp(e);
+ new this.mover(this.shape, e, this);
+ }
+ dojo.stopEvent(e);
+ },
+ onMouseUp: function(e){
+ // summary: event processor for onmouseup, used only for delayed delayed drags
+ // e: Event: mouse event
+ this.shape.disconnect(this.events.pop());
+ this.shape.disconnect(this.events.pop());
+ },
+
+ // local events
+ onMoveStart: function(/* dojox.gfx.Mover */ mover){
+ // summary: called before every move operation
+ dojo.publish("/gfx/move/start", [mover]);
+ dojo.addClass(dojo.body(), "dojoMove");
+ },
+ onMoveStop: function(/* dojox.gfx.Mover */ mover){
+ // summary: called after every move operation
+ dojo.publish("/gfx/move/stop", [mover]);
+ dojo.removeClass(dojo.body(), "dojoMove");
+ },
+ onFirstMove: function(/* dojox.gfx.Mover */ mover){
+ // summary: called during the very first move notification,
+ // can be used to initialize coordinates, can be overwritten.
+
+ // default implementation does nothing
+ },
+ onMove: function(/* dojox.gfx.Mover */ mover, /* Object */ shift){
+ // summary: called during every move notification,
+ // should actually move the node, can be overwritten.
+ this.onMoving(mover, shift);
+ this.shape.applyLeftTransform(shift);
+ this.onMoved(mover, shift);
+ },
+ onMoving: function(/* dojox.gfx.Mover */ mover, /* Object */ shift){
+ // summary: called before every incremental move,
+ // can be overwritten.
+
+ // default implementation does nothing
+ },
+ onMoved: function(/* dojox.gfx.Mover */ mover, /* Object */ shift){
+ // summary: called after every incremental move,
+ // can be overwritten.
+
+ // default implementation does nothing
+ }
+});
+
+}
diff --git a/includes/js/dojox/gfx/Mover.js b/includes/js/dojox/gfx/Mover.js
new file mode 100644
index 0000000..6a5d456
--- /dev/null
+++ b/includes/js/dojox/gfx/Mover.js
@@ -0,0 +1,62 @@
+if(!dojo._hasResource["dojox.gfx.Mover"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.Mover"] = true;
+dojo.provide("dojox.gfx.Mover");
+
+dojo.declare("dojox.gfx.Mover", null, {
+ constructor: function(shape, e, host){
+ // summary: an object, which makes a shape follow the mouse,
+ // used as a default mover, and as a base class for custom movers
+ // shape: dojox.gfx.Shape: a shape object to be moved
+ // e: Event: a mouse event, which started the move;
+ // only clientX and clientY properties are used
+ // host: Object?: object which implements the functionality of the move,
+ // and defines proper events (onMoveStart and onMoveStop)
+ this.shape = shape;
+ this.lastX = e.clientX
+ this.lastY = e.clientY;
+ var h = this.host = host, d = document,
+ firstEvent = dojo.connect(d, "onmousemove", this, "onFirstMove");
+ this.events = [
+ dojo.connect(d, "onmousemove", this, "onMouseMove"),
+ dojo.connect(d, "onmouseup", this, "destroy"),
+ // cancel text selection and text dragging
+ dojo.connect(d, "ondragstart", dojo, "stopEvent"),
+ dojo.connect(d, "onselectstart", dojo, "stopEvent"),
+ firstEvent
+ ];
+ // notify that the move has started
+ if(h && h.onMoveStart){
+ h.onMoveStart(this);
+ }
+ },
+ // mouse event processors
+ onMouseMove: function(e){
+ // summary: event processor for onmousemove
+ // e: Event: mouse event
+ var x = e.clientX;
+ var y = e.clientY;
+ this.host.onMove(this, {dx: x - this.lastX, dy: y - this.lastY});
+ this.lastX = x;
+ this.lastY = y;
+ dojo.stopEvent(e);
+ },
+ // utilities
+ onFirstMove: function(){
+ // summary: it is meant to be called only once
+ this.host.onFirstMove(this);
+ dojo.disconnect(this.events.pop());
+ },
+ destroy: function(){
+ // summary: stops the move, deletes all references, so the object can be garbage-collected
+ dojo.forEach(this.events, dojo.disconnect);
+ // undo global settings
+ var h = this.host;
+ if(h && h.onMoveStop){
+ h.onMoveStop(this);
+ }
+ // destroy objects
+ this.events = this.shape = null;
+ }
+});
+
+}
diff --git a/includes/js/dojox/gfx/README b/includes/js/dojox/gfx/README
new file mode 100644
index 0000000..c318ddb
--- /dev/null
+++ b/includes/js/dojox/gfx/README
@@ -0,0 +1,102 @@
+-------------------------------------------------------------------------------
+dojox.gfx
+-------------------------------------------------------------------------------
+Version 1.100
+Release date: 08/01/2006
+-------------------------------------------------------------------------------
+Project state:
+beta
+HTMLCanvas renderer: experimental
+-------------------------------------------------------------------------------
+Credits
+ Eugene Lazutkin (eugene.lazutkin@gmail.com)
+ Kun Xi (bookstack@gmail.com)
+ Chris Mitchell (ccmitchellusa@gmail.com) HTML Canvas
+-------------------------------------------------------------------------------
+Project description
+
+Implementation of simple portable 2D graphics library.
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core
+-------------------------------------------------------------------------------
+Documentation
+
+Currently it can be found here: http://docs.google.com/Doc?id=d764479_1hnb2tn
+
+HTMLCanvas Renderer Status
+
+To use canvas rendering, insert 'canvas' at the beginning of the gfxRenderers list in your
+djConfig, for example:
+<script type="text/javascript" src="../../../dojo/dojo.js"
+ djConfig="parseOnLoad: true, gfxRenderer: 'canvas,svg,silverlight,vml'"></script>
+canvas currently will only render on non-IE browsers (see dojox/gfx.js for where the renderer is loaded);
+although it should be possible to use an IE canvas implementation (like Google's); however, it will be very slow.
+
+The following tests can be made to work with HTML Canvas with minor testcase modification:
+dojox/gfx/tests
+ test_gfx.html-Bugs #1
+ test_arc.html
+ test_bezier.html
+ test_pattern.html
+ test_gradient.html
+ test_linearGradient.html
+ test_image1.html - Limitation #3
+ test_transform.html - Bug #1
+ test_poly.html - Bug #1
+dojox/gfx/demos
+ butterfly.html - Bug #1
+ lion.html - Bug #1
+ tiger.html - Bug #1
+ circles.html - No event processing yet :(
+ creator.html
+dojox/chart
+ test_pie2d.html - Dojo Charts on iPhone anyone? :)
+ test_chart2d.html -
+
+ // To make charts work, the following line needs to be added to the end of the
+ // Chart2D.js render() method (prior to return)
+ if(this.surface.render){this.surface.render()};
+
+Known Limitations:
+1) event handling- plan is to capture all events at canvas, perform intersect/hit
+ tests (not implemented) against scene graph, then propogate event to top-most
+ intersected shape. HtmlCanvas shape need intersectsStroke and intersectsBounds,
+ and intersects (region).
+2) SVG and VML are "live" scene graphs; eg. any state change to objects in the
+ scene automatically get rendered in next engine render pass. For canvas, it's
+ procedural, and current implementation requires application to call surface.render()
+ whenever scene needs to be updated. Plan is to do dirty region checking based
+ on bounding boxes (currently not properly computed), and track dirty areas anytime
+ state changes (invalidate) separate from render phase.
+ Add the following call where changes to the scene graph are complete and you want to
+ render:
+
+ if (surface.render){surface.render();}
+
+4) Text/Text Paths - Text shape is implemented using DIV overlays. Many text styles are not
+ applied, and outline/fills are not possible. This is due to limitations in Canvas spec.
+ Firefox 3.0 has proprietary text functions that we could test for and use once FF3 is out.
+ No luck on Safari.
+3) No Image skewing - Limitation of Canvas
+
+Known Bugs:
+1) Matrix xformations (applied from root to shape leaf nodes) not quite right--but very close.
+ Canvas does not have a built in transformation function that allows skewing. Need to
+ track skew matrix with Shape, and perform other trans/rot/scale transformations without
+ using canvas transform functions.
+
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/gfx.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/gfx/*
+
+Install into the following directory structure:
+/dojox/gfx/
+
+...which should be at the same level as your Dojo checkout.
+-------------------------------------------------------------------------------
diff --git a/includes/js/dojox/gfx/_base.js b/includes/js/dojox/gfx/_base.js
new file mode 100644
index 0000000..3b118c2
--- /dev/null
+++ b/includes/js/dojox/gfx/_base.js
@@ -0,0 +1,288 @@
+if(!dojo._hasResource["dojox.gfx._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx._base"] = true;
+dojo.provide("dojox.gfx._base");
+
+(function(){
+ var g = dojox.gfx, b = g._base;
+
+ // candidates for dojox.style (work on VML and SVG nodes)
+ g._hasClass = function(/*DomNode*/node, /*String*/classStr){
+ // summary:
+ // Returns whether or not the specified classes are a portion of the
+ // class list currently applied to the node.
+ // return (new RegExp('(^|\\s+)'+classStr+'(\\s+|$)')).test(node.className) // Boolean
+ return ((" "+node.getAttribute("className")+" ").indexOf(" "+classStr+" ") >= 0); // Boolean
+ }
+ g._addClass = function(/*DomNode*/node, /*String*/classStr){
+ // summary:
+ // Adds the specified classes to the end of the class list on the
+ // passed node.
+ var cls = node.getAttribute("className");
+ if((" "+cls+" ").indexOf(" "+classStr+" ") < 0){
+ node.setAttribute("className", cls + (cls ? ' ' : '') + classStr);
+ }
+ }
+ g._removeClass = function(/*DomNode*/node, /*String*/classStr){
+ // summary: Removes classes from node.
+ node.setAttribute("className", node.getAttribute("className").replace(new RegExp('(^|\\s+)'+classStr+'(\\s+|$)'), "$1$2"));
+ }
+
+
+ // candidate for dojox.html.metrics (dynamic font resize handler is not implemented here)
+
+ // derived from Morris John's emResized measurer
+ b._getFontMeasurements = function(){
+ // summary
+ // Returns an object that has pixel equivilents of standard font size values.
+ var heights = {
+ '1em':0, '1ex':0, '100%':0, '12pt':0, '16px':0, 'xx-small':0, 'x-small':0,
+ 'small':0, 'medium':0, 'large':0, 'x-large':0, 'xx-large':0
+ };
+
+ if(dojo.isIE){
+ // we do a font-size fix if and only if one isn't applied already.
+ // NOTE: If someone set the fontSize on the HTML Element, this will kill it.
+ dojo.doc.documentElement.style.fontSize="100%";
+ }
+
+ // set up the measuring node.
+ var div=dojo.doc.createElement("div");
+ div.style.position="absolute";
+ div.style.left="-100px";
+ div.style.top="0";
+ div.style.width="30px";
+ div.style.height="1000em";
+ div.style.border="0";
+ div.style.margin="0";
+ div.style.padding="0";
+ div.style.outline="0";
+ div.style.lineHeight="1";
+ div.style.overflow="hidden";
+ dojo.body().appendChild(div);
+
+ // do the measurements.
+ for(var p in heights){
+ div.style.fontSize = p;
+ heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000;
+ }
+
+ dojo.body().removeChild(div);
+ div = null;
+ return heights; // object
+ };
+
+ var fontMeasurements = null;
+
+ b._getCachedFontMeasurements = function(recalculate){
+ if(recalculate || !fontMeasurements){
+ fontMeasurements = b._getFontMeasurements();
+ }
+ return fontMeasurements;
+ };
+
+ // candidate for dojox.html.metrics
+
+ var measuringNode = null, empty = {};
+ b._getTextBox = function(/* String */ text, /* Object */ style, /* String? */ className){
+ var m;
+ if(!measuringNode){
+ m = measuringNode = dojo.doc.createElement("div");
+ m.style.position = "absolute";
+ m.style.left = "-10000px";
+ m.style.top = "0";
+ dojo.body().appendChild(m);
+ }else{
+ m = measuringNode;
+ }
+ // reset styles
+ m.className = "";
+ m.style.border = "0";
+ m.style.margin = "0";
+ m.style.padding = "0";
+ m.style.outline = "0";
+ // set new style
+ if(arguments.length > 1 && style){
+ for(var i in style){
+ if(i in empty){ continue; }
+ m.style[i] = style[i];
+ }
+ }
+ // set classes
+ if(arguments.length > 2 && className){
+ m.className = className;
+ }
+ // take a measure
+ m.innerHTML = text;
+ return dojo.marginBox(m);
+ };
+
+ // candidate for dojo.dom
+
+ var uniqueId = 0;
+ b._getUniqueId = function(){
+ // summary: returns a unique string for use with any DOM element
+ var id;
+ do{
+ id = dojo._scopeName + "Unique" + (++uniqueId);
+ }while(dojo.byId(id));
+ return id;
+ };
+})();
+
+dojo.mixin(dojox.gfx, {
+ // summary: defines constants, prototypes, and utility functions
+
+ // default shapes, which are used to fill in missing parameters
+ defaultPath: {type: "path", path: ""},
+ defaultPolyline: {type: "polyline", points: []},
+ defaultRect: {type: "rect", x: 0, y: 0, width: 100, height: 100, r: 0},
+ defaultEllipse: {type: "ellipse", cx: 0, cy: 0, rx: 200, ry: 100},
+ defaultCircle: {type: "circle", cx: 0, cy: 0, r: 100},
+ defaultLine: {type: "line", x1: 0, y1: 0, x2: 100, y2: 100},
+ defaultImage: {type: "image", x: 0, y: 0, width: 0, height: 0, src: ""},
+ defaultText: {type: "text", x: 0, y: 0, text: "",
+ align: "start", decoration: "none", rotated: false, kerning: true },
+ defaultTextPath: {type: "textpath", text: "",
+ align: "start", decoration: "none", rotated: false, kerning: true },
+
+ // default geometric attributes
+ defaultStroke: {type: "stroke", color: "black", style: "solid", width: 1, cap: "butt", join: 4},
+ defaultLinearGradient: {type: "linear", x1: 0, y1: 0, x2: 100, y2: 100,
+ colors: [{offset: 0, color: "black"}, {offset: 1, color: "white"}]},
+ defaultRadialGradient: {type: "radial", cx: 0, cy: 0, r: 100,
+ colors: [{offset: 0, color: "black"}, {offset: 1, color: "white"}]},
+ defaultPattern: {type: "pattern", x: 0, y: 0, width: 0, height: 0, src: ""},
+ defaultFont: {type: "font", style: "normal", variant: "normal", weight: "normal",
+ size: "10pt", family: "serif"},
+
+ normalizeColor: function(/*Color*/ color){
+ // summary: converts any legal color representation to normalized dojo.Color object
+ return (color instanceof dojo.Color) ? color : new dojo.Color(color); // dojo.Color
+ },
+ normalizeParameters: function(existed, update){
+ // summary: updates an existing object with properties from an "update" object
+ // existed: Object: the "target" object to be updated
+ // update: Object: the "update" object, whose properties will be used to update the existed object
+ if(update){
+ var empty = {};
+ for(var x in existed){
+ if(x in update && !(x in empty)){
+ existed[x] = update[x];
+ }
+ }
+ }
+ return existed; // Object
+ },
+ makeParameters: function(defaults, update){
+ // summary: copies the original object, and all copied properties from the "update" object
+ // defaults: Object: the object to be cloned before updating
+ // update: Object: the object, which properties are to be cloned during updating
+ if(!update) return dojo.clone(defaults);
+ var result = {};
+ for(var i in defaults){
+ if(!(i in result)){
+ result[i] = dojo.clone((i in update) ? update[i] : defaults[i]);
+ }
+ }
+ return result; // Object
+ },
+ formatNumber: function(x, addSpace){
+ // summary: converts a number to a string using a fixed notation
+ // x: Number: number to be converted
+ // addSpace: Boolean?: if it is true, add a space before a positive number
+ var val = x.toString();
+ if(val.indexOf("e") >= 0){
+ val = x.toFixed(4);
+ }else{
+ var point = val.indexOf(".");
+ if(point >= 0 && val.length - point > 5){
+ val = x.toFixed(4);
+ }
+ }
+ if(x < 0){
+ return val; // String
+ }
+ return addSpace ? " " + val : val; // String
+ },
+ // font operations
+ makeFontString: function(font){
+ // summary: converts a font object to a CSS font string
+ // font: Object: font object (see dojox.gfx.defaultFont)
+ return font.style + " " + font.variant + " " + font.weight + " " + font.size + " " + font.family; // Object
+ },
+ splitFontString: function(str){
+ // summary: converts a CSS font string to a font object
+ // str: String: a CSS font string
+ var font = dojo.clone(dojox.gfx.defaultFont);
+ var t = str.split(/\s+/);
+ do{
+ if(t.length < 5){ break; }
+ font.style = t[0];
+ font.varian = t[1];
+ font.weight = t[2];
+ var i = t[3].indexOf("/");
+ font.size = i < 0 ? t[3] : t[3].substring(0, i);
+ var j = 4;
+ if(i < 0){
+ if(t[4] == "/"){
+ j = 6;
+ break;
+ }
+ if(t[4].substr(0, 1) == "/"){
+ j = 5;
+ break;
+ }
+ }
+ if(j + 3 > t.length){ break; }
+ font.size = t[j];
+ font.family = t[j + 1];
+ }while(false);
+ return font; // Object
+ },
+ // length operations
+ cm_in_pt: 72 / 2.54, // Number: centimeters per inch
+ mm_in_pt: 7.2 / 2.54, // Number: millimeters per inch
+ px_in_pt: function(){
+ // summary: returns a number of pixels per point
+ return dojox.gfx._base._getCachedFontMeasurements()["12pt"] / 12; // Number
+ },
+ pt2px: function(len){
+ // summary: converts points to pixels
+ // len: Number: a value in points
+ return len * dojox.gfx.px_in_pt(); // Number
+ },
+ px2pt: function(len){
+ // summary: converts pixels to points
+ // len: Number: a value in pixels
+ return len / dojox.gfx.px_in_pt(); // Number
+ },
+ normalizedLength: function(len) {
+ // summary: converts any length value to pixels
+ // len: String: a length, e.g., "12pc"
+ if(len.length == 0) return 0;
+ if(len.length > 2){
+ var px_in_pt = dojox.gfx.px_in_pt();
+ var val = parseFloat(len);
+ switch(len.slice(-2)){
+ case "px": return val;
+ case "pt": return val * px_in_pt;
+ case "in": return val * 72 * px_in_pt;
+ case "pc": return val * 12 * px_in_pt;
+ case "mm": return val / dojox.gfx.mm_in_pt * px_in_pt;
+ case "cm": return val / dojox.gfx.cm_in_pt * px_in_pt;
+ }
+ }
+ return parseFloat(len); // Number
+ },
+
+ // a constant used to split a SVG/VML path into primitive components
+ pathVmlRegExp: /([A-Za-z]+)|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
+ pathSvgRegExp: /([A-Za-z])|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
+
+ equalSources: function(a, b){
+ // summary: compares event sources, returns true if they are equal
+ return a && b && a == b;
+ }
+});
+
+}
diff --git a/includes/js/dojox/gfx/arc.js b/includes/js/dojox/gfx/arc.js
new file mode 100644
index 0000000..4a0eade
--- /dev/null
+++ b/includes/js/dojox/gfx/arc.js
@@ -0,0 +1,122 @@
+if(!dojo._hasResource["dojox.gfx.arc"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.arc"] = true;
+dojo.provide("dojox.gfx.arc");
+
+dojo.require("dojox.gfx.matrix");
+
+(function(){
+ var m = dojox.gfx.matrix,
+ unitArcAsBezier = function(alpha){
+ // summary: return a start point, 1st and 2nd control points, and an end point of
+ // a an arc, which is reflected on the x axis
+ // alpha: Number: angle in radians, the arc will be 2 * angle size
+ var cosa = Math.cos(alpha), sina = Math.sin(alpha),
+ p2 = {x: cosa + (4 / 3) * (1 - cosa), y: sina - (4 / 3) * cosa * (1 - cosa) / sina};
+ return { // Object
+ s: {x: cosa, y: -sina},
+ c1: {x: p2.x, y: -p2.y},
+ c2: p2,
+ e: {x: cosa, y: sina}
+ };
+ },
+ twoPI = 2 * Math.PI, pi4 = Math.PI / 4, pi8 = Math.PI / 8,
+ pi48 = pi4 + pi8, curvePI4 = unitArcAsBezier(pi8);
+
+ dojo.mixin(dojox.gfx.arc, {
+ unitArcAsBezier: unitArcAsBezier,
+ curvePI4: curvePI4,
+ arcAsBezier: function(last, rx, ry, xRotg, large, sweep, x, y){
+ // summary: calculates an arc as a series of Bezier curves
+ // given the last point and a standard set of SVG arc parameters,
+ // it returns an array of arrays of parameters to form a series of
+ // absolute Bezier curves.
+ // last: Object: a point-like object as a start of the arc
+ // rx: Number: a horizontal radius for the virtual ellipse
+ // ry: Number: a vertical radius for the virtual ellipse
+ // xRotg: Number: a rotation of an x axis of the virtual ellipse in degrees
+ // large: Boolean: which part of the ellipse will be used (the larger arc if true)
+ // sweep: Boolean: direction of the arc (CW if true)
+ // x: Number: the x coordinate of the end point of the arc
+ // y: Number: the y coordinate of the end point of the arc
+
+ // calculate parameters
+ large = Boolean(large);
+ sweep = Boolean(sweep);
+ var xRot = m._degToRad(xRotg),
+ rx2 = rx * rx, ry2 = ry * ry,
+ pa = m.multiplyPoint(
+ m.rotate(-xRot),
+ {x: (last.x - x) / 2, y: (last.y - y) / 2}
+ ),
+ pax2 = pa.x * pa.x, pay2 = pa.y * pa.y,
+ c1 = Math.sqrt((rx2 * ry2 - rx2 * pay2 - ry2 * pax2) / (rx2 * pay2 + ry2 * pax2));
+ if(isNaN(c1)){ c1 = 0; }
+ var ca = {
+ x: c1 * rx * pa.y / ry,
+ y: -c1 * ry * pa.x / rx
+ };
+ if(large == sweep){
+ ca = {x: -ca.x, y: -ca.y};
+ }
+ // the center
+ var c = m.multiplyPoint(
+ [
+ m.translate(
+ (last.x + x) / 2,
+ (last.y + y) / 2
+ ),
+ m.rotate(xRot)
+ ],
+ ca
+ );
+ // calculate the elliptic transformation
+ var elliptic_transform = m.normalize([
+ m.translate(c.x, c.y),
+ m.rotate(xRot),
+ m.scale(rx, ry)
+ ]);
+ // start, end, and size of our arc
+ var inversed = m.invert(elliptic_transform),
+ sp = m.multiplyPoint(inversed, last),
+ ep = m.multiplyPoint(inversed, x, y),
+ startAngle = Math.atan2(sp.y, sp.x),
+ endAngle = Math.atan2(ep.y, ep.x),
+ theta = startAngle - endAngle; // size of our arc in radians
+ if(sweep){ theta = -theta; }
+ if(theta < 0){
+ theta += twoPI;
+ }else if(theta > twoPI){
+ theta -= twoPI;
+ }
+
+ // draw curve chunks
+ var alpha = pi8, curve = curvePI4, step = sweep ? alpha : -alpha,
+ result = [];
+ for(var angle = theta; angle > 0; angle -= pi4){
+ if(angle < pi48){
+ alpha = angle / 2;
+ curve = unitArcAsBezier(alpha);
+ step = sweep ? alpha : -alpha;
+ angle = 0; // stop the loop
+ }
+ var c1, c2, e,
+ M = m.normalize([elliptic_transform, m.rotate(startAngle + step)]);
+ if(sweep){
+ c1 = m.multiplyPoint(M, curve.c1);
+ c2 = m.multiplyPoint(M, curve.c2);
+ e = m.multiplyPoint(M, curve.e );
+ }else{
+ c1 = m.multiplyPoint(M, curve.c2);
+ c2 = m.multiplyPoint(M, curve.c1);
+ e = m.multiplyPoint(M, curve.s );
+ }
+ // draw the curve
+ result.push([c1.x, c1.y, c2.x, c2.y, e.x, e.y]);
+ startAngle += 2 * step;
+ }
+ return result; // Object
+ }
+ });
+})();
+
+}
diff --git a/includes/js/dojox/gfx/attach.js b/includes/js/dojox/gfx/attach.js
new file mode 100644
index 0000000..901f66f
--- /dev/null
+++ b/includes/js/dojox/gfx/attach.js
@@ -0,0 +1,7 @@
+dojo.require("dojox.gfx");
+
+// include an attacher conditionally
+dojo.requireIf(dojox.gfx.renderer == "svg", "dojox.gfx.svg_attach");
+dojo.requireIf(dojox.gfx.renderer == "vml", "dojox.gfx.vml_attach");
+dojo.requireIf(dojox.gfx.renderer == "silverlight", "dojox.gfx.silverlight_attach");
+dojo.requireIf(dojox.gfx.renderer == "canvas", "dojox.gfx.canvas_attach");
diff --git a/includes/js/dojox/gfx/canvas.js b/includes/js/dojox/gfx/canvas.js
new file mode 100644
index 0000000..6872b2f
--- /dev/null
+++ b/includes/js/dojox/gfx/canvas.js
@@ -0,0 +1,687 @@
+if(!dojo._hasResource["dojox.gfx.canvas"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.canvas"] = true;
+dojo.provide("dojox.gfx.canvas");
+
+dojo.require("dojox.gfx._base");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojo.require("dojox.gfx.arc");
+dojo.require("dojox.gfx.decompose");
+
+dojo.experimental("dojox.gfx.canvas");
+
+(function(){
+ var g = dojox.gfx, gs = g.shape, ga = g.arc,
+ m = g.matrix, mp = m.multiplyPoint, pi = Math.PI, twoPI = 2 * pi, halfPI = pi /2;
+
+ dojo.extend(g.Shape, {
+ _render: function(/* Object */ ctx){
+ // summary: render the shape
+ ctx.save();
+ this._renderTransform(ctx);
+ this._renderShape(ctx);
+ this._renderFill(ctx, true);
+ this._renderStroke(ctx, true);
+ ctx.restore();
+ },
+ _renderTransform: function(/* Object */ ctx){
+ if("canvasTransform" in this){
+ var t = this.canvasTransform;
+ ctx.translate(t.dx, t.dy);
+ ctx.rotate(t.angle2);
+ ctx.scale(t.sx, t.sy);
+ ctx.rotate(t.angle1);
+ // The future implementation when vendors catch up with the spec:
+ // var t = this.matrix;
+ // ctx.transform(t.xx, t.yx, t.xy, t.yy, t.dx, t.dy);
+ }
+ },
+ _renderShape: function(/* Object */ ctx){
+ // nothing
+ },
+ _renderFill: function(/* Object */ ctx, /* Boolean */ apply){
+ if("canvasFill" in this){
+ if("canvasFillImage" in this){
+ this.canvasFill = ctx.createPattern(this.canvasFillImage, "repeat");
+ delete this.canvasFillImage;
+ }
+ ctx.fillStyle = this.canvasFill;
+ if(apply){ ctx.fill(); }
+ }else{
+ ctx.fillStyle = "rgba(0,0,0,0.0)";
+ }
+ },
+ _renderStroke: function(/* Object */ ctx, /* Boolean */ apply){
+ var s = this.strokeStyle;
+ if(s){
+ ctx.strokeStyle = s.color.toString();
+ ctx.lineWidth = s.width;
+ ctx.lineCap = s.cap;
+ if(typeof s.join == "number"){
+ ctx.lineJoin = "miter";
+ ctx.miterLimit = s.join;
+ }else{
+ ctx.lineJoin = s.join;
+ }
+ if(apply){ ctx.stroke(); }
+ }else if(!apply){
+ ctx.strokeStyle = "rgba(0,0,0,0.0)";
+ }
+ },
+
+ // events are not implemented
+ getEventSource: function(){ return null; },
+ connect: function(){},
+ disconnect: function(){}
+ });
+
+ var modifyMethod = function(shape, method, extra){
+ var old = shape.prototype[method];
+ shape.prototype[method] = extra ?
+ function(){
+ this.surface.makeDirty();
+ old.apply(this, arguments);
+ extra.call(this);
+ return this;
+ } :
+ function(){
+ this.surface.makeDirty();
+ return old.apply(this, arguments);
+ };
+ };
+
+ modifyMethod(g.Shape, "setTransform",
+ function(){
+ // prepare Canvas-specific structures
+ if(this.matrix){
+ this.canvasTransform = g.decompose(this.matrix);
+ }else{
+ delete this.canvasTransform;
+ }
+ });
+
+ modifyMethod(g.Shape, "setFill",
+ function(){
+ // prepare Canvas-specific structures
+ var fs = this.fillStyle, f;
+ if(fs){
+ if(typeof(fs) == "object" && "type" in fs){
+ var ctx = this.surface.rawNode.getContext("2d");
+ switch(fs.type){
+ case "linear":
+ case "radial":
+ f = fs.type == "linear" ?
+ ctx.createLinearGradient(fs.x1, fs.y1, fs.x2, fs.y2) :
+ ctx.createRadialGradient(fs.cx, fs.cy, 0, fs.cx, fs.cy, fs.r);
+ dojo.forEach(fs.colors, function(step){
+ f.addColorStop(step.offset, g.normalizeColor(step.color).toString());
+ });
+ break;
+ case "pattern":
+ var img = new Image(fs.width, fs.height);
+ this.surface.downloadImage(img, fs.src);
+ this.canvasFillImage = img;
+ }
+ }else{
+ // Set fill color using CSS RGBA func style
+ f = fs.toString();
+ }
+ this.canvasFill = f;
+ }else{
+ delete this.canvasFill;
+ }
+ });
+
+ modifyMethod(g.Shape, "setStroke");
+ modifyMethod(g.Shape, "setShape");
+
+ dojo.declare("dojox.gfx.Group", g.Shape, {
+ // summary: a group shape (Canvas), which can be used
+ // to logically group shapes (e.g, to propagate matricies)
+ constructor: function(){
+ gs.Container._init.call(this);
+ },
+ _render: function(/* Object */ ctx){
+ // summary: render the group
+ ctx.save();
+ this._renderTransform(ctx);
+ this._renderFill(ctx);
+ this._renderStroke(ctx);
+ for(var i = 0; i < this.children.length; ++i){
+ this.children[i]._render(ctx);
+ }
+ ctx.restore();
+ }
+ });
+
+ dojo.declare("dojox.gfx.Rect", gs.Rect, {
+ // summary: a rectangle shape (Canvas)
+ _renderShape: function(/* Object */ ctx){
+ var s = this.shape, r = Math.min(s.r, s.height / 2, s.width / 2),
+ xl = s.x, xr = xl + s.width, yt = s.y, yb = yt + s.height,
+ xl2 = xl + r, xr2 = xr - r, yt2 = yt + r, yb2 = yb - r;
+ ctx.beginPath();
+ ctx.moveTo(xl2, yt);
+ if(r){
+ ctx.arc(xr2, yt2, r, -halfPI, 0, false);
+ ctx.arc(xr2, yb2, r, 0, halfPI, false);
+ ctx.arc(xl2, yb2, r, halfPI, pi, false);
+ ctx.arc(xl2, yt2, r, pi, halfPI, false);
+ }else{
+ ctx.lineTo(xr2, yt);
+ ctx.lineTo(xr, yb2);
+ ctx.lineTo(xl2, yb);
+ ctx.lineTo(xl, yt2);
+ }
+ ctx.closePath();
+ }
+ });
+
+ var bezierCircle = [];
+ (function(){
+ var u = ga.curvePI4;
+ bezierCircle.push(u.s, u.c1, u.c2, u.e);
+ for(var a = 45; a < 360; a += 45){
+ var r = m.rotateg(a);
+ bezierCircle.push(mp(r, u.c1), mp(r, u.c2), mp(r, u.e));
+ }
+ })();
+
+ dojo.declare("dojox.gfx.Ellipse", gs.Ellipse, {
+ // summary: an ellipse shape (Canvas)
+ setShape: function(){
+ g.Ellipse.superclass.setShape.apply(this, arguments);
+ // prepare Canvas-specific structures
+ var s = this.shape, t, c1, c2, r = [],
+ M = m.normalize([m.translate(s.cx, s.cy), m.scale(s.rx, s.ry)]);
+ t = mp(M, bezierCircle[0]);
+ r.push([t.x, t.y]);
+ for(var i = 1; i < bezierCircle.length; i += 3){
+ c1 = mp(M, bezierCircle[i]);
+ c2 = mp(M, bezierCircle[i + 1]);
+ t = mp(M, bezierCircle[i + 2]);
+ r.push([c1.x, c1.y, c2.x, c2.y, t.x, t.y]);
+ }
+ this.canvasEllipse = r;
+ return this;
+ },
+ _renderShape: function(/* Object */ ctx){
+ var r = this.canvasEllipse;
+ ctx.beginPath();
+ ctx.moveTo.apply(ctx, r[0]);
+ for(var i = 1; i < r.length; ++i){
+ ctx.bezierCurveTo.apply(ctx, r[i]);
+ }
+ ctx.closePath();
+ }
+ });
+
+ dojo.declare("dojox.gfx.Circle", gs.Circle, {
+ // summary: a circle shape (Canvas)
+ _renderShape: function(/* Object */ ctx){
+ var s = this.shape;
+ ctx.beginPath();
+ ctx.arc(s.cx, s.cy, s.r, 0, twoPI, 1);
+ }
+ });
+
+ dojo.declare("dojox.gfx.Line", gs.Line, {
+ // summary: a line shape (Canvas)
+ _renderShape: function(/* Object */ ctx){
+ var s = this.shape;
+ ctx.beginPath();
+ ctx.moveTo(s.x1, s.y1);
+ ctx.lineTo(s.x2, s.y2);
+ }
+ });
+
+ dojo.declare("dojox.gfx.Polyline", gs.Polyline, {
+ // summary: a polyline/polygon shape (Canvas)
+ setShape: function(){
+ g.Polyline.superclass.setShape.apply(this, arguments);
+ // dojo.inherited("setShape", arguments);
+ // prepare Canvas-specific structures
+ var p = this.shape.points, f = p[0], r = [], c, i;
+ if(p.length){
+ if(typeof f == "number"){
+ r.push(f, p[1]);
+ i = 2;
+ }else{
+ r.push(f.x, f.y);
+ i = 1;
+ }
+ for(; i < p.length; ++i){
+ c = p[i];
+ if(typeof c == "number"){
+ r.push(c, p[++i]);
+ }else{
+ r.push(c.x, c.y);
+ }
+ }
+ }
+ this.canvasPolyline = r;
+ return this;
+ },
+ _renderShape: function(/* Object */ ctx){
+ // console.debug("Polyline::_renderShape");
+ var p = this.canvasPolyline;
+ if(p.length){
+ ctx.beginPath();
+ ctx.moveTo(p[0], p[1]);
+ for(var i = 2; i < p.length; i += 2){
+ ctx.lineTo(p[i], p[i + 1]);
+ }
+ }
+ }
+ });
+
+ dojo.declare("dojox.gfx.Image", gs.Image, {
+ // summary: an image shape (Canvas)
+ setShape: function(){
+ g.Image.superclass.setShape.apply(this, arguments);
+ // prepare Canvas-specific structures
+ var img = new Image();
+ this.surface.downloadImage(img, this.shape.src);
+ this.canvasImage = img;
+ return this;
+ },
+ _renderShape: function(/* Object */ ctx){
+ var s = this.shape;
+ ctx.drawImage(this.canvasImage, s.x, s.y, s.width, s.height);
+ }
+ });
+
+ dojo.declare("dojox.gfx.Text", gs.Text, {
+ // summary: a text shape (Canvas)
+ _renderShape: function(/* Object */ ctx){
+ var s = this.shape;
+ // nothing for the moment
+ }
+ });
+ modifyMethod(g.Text, "setFont");
+
+ var pathRenderers = {
+ M: "_moveToA", m: "_moveToR",
+ L: "_lineToA", l: "_lineToR",
+ H: "_hLineToA", h: "_hLineToR",
+ V: "_vLineToA", v: "_vLineToR",
+ C: "_curveToA", c: "_curveToR",
+ S: "_smoothCurveToA", s: "_smoothCurveToR",
+ Q: "_qCurveToA", q: "_qCurveToR",
+ T: "_qSmoothCurveToA", t: "_qSmoothCurveToR",
+ A: "_arcTo", a: "_arcTo",
+ Z: "_closePath", z: "_closePath"
+ };
+
+ dojo.declare("dojox.gfx.Path", g.path.Path, {
+ // summary: a path shape (Canvas)
+ constructor: function(){
+ this.last = {};
+ this.lastControl = {};
+ },
+ setShape: function(){
+ this.canvasPath = [];
+ return g.Path.superclass.setShape.apply(this, arguments);
+ },
+ _updateWithSegment: function(segment){
+ var last = dojo.clone(this.last);
+ this[pathRenderers[segment.action]](this.canvasPath, segment.action, segment.args);
+ this.last = last;
+ g.Path.superclass._updateWithSegment.apply(this, arguments);
+ },
+ _renderShape: function(/* Object */ ctx){
+ var r = this.canvasPath;
+ ctx.beginPath();
+ for(var i = 0; i < r.length; i += 2){
+ ctx[r[i]].apply(ctx, r[i + 1]);
+ }
+ },
+ _moveToA: function(result, action, args){
+ result.push("moveTo", [args[0], args[1]]);
+ for(var i = 2; i < args.length; i += 2){
+ result.push("lineTo", [args[i], args[i + 1]]);
+ }
+ this.last.x = args[args.length - 2];
+ this.last.y = args[args.length - 1];
+ this.lastControl = {};
+ },
+ _moveToR: function(result, action, args){
+ if("x" in this.last){
+ result.push("moveTo", [this.last.x += args[0], this.last.y += args[1]]);
+ }else{
+ result.push("moveTo", [this.last.x = args[0], this.last.y = args[1]]);
+ }
+ for(var i = 2; i < args.length; i += 2){
+ result.push("lineTo", [this.last.x += args[i], this.last.y += args[i + 1]]);
+ }
+ this.lastControl = {};
+ },
+ _lineToA: function(result, action, args){
+ for(var i = 0; i < args.length; i += 2){
+ result.push("lineTo", [args[i], args[i + 1]]);
+ }
+ this.last.x = args[args.length - 2];
+ this.last.y = args[args.length - 1];
+ this.lastControl = {};
+ },
+ _lineToR: function(result, action, args){
+ for(var i = 0; i < args.length; i += 2){
+ result.push("lineTo", [this.last.x += args[i], this.last.y += args[i + 1]]);
+ }
+ this.lastControl = {};
+ },
+ _hLineToA: function(result, action, args){
+ for(var i = 0; i < args.length; ++i){
+ result.push("lineTo", [args[i], this.last.y]);
+ }
+ this.last.x = args[args.length - 1];
+ this.lastControl = {};
+ },
+ _hLineToR: function(result, action, args){
+ for(var i = 0; i < args.length; ++i){
+ result.push("lineTo", [this.last.x += args[i], this.last.y]);
+ }
+ this.lastControl = {};
+ },
+ _vLineToA: function(result, action, args){
+ for(var i = 0; i < args.length; ++i){
+ result.push("lineTo", [this.last.x, args[i]]);
+ }
+ this.last.y = args[args.length - 1];
+ this.lastControl = {};
+ },
+ _vLineToR: function(result, action, args){
+ for(var i = 0; i < args.length; ++i){
+ result.push("lineTo", [this.last.x, this.last.y += args[i]]);
+ }
+ this.lastControl = {};
+ },
+ _curveToA: function(result, action, args){
+ for(var i = 0; i < args.length; i += 6){
+ result.push("bezierCurveTo", args.slice(i, i + 6));
+ }
+ this.last.x = args[args.length - 2];
+ this.last.y = args[args.length - 1];
+ this.lastControl.x = args[args.length - 4];
+ this.lastControl.y = args[args.length - 3];
+ this.lastControl.type = "C";
+ },
+ _curveToR: function(result, action, args){
+ for(var i = 0; i < args.length; i += 6){
+ result.push("bezierCurveTo", [
+ this.last.x + args[i],
+ this.last.y + args[i + 1],
+ this.lastControl.x = this.last.x + args[i + 2],
+ this.lastControl.y = this.last.y + args[i + 3],
+ this.last.x + args[i + 4],
+ this.last.y + args[i + 5]
+ ]);
+ this.last.x += args[i + 4];
+ this.last.y += args[i + 5];
+ }
+ this.lastControl.type = "C";
+ },
+ _smoothCurveToA: function(result, action, args){
+ for(var i = 0; i < args.length; i += 4){
+ var valid = this.lastControl.type == "C";
+ result.push("bezierCurveTo", [
+ valid ? 2 * this.last.x - this.lastControl.x : this.last.x,
+ valid ? 2 * this.last.y - this.lastControl.y : this.last.y,
+ args[i],
+ args[i + 1],
+ args[i + 2],
+ args[i + 3]
+ ]);
+ this.lastControl.x = args[i];
+ this.lastControl.y = args[i + 1];
+ this.lastControl.type = "C";
+ }
+ this.last.x = args[args.length - 2];
+ this.last.y = args[args.length - 1];
+ },
+ _smoothCurveToR: function(result, action, args){
+ for(var i = 0; i < args.length; i += 4){
+ var valid = this.lastControl.type == "C";
+ result.push("bezierCurveTo", [
+ valid ? 2 * this.last.x - this.lastControl.x : this.last.x,
+ valid ? 2 * this.last.y - this.lastControl.y : this.last.y,
+ this.last.x + args[i],
+ this.last.y + args[i + 1],
+ this.last.x + args[i + 2],
+ this.last.y + args[i + 3]
+ ]);
+ this.lastControl.x = this.last.x + args[i];
+ this.lastControl.y = this.last.y + args[i + 1];
+ this.lastControl.type = "C";
+ this.last.x += args[i + 2];
+ this.last.y += args[i + 3];
+ }
+ },
+ _qCurveToA: function(result, action, args){
+ for(var i = 0; i < args.length; i += 4){
+ result.push("quadraticCurveTo", args.slice(i, i + 4));
+ }
+ this.last.x = args[args.length - 2];
+ this.last.y = args[args.length - 1];
+ this.lastControl.x = args[args.length - 4];
+ this.lastControl.y = args[args.length - 3];
+ this.lastControl.type = "Q";
+ },
+ _qCurveToR: function(result, action, args){
+ for(var i = 0; i < args.length; i += 4){
+ result.push("quadraticCurveTo", [
+ this.lastControl.x = this.last.x + args[i],
+ this.lastControl.y = this.last.y + args[i + 1],
+ this.last.x + args[i + 2],
+ this.last.y + args[i + 3]
+ ]);
+ this.last.x += args[i + 2];
+ this.last.y += args[i + 3];
+ }
+ this.lastControl.type = "Q";
+ },
+ _qSmoothCurveToA: function(result, action, args){
+ for(var i = 0; i < args.length; i += 2){
+ var valid = this.lastControl.type == "Q";
+ result.push("quadraticCurveTo", [
+ this.lastControl.x = valid ? 2 * this.last.x - this.lastControl.x : this.last.x,
+ this.lastControl.y = valid ? 2 * this.last.y - this.lastControl.y : this.last.y,
+ args[i],
+ args[i + 1]
+ ]);
+ this.lastControl.type = "Q";
+ }
+ this.last.x = args[args.length - 2];
+ this.last.y = args[args.length - 1];
+ },
+ _qSmoothCurveToR: function(result, action, args){
+ for(var i = 0; i < args.length; i += 2){
+ var valid = this.lastControl.type == "Q";
+ result.push("quadraticCurveTo", [
+ this.lastControl.x = valid ? 2 * this.last.x - this.lastControl.x : this.last.x,
+ this.lastControl.y = valid ? 2 * this.last.y - this.lastControl.y : this.last.y,
+ this.last.x + args[i],
+ this.last.y + args[i + 1]
+ ]);
+ this.lastControl.type = "Q";
+ this.last.x += args[i];
+ this.last.y += args[i + 1];
+ }
+ },
+ _arcTo: function(result, action, args){
+ var relative = action == "a";
+ for(var i = 0; i < args.length; i += 7){
+ var x1 = args[i + 5], y1 = args[i + 6];
+ if(relative){
+ x1 += this.last.x;
+ y1 += this.last.y;
+ }
+ var arcs = ga.arcAsBezier(
+ this.last, args[i], args[i + 1], args[i + 2],
+ args[i + 3] ? 1 : 0, args[i + 4] ? 1 : 0,
+ x1, y1
+ );
+ dojo.forEach(arcs, function(p){
+ result.push("bezierCurveTo", p);
+ });
+ this.last.x = x1;
+ this.last.y = y1;
+ }
+ this.lastControl = {};
+ },
+ _closePath: function(result, action, args){
+ result.push("closePath", []);
+ this.lastControl = {};
+ }
+ });
+ dojo.forEach(["moveTo", "lineTo", "hLineTo", "vLineTo", "curveTo",
+ "smoothCurveTo", "qCurveTo", "qSmoothCurveTo", "arcTo", "closePath"],
+ function(method){ modifyMethod(g.Path, method); }
+ );
+
+ dojo.declare("dojox.gfx.TextPath", g.path.TextPath, {
+ // summary: a text shape (Canvas)
+ _renderShape: function(/* Object */ ctx){
+ var s = this.shape;
+ // nothing for the moment
+ }
+ });
+
+ dojo.declare("dojox.gfx.Surface", gs.Surface, {
+ // summary: a surface object to be used for drawings (Canvas)
+ constructor: function(){
+ gs.Container._init.call(this);
+ this.pendingImageCount = 0;
+ this.makeDirty();
+ },
+ setDimensions: function(width, height){
+ // summary: sets the width and height of the rawNode
+ // width: String: width of surface, e.g., "100px"
+ // height: String: height of surface, e.g., "100px"
+ this.width = g.normalizedLength(width); // in pixels
+ this.height = g.normalizedLength(height); // in pixels
+ if(!this.rawNode) return this;
+ this.rawNode.width = width;
+ this.rawNode.height = height;
+ this.makeDirty();
+ return this; // self
+ },
+ getDimensions: function(){
+ // summary: returns an object with properties "width" and "height"
+ return this.rawNode ? {width: this.rawNode.width, height: this.rawNode.height} : null; // Object
+ },
+ _render: function(){
+ // summary: render the all shapes
+ if(this.pendingImageCount){ return; }
+ var ctx = this.rawNode.getContext("2d");
+ ctx.save();
+ ctx.clearRect(0, 0, this.rawNode.width, this.rawNode.height);
+ for(var i = 0; i < this.children.length; ++i){
+ this.children[i]._render(ctx);
+ }
+ ctx.restore();
+ if("pendingRender" in this){
+ clearTimeout(this.pendingRender);
+ delete this.pendingRender;
+ }
+ },
+ makeDirty: function(){
+ // summary: internal method, which is called when we may need to redraw
+ if(!this.pendingImagesCount && !("pendingRender" in this)){
+ this.pendingRender = setTimeout(dojo.hitch(this, this._render), 0);
+ }
+ },
+ downloadImage: function(img, url){
+ // summary:
+ // internal method, which starts an image download and renders, when it is ready
+ // img: Image:
+ // the image object
+ // url: String:
+ // the url of the image
+ var handler = dojo.hitch(this, this.onImageLoad);
+ if(!this.pendingImageCount++ && "pendingRender" in this){
+ clearTimeout(this.pendingRender);
+ delete this.pendingRender;
+ }
+ img.onload = handler;
+ img.onerror = handler;
+ img.onabort = handler;
+ img.src = url;
+ },
+ onImageLoad: function(){
+ if(!--this.pendingImageCount){ this._render(); }
+ },
+
+ // events are not implemented
+ getEventSource: function(){ return null; },
+ connect: function(){},
+ disconnect: function(){}
+ });
+
+ g.createSurface = function(parentNode, width, height){
+ // summary: creates a surface (Canvas)
+ // parentNode: Node: a parent node
+ // width: String: width of surface, e.g., "100px"
+ // height: String: height of surface, e.g., "100px"
+
+ if(!width){ width = "100%"; }
+ if(!height){ height = "100%"; }
+ var s = new g.Surface(),
+ p = dojo.byId(parentNode),
+ c = p.ownerDocument.createElement("canvas");
+ c.width = width;
+ c.height = height;
+ p.appendChild(c);
+ s.rawNode = c;
+ s.surface = s;
+ return s; // dojox.gfx.Surface
+ };
+
+ // Extenders
+
+ var C = gs.Container, Container = {
+ add: function(shape){
+ this.surface.makeDirty();
+ return C.add.apply(this, arguments);
+ },
+ remove: function(shape, silently){
+ this.surface.makeDirty();
+ return C.remove.apply(this, arguments);
+ },
+ clear: function(){
+ this.surface.makeDirty();
+ return C.clear.apply(this, arguments);
+ },
+ _moveChildToFront: function(shape){
+ this.surface.makeDirty();
+ return C._moveChildToFront.apply(this, arguments);
+ },
+ _moveChildToBack: function(shape){
+ this.surface.makeDirty();
+ return C._moveChildToBack.apply(this, arguments);
+ }
+ };
+
+ dojo.mixin(gs.Creator, {
+ // summary: Canvas shape creators
+ createObject: function(shapeType, rawShape) {
+ // summary: creates an instance of the passed shapeType class
+ // shapeType: Function: a class constructor to create an instance of
+ // rawShape: Object: properties to be passed in to the classes "setShape" method
+ // overrideSize: Boolean: set the size explicitly, if true
+ var shape = new shapeType();
+ shape.surface = this.surface;
+ shape.setShape(rawShape);
+ this.add(shape);
+ return shape; // dojox.gfx.Shape
+ }
+ });
+
+ dojo.extend(g.Group, Container);
+ dojo.extend(g.Group, gs.Creator);
+
+ dojo.extend(g.Surface, Container);
+ dojo.extend(g.Surface, gs.Creator);
+})();
+
+}
diff --git a/includes/js/dojox/gfx/canvas_attach.js b/includes/js/dojox/gfx/canvas_attach.js
new file mode 100644
index 0000000..82ccd13
--- /dev/null
+++ b/includes/js/dojox/gfx/canvas_attach.js
@@ -0,0 +1,8 @@
+dojo.require("dojox.gfx.canvas");
+
+dojo.experimental("dojox.gfx.canvas_attach");
+
+// not implemented
+dojox.gfx.attachNode = function(){
+ return null; // for now
+};
diff --git a/includes/js/dojox/gfx/decompose.js b/includes/js/dojox/gfx/decompose.js
new file mode 100644
index 0000000..4e34ee6
--- /dev/null
+++ b/includes/js/dojox/gfx/decompose.js
@@ -0,0 +1,139 @@
+if(!dojo._hasResource["dojox.gfx.decompose"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.decompose"] = true;
+dojo.provide("dojox.gfx.decompose");
+
+dojo.require("dojox.gfx.matrix");
+
+(function(){
+ var m = dojox.gfx.matrix;
+
+ var eq = function(/* Number */ a, /* Number */ b){
+ // summary: compare two FP numbers for equality
+ return Math.abs(a - b) <= 1e-6 * (Math.abs(a) + Math.abs(b)); // Boolean
+ };
+
+ var calcFromValues = function(/* Number */ r1, /* Number */ m1, /* Number */ r2, /* Number */ m2){
+ // summary: uses two close FP ration and their original magnitudes to approximate the result
+ if(!isFinite(r1)){
+ return r2; // Number
+ }else if(!isFinite(r2)){
+ return r1; // Number
+ }
+ m1 = Math.abs(m1), m2 = Math.abs(m2);
+ return (m1 * r1 + m2 * r2) / (m1 + m2); // Number
+ };
+
+ var transpose = function(/* dojox.gfx.matrix.Matrix2D */ matrix){
+ // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object
+ var M = new m.Matrix2D(matrix);
+ return dojo.mixin(M, {dx: 0, dy: 0, xy: M.yx, yx: M.xy}); // dojox.gfx.matrix.Matrix2D
+ };
+
+ var scaleSign = function(/* dojox.gfx.matrix.Matrix2D */ matrix){
+ return (matrix.xx * matrix.yy < 0 || matrix.xy * matrix.yx > 0) ? -1 : 1; // Number
+ };
+
+ var eigenvalueDecomposition = function(/* dojox.gfx.matrix.Matrix2D */ matrix){
+ // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object
+ var M = m.normalize(matrix),
+ b = -M.xx - M.yy,
+ c = M.xx * M.yy - M.xy * M.yx,
+ d = Math.sqrt(b * b - 4 * c),
+ l1 = -(b + (b < 0 ? -d : d)) / 2,
+ l2 = c / l1,
+ vx1 = M.xy / (l1 - M.xx), vy1 = 1,
+ vx2 = M.xy / (l2 - M.xx), vy2 = 1;
+ if(eq(l1, l2)){
+ vx1 = 1, vy1 = 0, vx2 = 0, vy2 = 1;
+ }
+ if(!isFinite(vx1)){
+ vx1 = 1, vy1 = (l1 - M.xx) / M.xy;
+ if(!isFinite(vy1)){
+ vx1 = (l1 - M.yy) / M.yx, vy1 = 1;
+ if(!isFinite(vx1)){
+ vx1 = 1, vy1 = M.yx / (l1 - M.yy);
+ }
+ }
+ }
+ if(!isFinite(vx2)){
+ vx2 = 1, vy2 = (l2 - M.xx) / M.xy;
+ if(!isFinite(vy2)){
+ vx2 = (l2 - M.yy) / M.yx, vy2 = 1;
+ if(!isFinite(vx2)){
+ vx2 = 1, vy2 = M.yx / (l2 - M.yy);
+ }
+ }
+ }
+ var d1 = Math.sqrt(vx1 * vx1 + vy1 * vy1),
+ d2 = Math.sqrt(vx2 * vx2 + vy2 * vy2);
+ if(!isFinite(vx1 /= d1)){ vx1 = 0; }
+ if(!isFinite(vy1 /= d1)){ vy1 = 0; }
+ if(!isFinite(vx2 /= d2)){ vx2 = 0; }
+ if(!isFinite(vy2 /= d2)){ vy2 = 0; }
+ return { // Object
+ value1: l1,
+ value2: l2,
+ vector1: {x: vx1, y: vy1},
+ vector2: {x: vx2, y: vy2}
+ };
+ };
+
+ var decomposeSR = function(/* dojox.gfx.matrix.Matrix2D */ M, /* Object */ result){
+ // summary: decomposes a matrix into [scale, rotate]; no checks are done.
+ var sign = scaleSign(M),
+ a = result.angle1 = (Math.atan2(M.yx, M.yy) + Math.atan2(-sign * M.xy, sign * M.xx)) / 2,
+ cos = Math.cos(a), sin = Math.sin(a);
+ result.sx = calcFromValues(M.xx / cos, cos, -M.xy / sin, sin);
+ result.sy = calcFromValues(M.yy / cos, cos, M.yx / sin, sin);
+ return result; // Object
+ };
+
+ var decomposeRS = function(/* dojox.gfx.matrix.Matrix2D */ M, /* Object */ result){
+ // summary: decomposes a matrix into [rotate, scale]; no checks are done
+ var sign = scaleSign(M),
+ a = result.angle2 = (Math.atan2(sign * M.yx, sign * M.xx) + Math.atan2(-M.xy, M.yy)) / 2,
+ cos = Math.cos(a), sin = Math.sin(a);
+ result.sx = calcFromValues(M.xx / cos, cos, M.yx / sin, sin);
+ result.sy = calcFromValues(M.yy / cos, cos, -M.xy / sin, sin);
+ return result; // Object
+ };
+
+ dojox.gfx.decompose = function(matrix){
+ // summary: decompose a 2D matrix into translation, scaling, and rotation components
+ // description: this function decompose a matrix into four logical components:
+ // translation, rotation, scaling, and one more rotation using SVD.
+ // The components should be applied in following order:
+ // | [translate, rotate(angle2), scale, rotate(angle1)]
+ // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object
+ var M = m.normalize(matrix),
+ result = {dx: M.dx, dy: M.dy, sx: 1, sy: 1, angle1: 0, angle2: 0};
+ // detect case: [scale]
+ if(eq(M.xy, 0) && eq(M.yx, 0)){
+ return dojo.mixin(result, {sx: M.xx, sy: M.yy}); // Object
+ }
+ // detect case: [scale, rotate]
+ if(eq(M.xx * M.yx, -M.xy * M.yy)){
+ return decomposeSR(M, result); // Object
+ }
+ // detect case: [rotate, scale]
+ if(eq(M.xx * M.xy, -M.yx * M.yy)){
+ return decomposeRS(M, result); // Object
+ }
+ // do SVD
+ var MT = transpose(M),
+ u = eigenvalueDecomposition([M, MT]),
+ v = eigenvalueDecomposition([MT, M]),
+ U = new m.Matrix2D({xx: u.vector1.x, xy: u.vector2.x, yx: u.vector1.y, yy: u.vector2.y}),
+ VT = new m.Matrix2D({xx: v.vector1.x, xy: v.vector1.y, yx: v.vector2.x, yy: v.vector2.y}),
+ S = new m.Matrix2D([m.invert(U), M, m.invert(VT)]);
+ decomposeSR(VT, result);
+ S.xx *= result.sx;
+ S.yy *= result.sy;
+ decomposeRS(U, result);
+ S.xx *= result.sx;
+ S.yy *= result.sy;
+ return dojo.mixin(result, {sx: S.xx, sy: S.yy}); // Object
+ };
+})();
+
+}
diff --git a/includes/js/dojox/gfx/demos/beautify.html b/includes/js/dojox/gfx/demos/beautify.html
new file mode 100644
index 0000000..d1f02f5
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/beautify.html
@@ -0,0 +1,48 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Beautify JSON</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript">
+
+trimPath = function(o){
+ if(o instanceof Array){
+ for(var i = 0; i < o.length; ++i){
+ trimPath(o[i]);
+ }
+ return;
+ }
+ if(("shape" in o) && ("path" in o.shape)){
+ o.shape.path = dojo.trim(o.shape.path.replace(/\s\s+/g, " "));
+ }
+ if("children" in o){
+ trimPath(o.children);
+ }
+};
+
+beautify = function(){
+ var t = dojo.byId("io");
+ var v = dojo.fromJson(t.value);
+ if(dojo.byId("path").checked){
+ trimPath(v);
+ }
+ t.value = dojo.toJson(v, dojo.byId("pprint").checked);
+};
+
+</script>
+</head>
+<body>
+ <h1>Beautify JSON</h1>
+ <p>Paste valid JSON in this textarea and receive a pretty-printed version of it. Use Firefox, if you want to be able to read comma-ended sequences (Python style).
+ Additionally it knows how to remove extra spaces from path elements.</p>
+ <p><textarea id="io" cols="80" rows="10" wrap="off"></textarea></p>
+ <p><button onclick="beautify()">Beautify!</button>
+ &nbsp;&nbsp;&nbsp;<input type="checkbox" id="path" checked="checked" />&nbsp;Process "path" elements
+ &nbsp;&nbsp;&nbsp;<input type="checkbox" id="pprint" checked="checked" />&nbsp;Pretty-print JSON</p>
+ <p><em>This program is a companion for inspector.html.</em></p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/demos/butterfly.html b/includes/js/dojox/gfx/demos/butterfly.html
new file mode 100644
index 0000000..2b9f188
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/butterfly.html
@@ -0,0 +1,88 @@
+<html>
+<head>
+<title>dojox.gfx: Butterfly</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/themes/tundra/tundra.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<script type="text/javascript">
+
+dojo.require("dijit.form.Slider");
+dojo.require("dojo.parser"); // scan page for widgets
+
+dojo.require("dojox.gfx");
+
+var rotation = 0, scaling = 1;
+var surface, g, m = dojox.gfx.matrix;
+var initial_matrix = m.translate(140, 180);
+
+var updateMatrix = function(){
+ if(g){ g.setTransform([m.rotategAt(rotation, 350, 350), m.scaleAt(scaling, 350, 350), initial_matrix]); }
+};
+
+var rotatingEvent = function(value){
+ rotation = value;
+ dojo.byId("rotationValue").innerHTML = rotation;
+ updateMatrix();
+};
+
+var scalingEvent = function(value){
+ scaling = Math.exp(Math.LN10 * (value - 1));
+ dojo.byId("scaleValue").innerHTML = scaling.toFixed(3);
+ updateMatrix();
+};
+
+var makeShapes = function(){
+ surface = dojox.gfx.createSurface(dojo.byId("gfx_holder"), 700, 700);
+ surface.createRect({x: 0, y: 0, width: 700, height: 700}).setFill("#eee");
+ g = surface.createGroup().setTransform(initial_matrix);
+ g.createPath("M204.33 139.83 C196.33 133.33 206.68 132.82 206.58 132.58 C192.33 97.08 169.35 81.41 167.58 80.58 C162.12 78.02 159.48 78.26 160.45 76.97 C161.41 75.68 167.72 79.72 168.58 80.33 C193.83 98.33 207.58 132.33 207.58 132.33 C207.58 132.33 209.33 133.33 209.58 132.58 C219.58 103.08 239.58 87.58 246.33 81.33 C253.08 75.08 256.63 74.47 247.33 81.58 C218.58 103.58 210.34 132.23 210.83 132.33 C222.33 134.83 211.33 140.33 211.83 139.83 C214.85 136.81 214.83 145.83 214.83 145.83 C214.83 145.83 231.83 110.83 298.33 66.33 C302.43 63.59 445.83 -14.67 395.83 80.83 C393.24 85.79 375.83 105.83 375.83 105.83 C375.83 105.83 377.33 114.33 371.33 121.33 C370.3 122.53 367.83 134.33 361.83 140.83 C360.14 142.67 361.81 139.25 361.83 140.83 C362.33 170.83 337.76 170.17 339.33 170.33 C348.83 171.33 350.19 183.66 350.33 183.83 C355.83 190.33 353.83 191.83 355.83 194.83 C366.63 211.02 355.24 210.05 356.83 212.83 C360.83 219.83 355.99 222.72 357.33 224.83 C360.83 230.33 354.75 233.84 354.83 235.33 C355.33 243.83 349.67 240.73 349.83 244.33 C350.33 255.33 346.33 250.83 343.83 254.83 C336.33 266.83 333.46 262.38 332.83 263.83 C329.83 270.83 325.81 269.15 324.33 270.83 C320.83 274.83 317.33 274.83 315.83 276.33 C308.83 283.33 304.86 278.39 303.83 278.83 C287.83 285.83 280.33 280.17 277.83 280.33 C270.33 280.83 271.48 279.67 269.33 277.83 C237.83 250.83 219.33 211.83 215.83 206.83 C214.4 204.79 211.35 193.12 212.33 195.83 C214.33 201.33 213.33 250.33 207.83 250.33 C202.33 250.33 201.83 204.33 205.33 195.83 C206.43 193.16 204.4 203.72 201.79 206.83 C196.33 213.33 179.5 250.83 147.59 277.83 C145.42 279.67 146.58 280.83 138.98 280.33 C136.46 280.17 128.85 285.83 112.65 278.83 C111.61 278.39 107.58 283.33 100.49 276.33 C98.97 274.83 95.43 274.83 91.88 270.83 C90.39 269.15 86.31 270.83 83.27 263.83 C82.64 262.38 79.73 266.83 72.13 254.83 C69.6 250.83 65.54 255.33 66.05 244.33 C66.22 240.73 60.48 243.83 60.99 235.33 C61.08 233.84 54.91 230.33 58.45 224.83 C59.81 222.72 54.91 219.83 58.96 212.83 C60.57 210.05 49.04 211.02 59.97 194.83 C62 191.83 59.97 190.33 65.54 183.83 C65.69 183.66 67.06 171.33 76.69 170.33 C78.28 170.17 53.39 170.83 53.9 140.83 C53.92 139.25 55.61 142.67 53.9 140.83 C47.82 134.33 45.32 122.53 44.27 121.33 C38.19 114.33 39.71 105.83 39.71 105.83 C39.71 105.83 22.08 85.79 19.46 80.83 C-31.19 -14.67 114.07 63.59 118.22 66.33 C185.58 110.83 202 145.83 202 145.83 C202 145.83 202.36 143.28 203 141.83 C203.64 140.39 204.56 140.02 204.33 139.83 z").setFill("rgb(246,127,0)");
+ g.createPath("M203.62 139.62 C195.62 133.12 205.96 132.6 205.87 132.37 C191.62 96.87 168.64 81.2 166.87 80.37 C161.41 77.81 158.77 78.05 159.73 76.76 C160.69 75.47 167.01 79.51 167.87 80.12 C193.12 98.12 206.87 132.12 206.87 132.12 C206.87 132.12 208.62 133.12 208.87 132.37 C218.87 102.87 238.87 87.37 245.62 81.12 C252.37 74.87 255.92 74.26 246.62 81.37 C217.87 103.37 209.63 132.01 210.12 132.12 C221.62 134.62 210.62 140.12 211.12 139.62 C214.14 136.6 214.12 145.62 214.12 145.62 C214.12 145.62 231.12 110.62 297.62 66.12 C301.71 63.38 445.12 -14.88 395.12 80.62 C392.53 85.57 375.12 105.62 375.12 105.62 C375.12 105.62 376.62 114.12 370.62 121.12 C369.59 122.32 367.12 134.12 361.12 140.62 C359.43 142.46 361.09 139.04 361.12 140.62 C361.62 170.62 337.05 169.96 338.62 170.12 C348.12 171.12 349.47 183.45 349.62 183.62 C355.12 190.12 353.12 191.62 355.12 194.62 C365.91 210.81 354.53 209.84 356.12 212.62 C360.12 219.62 355.28 222.51 356.62 224.62 C360.12 230.12 354.03 233.62 354.12 235.12 C354.62 243.62 348.96 240.52 349.12 244.12 C349.62 255.12 345.62 250.62 343.12 254.62 C335.62 266.62 332.74 262.17 332.12 263.62 C329.12 270.62 325.09 268.94 323.62 270.62 C320.12 274.62 316.62 274.62 315.12 276.12 C308.12 283.12 304.15 278.17 303.12 278.62 C287.12 285.62 279.62 279.95 277.12 280.12 C269.62 280.62 270.77 279.46 268.62 277.62 C237.12 250.62 218.62 211.62 215.12 206.62 C213.69 204.57 210.63 192.91 211.62 195.62 C213.62 201.12 212.62 250.12 207.12 250.12 C201.62 250.12 201.12 204.12 204.62 195.62 C205.72 192.95 203.69 203.5 201.08 206.62 C195.62 213.12 178.79 250.62 146.88 277.62 C144.71 279.46 145.87 280.62 138.27 280.12 C135.75 279.95 128.14 285.62 111.94 278.62 C110.9 278.17 106.87 283.12 99.78 276.12 C98.26 274.62 94.72 274.62 91.17 270.62 C89.68 268.94 85.6 270.62 82.56 263.62 C81.93 262.17 79.01 266.62 71.42 254.62 C68.88 250.62 64.83 255.12 65.34 244.12 C65.51 240.52 59.77 243.62 60.27 235.12 C60.36 233.62 54.2 230.12 57.74 224.62 C59.1 222.51 54.2 219.62 58.25 212.62 C59.86 209.84 48.33 210.81 59.26 194.62 C61.29 191.62 59.26 190.12 64.83 183.62 C64.98 183.45 66.35 171.12 75.98 170.12 C77.57 169.96 52.68 170.62 53.18 140.62 C53.21 139.04 54.9 142.46 53.18 140.62 C47.11 134.12 44.6 122.32 43.56 121.12 C37.48 114.12 39 105.62 39 105.62 C39 105.62 21.37 85.57 18.74 80.62 C-31.9 -14.88 113.36 63.38 117.51 66.12 C184.87 110.62 201.29 145.62 201.29 145.62 C201.29 145.62 201.65 143.07 202.29 141.62 C202.93 140.18 203.85 139.81 203.62 139.62 zM242.12 153.12 C245.16 153.02 251.35 156.17 255.12 155.12 C280.55 148.06 328.44 154.56 331.62 155.62 C343.62 159.62 351.62 131.12 326.12 131.12 C294.59 131.12 301.12 129.12 280.12 126.12 C278.34 125.87 252.6 135.42 228.62 149.12 C225.12 151.12 227.12 153.62 242.12 153.12 zM223.12 148.12 C225.66 148.4 238.12 139.62 277.12 124.12 C279.49 123.18 279.62 118.12 300.62 108.62 C301.99 108 300.12 104.62 314.62 92.62 C321.79 86.69 297.12 87.62 291.62 88.62 C286.12 89.62 272.62 100.62 272.62 100.62 C272.62 100.62 287.8 88.55 282.62 90.12 C271.12 93.62 241.12 126.62 231.12 140.62 C221.12 154.62 247.62 116.62 254.12 110.62 C260.62 104.62 204.62 146.12 223.12 148.12 zM335.62 128.62 C350.14 131.53 348.62 110.12 341.12 109.12 C329.55 107.58 307.51 108.3 301.12 110.62 C284.62 116.62 280.29 122.65 281.62 123.12 C310.12 133.12 330.62 127.62 335.62 128.62 zM335.12 106.62 C341.04 107.36 351.12 109.62 351.62 101.62 C351.87 97.6 365.62 104.62 368.62 105.12 C371.1 105.53 358.12 100.33 353.62 97.12 C350.12 94.62 349.51 91.76 349.12 91.62 C317.12 80.12 303.62 107.12 303.62 107.12 C303.62 107.12 331.12 106.12 335.12 106.62 zM400.62 62.62 C395.62 54.62 386.66 57.08 383.62 53.62 C369.12 37.12 335.54 58.28 363.12 56.12 C395.12 53.62 401.21 63.57 400.62 62.62 zM376.62 66.62 C390.13 66.62 396.12 72.62 395.12 71.62 C388.12 64.62 382.12 66.12 380.62 64.12 C371.7 52.23 345.12 64.62 347.12 67.62 C349.12 70.62 373.12 66.62 376.62 66.62 zM330.12 76.12 C309.12 81.12 318.12 88.62 320.62 88.12 C340.05 84.24 334.5 75.08 330.12 76.12 zM340.62 52.12 C331.12 53.12 330.48 70.43 335.12 67.12 C342.12 62.12 350.12 51.12 340.62 52.12 zM315.62 75.62 C329.62 70.12 319.12 67.62 314.62 68.12 C310.12 68.62 306.79 75.45 308.12 78.12 C311.12 84.12 312.91 76.69 315.62 75.62 zM359.62 121.12 C364.12 118.62 358.62 112.62 354.62 115.12 C350.62 117.62 355.12 123.62 359.62 121.12 zM350.12 78.62 C361.89 90.39 366.62 84.12 369.12 83.12 C377.24 79.87 386.12 88.62 384.62 87.12 C377.34 79.84 372.62 81.12 371.62 79.62 C364.01 68.2 352.66 75.44 350.12 75.62 C343.12 76.12 334.43 81.03 337.62 80.12 C341.12 79.12 348.62 77.12 350.12 78.62 zM383.62 44.12 C390.62 39.12 381.4 37.85 379.62 38.12 C373.12 39.12 376.62 49.12 383.62 44.12 zM224.62 181.12 C230.12 187.62 291.62 285.12 282.12 252.62 C280.83 248.2 285.62 266.12 291.12 256.12 C292.66 253.32 301.27 253.03 274.62 208.62 C273.12 206.12 252.62 198.12 232.12 175.62 C229.02 172.21 220.05 175.72 224.62 181.12 zM280.12 215.62 C284.62 222.62 295.81 246.07 296.62 249.62 C299.12 260.62 306.12 248.12 307.62 248.62 C320.78 253.01 311.12 241.12 310.12 238.12 C300.95 210.62 279.62 213.12 279.62 213.12 C279.62 213.12 275.62 208.62 280.12 215.62 zM253.62 256.12 C266.26 274.09 271.12 267.12 273.62 265.12 C281.32 258.96 232.34 196.14 229.12 192.12 C225.12 187.12 225.12 215.62 253.62 256.12 zM300.12 219.12 C306.62 224.12 313.86 245.19 317.62 244.62 C327.62 243.12 321.62 234.62 324.12 236.12 C326.62 237.62 331.62 234.95 330.12 232.12 C317.62 208.62 298.12 216.12 298.12 216.12 C298.12 216.12 293.62 214.12 300.12 219.12 zM235.62 168.62 C216.12 168.62 282.12 222.62 301.12 212.12 C305.06 209.94 296.12 208.62 297.62 197.12 C297.9 195.02 284.12 191.12 284.12 178.12 C284.12 173.88 276.2 172.12 251.12 172.12 C246.62 172.12 256.03 168.62 235.62 168.62 zM307.62 213.62 C325.89 215.65 330.23 229.8 332.62 228.12 C361.12 208.12 309.89 199.96 300.62 201.12 C296.62 201.62 303.12 213.12 307.62 213.62 zM238.62 164.12 C242.12 166.62 254.12 176.62 292.62 168.12 C294.09 167.8 263.62 167.62 259.62 166.62 C255.62 165.62 236.25 162.43 238.62 164.12 zM305.12 198.62 C342.62 207.62 332.72 201.36 334.12 200.62 C342.62 196.12 333.33 195.23 334.62 193.62 C338.83 188.36 327.62 185.12 304.12 182.62 C298.56 182.03 287.54 179.27 287.12 180.12 C283.62 187.12 300.33 197.47 305.12 198.62 zM311.12 182.12 C343.62 187.62 323.23 177.43 323.62 177.12 C335.12 168.12 297.12 168.12 297.12 168.12 C297.12 168.12 280.79 172 281.12 172.62 C285.62 181.12 307.15 181.45 311.12 182.12 zM249.62 253.62 C249.62 253.62 220.62 207.12 226.62 188.12 C227.83 184.31 213.62 165.62 220.12 197.12 C220.22 197.61 218.89 190.43 216.62 187.12 C214.35 183.81 211.18 184.9 213.12 194.62 C218.01 219.05 249.62 253.62 249.62 253.62 zM289.12 83.62 C296.62 81.62 293.12 79.12 288.62 78.12 C284.12 77.12 281.62 85.62 289.12 83.62 zM187.4 149.12 C163.12 135.42 137.04 125.87 135.23 126.12 C113.96 129.12 120.58 131.12 88.64 131.12 C62.81 131.12 70.91 159.62 83.07 155.62 C86.29 154.56 134.8 148.06 160.56 155.12 C164.37 156.17 170.65 153.02 173.73 153.12 C188.92 153.62 190.95 151.12 187.4 149.12 zM161.57 110.62 C168.15 116.62 195 154.62 184.87 140.62 C174.74 126.62 144.35 93.62 132.7 90.12 C127.46 88.55 142.83 100.62 142.83 100.62 C142.83 100.62 129.16 89.62 123.58 88.62 C118.01 87.62 93.03 86.69 100.29 92.62 C114.97 104.62 113.08 108 114.47 108.62 C135.74 118.12 135.87 123.18 138.27 124.12 C177.78 139.62 190.4 148.4 192.97 148.12 C211.71 146.12 154.99 104.62 161.57 110.62 zM133.71 123.12 C135.07 122.65 130.68 116.62 113.96 110.62 C107.49 108.3 85.16 107.58 73.44 109.12 C65.85 110.12 64.31 131.53 79.01 128.62 C84.08 127.62 104.84 133.12 133.71 123.12 zM111.43 107.12 C111.43 107.12 97.75 80.12 65.34 91.62 C64.95 91.76 64.33 94.62 60.78 97.12 C56.23 100.33 43.08 105.53 45.59 105.12 C48.63 104.62 62.55 97.6 62.81 101.62 C63.31 109.62 73.53 107.36 79.52 106.62 C83.57 106.12 111.43 107.12 111.43 107.12 zM51.16 56.12 C79.09 58.28 45.08 37.12 30.39 53.62 C27.31 57.08 18.24 54.62 13.17 62.62 C12.57 63.57 18.74 53.62 51.16 56.12 zM67.37 67.62 C69.39 64.62 42.47 52.23 33.43 64.12 C31.91 66.12 25.83 64.62 18.74 71.62 C17.73 72.62 23.8 66.62 37.48 66.62 C41.03 66.62 65.34 70.62 67.37 67.62 zM84.59 76.12 C105.86 81.12 96.74 88.62 94.21 88.12 C74.53 84.24 80.15 75.08 84.59 76.12 zM79.52 67.12 C84.22 70.43 83.57 53.12 73.95 52.12 C64.33 51.12 72.43 62.12 79.52 67.12 zM106.87 78.12 C108.22 75.45 104.84 68.62 100.29 68.12 C95.73 67.62 85.09 70.12 99.27 75.62 C102.02 76.69 103.83 84.12 106.87 78.12 zM59.77 115.12 C55.72 112.62 50.14 118.62 54.7 121.12 C59.26 123.62 63.82 117.62 59.77 115.12 zM76.99 80.12 C80.22 81.03 71.42 76.12 64.33 75.62 C61.75 75.44 50.26 68.2 42.55 79.62 C41.53 81.12 36.75 79.84 29.38 87.12 C27.86 88.62 36.85 79.87 45.08 83.12 C47.61 84.12 52.41 90.39 64.33 78.62 C65.85 77.12 73.44 79.12 76.99 80.12 zM34.44 38.12 C32.64 37.85 23.3 39.12 30.39 44.12 C37.48 49.12 41.03 39.12 34.44 38.12 zM183.86 175.62 C163.09 198.12 142.32 206.12 140.8 208.62 C113.81 253.03 122.53 253.32 124.09 256.12 C129.66 266.12 134.52 248.2 133.21 252.62 C123.58 285.12 185.88 187.62 191.45 181.12 C196.08 175.72 187 172.21 183.86 175.62 zM135.74 213.12 C135.74 213.12 114.13 210.62 104.84 238.12 C103.83 241.12 94.05 253.01 107.38 248.62 C108.9 248.12 115.99 260.62 118.52 249.62 C119.34 246.07 130.68 222.62 135.23 215.62 C139.79 208.62 135.74 213.12 135.74 213.12 zM186.89 192.12 C183.64 196.14 134.02 258.96 141.82 265.12 C144.35 267.12 149.27 274.09 162.08 256.12 C190.95 215.62 190.95 187.12 186.89 192.12 zM117 216.12 C117 216.12 97.25 208.62 84.59 232.12 C83.06 234.95 88.13 237.62 90.66 236.12 C93.2 234.62 87.12 243.12 97.25 244.62 C101.06 245.19 108.39 224.12 114.97 219.12 C121.56 214.12 117 216.12 117 216.12 zM164.61 172.12 C139.2 172.12 131.18 173.88 131.18 178.12 C131.18 191.12 117.23 195.02 117.51 197.12 C119.03 208.62 109.97 209.94 113.96 212.12 C133.21 222.62 200.06 168.62 180.31 168.62 C159.64 168.62 169.17 172.12 164.61 172.12 zM114.47 201.12 C105.08 199.96 53.18 208.12 82.05 228.12 C84.47 229.8 88.87 215.65 107.38 213.62 C111.94 213.12 118.52 201.62 114.47 201.12 zM156 166.62 C151.95 167.62 121.09 167.8 122.57 168.12 C161.57 176.62 173.73 166.62 177.27 164.12 C179.67 162.43 160.05 165.62 156 166.62 zM128.14 180.12 C127.71 179.27 116.55 182.03 110.92 182.62 C87.12 185.12 75.76 188.36 80.03 193.62 C81.33 195.23 71.92 196.12 80.53 200.62 C81.95 201.36 71.92 207.62 109.91 198.62 C114.76 197.47 131.69 187.12 128.14 180.12 zM134.22 172.62 C134.56 172 118.01 168.12 118.01 168.12 C118.01 168.12 79.52 168.12 91.17 177.12 C91.57 177.43 70.91 187.62 103.83 182.12 C107.86 181.45 129.66 181.12 134.22 172.62 zM203.1 194.62 C205.07 184.9 201.85 183.81 199.56 187.12 C197.26 190.43 195.91 197.61 196.01 197.12 C202.6 165.62 188.21 184.31 189.43 188.12 C195.5 207.12 166.13 253.62 166.13 253.62 C166.13 253.62 198.15 219.05 203.1 194.62 zM126.62 78.12 C122.06 79.12 118.52 81.62 126.12 83.62 C133.71 85.62 131.18 77.12 126.62 78.12 z").setFill("black");
+ g.createPath("M363.73 85.73 C359.27 86.29 355.23 86.73 354.23 81.23 C353.23 75.73 355.73 73.73 363.23 75.73 C370.73 77.73 375.73 84.23 363.73 85.73 zM327.23 89.23 C327.23 89.23 308.51 93.65 325.73 80.73 C333.73 74.73 334.23 79.73 334.73 82.73 C335.48 87.2 327.23 89.23 327.23 89.23 zM384.23 48.73 C375.88 47.06 376.23 42.23 385.23 40.23 C386.7 39.91 389.23 49.73 384.23 48.73 zM389.23 48.73 C391.73 48.23 395.73 49.23 396.23 52.73 C396.73 56.23 392.73 58.23 390.23 56.23 C387.73 54.23 386.73 49.23 389.23 48.73 zM383.23 59.73 C385.73 58.73 393.23 60.23 392.73 63.23 C392.23 66.23 386.23 66.73 383.73 65.23 C381.23 63.73 380.73 60.73 383.23 59.73 zM384.23 77.23 C387.23 74.73 390.73 77.23 391.73 78.73 C392.73 80.23 387.73 82.23 386.23 82.73 C384.73 83.23 381.23 79.73 384.23 77.23 zM395.73 40.23 C395.73 40.23 399.73 40.23 398.73 41.73 C397.73 43.23 394.73 43.23 394.73 43.23 zM401.73 49.23 C401.73 49.23 405.73 49.23 404.73 50.73 C403.73 52.23 400.73 52.23 400.73 52.23 zM369.23 97.23 C369.23 97.23 374.23 99.23 373.23 100.73 C372.23 102.23 370.73 104.73 367.23 101.23 C363.73 97.73 369.23 97.23 369.23 97.23 zM355.73 116.73 C358.73 114.23 362.23 116.73 363.23 118.23 C364.23 119.73 359.23 121.73 357.73 122.23 C356.23 122.73 352.73 119.23 355.73 116.73 zM357.73 106.73 C360.73 104.23 363.23 107.73 364.23 109.23 C365.23 110.73 361.23 111.73 359.73 112.23 C358.23 112.73 354.73 109.23 357.73 106.73 zM340.73 73.23 C337.16 73.43 331.23 71.73 340.23 65.73 C348.55 60.19 348.23 61.73 348.73 64.73 C349.48 69.2 344.3 73.04 340.73 73.23 zM310.23 82.23 C310.23 82.23 306.73 79.23 313.73 73.23 C321.33 66.73 320.23 69.23 320.73 72.23 C321.48 76.7 310.23 82.23 310.23 82.23 zM341.23 55.73 C341.23 55.73 347.23 54.73 346.23 56.23 C345.23 57.73 342.73 63.23 339.23 59.73 C335.73 56.23 341.23 55.73 341.23 55.73 zM374.73 86.23 C376.11 86.23 377.23 87.36 377.23 88.73 C377.23 90.11 376.11 91.23 374.73 91.23 C373.36 91.23 372.23 90.11 372.23 88.73 C372.23 87.36 373.36 86.23 374.73 86.23 zM369.73 110.73 C371.11 110.73 372.23 111.86 372.23 113.23 C372.23 114.61 371.11 115.73 369.73 115.73 C368.36 115.73 367.23 114.61 367.23 113.23 C367.23 111.86 368.36 110.73 369.73 110.73 zM365.73 120.73 C367.11 120.73 368.23 121.86 368.23 123.23 C368.23 124.61 367.11 125.73 365.73 125.73 C364.36 125.73 363.23 124.61 363.23 123.23 C363.23 121.86 364.36 120.73 365.73 120.73 zM349.73 127.23 C351.11 127.23 352.23 128.36 352.23 129.73 C352.23 131.11 351.11 132.23 349.73 132.23 C348.36 132.23 347.23 131.11 347.23 129.73 C347.23 128.36 348.36 127.23 349.73 127.23 zM358.23 128.73 C359.61 128.73 362.23 130.86 362.23 132.23 C362.23 133.61 359.61 133.73 358.23 133.73 C356.86 133.73 355.73 132.61 355.73 131.23 C355.73 129.86 356.86 128.73 358.23 128.73 zM382.23 89.73 C383.61 89.73 384.73 90.86 384.73 92.23 C384.73 93.61 383.61 94.73 382.23 94.73 C380.86 94.73 379.73 93.61 379.73 92.23 C379.73 90.86 380.86 89.73 382.23 89.73 zM395.73 66.23 C397.11 66.23 398.23 67.36 398.23 68.73 C398.23 70.11 397.11 71.23 395.73 71.23 C394.36 71.23 393.23 70.11 393.23 68.73 C393.23 67.36 394.36 66.23 395.73 66.23 zM300.73 74.23 C303.05 75.16 314.23 67.73 310.73 66.73 C307.23 65.73 298.23 73.23 300.73 74.23 zM319.73 61.23 C322.23 61.73 329.73 58.73 326.23 57.73 C322.73 56.73 317.09 60.71 319.73 61.23 zM271.73 91.73 C277.23 88.73 292.73 81.23 285.23 82.23 C277.73 83.23 267.01 94.31 271.73 91.73 zM364.23 42.23 C366.73 42.73 374.23 39.73 370.73 38.73 C367.23 37.73 361.59 41.71 364.23 42.23 zM292.23 78.73 C294.73 79.23 299.73 76.73 296.23 75.73 C292.73 74.73 289.59 78.21 292.23 78.73 zM355.23 141.23 C356.61 141.23 357.73 142.86 357.73 144.23 C357.73 145.61 357.11 145.73 355.73 145.73 C354.36 145.73 353.23 144.61 353.23 143.23 C353.23 141.86 353.86 141.23 355.23 141.23 zM347.73 140.73 C349.11 140.73 351.23 141.36 351.23 142.73 C351.23 144.11 348.61 143.73 347.23 143.73 C345.86 143.73 344.73 142.61 344.73 141.23 C344.73 139.86 346.36 140.73 347.73 140.73 zM349.73 155.23 C351.11 155.23 353.73 157.36 353.73 158.73 C353.73 160.11 351.11 160.23 349.73 160.23 C348.36 160.23 347.23 159.11 347.23 157.73 C347.23 156.36 348.36 155.23 349.73 155.23 zM337.73 175.73 C341.73 174.73 341.73 176.73 342.73 180.23 C343.73 183.73 350.8 195.11 339.23 181.23 C336.73 178.23 333.73 176.73 337.73 175.73 zM349.73 187.73 C351.11 187.73 352.23 188.86 352.23 190.23 C352.23 191.61 351.11 192.73 349.73 192.73 C348.36 192.73 347.23 191.61 347.23 190.23 C347.23 188.86 348.36 187.73 349.73 187.73 zM352.23 196.73 C353.61 196.73 354.73 197.86 354.73 199.23 C354.73 200.61 353.61 201.73 352.23 201.73 C350.86 201.73 349.73 200.61 349.73 199.23 C349.73 197.86 350.86 196.73 352.23 196.73 zM352.4 205.73 C353.77 205.73 355.73 208.86 355.73 210.23 C355.73 211.61 354.61 212.73 353.23 212.73 C351.86 212.73 349.07 211.11 349.07 209.73 C349.07 208.36 351.02 205.73 352.4 205.73 zM353.73 221.73 C355.11 221.73 354.73 221.86 354.73 223.23 C354.73 224.61 354.61 223.73 353.23 223.73 C351.86 223.73 352.23 224.61 352.23 223.23 C352.23 221.86 352.36 221.73 353.73 221.73 zM340.23 188.73 C341.61 188.73 341.23 188.86 341.23 190.23 C341.23 191.61 341.11 190.73 339.73 190.73 C338.36 190.73 338.73 191.61 338.73 190.23 C338.73 188.86 338.86 188.73 340.23 188.73 zM343.23 201.23 C344.61 201.23 344.23 201.36 344.23 202.73 C344.23 204.11 344.44 207.73 343.07 207.73 C341.69 207.73 341.73 204.11 341.73 202.73 C341.73 201.36 341.86 201.23 343.23 201.23 zM346.73 215.23 C348.11 215.23 347.73 215.36 347.73 216.73 C347.73 218.11 347.61 217.23 346.23 217.23 C344.86 217.23 345.23 218.11 345.23 216.73 C345.23 215.36 345.36 215.23 346.73 215.23 zM340.57 228.73 C341.94 228.73 341.73 228.86 341.73 230.23 C341.73 231.61 341.44 230.73 340.07 230.73 C338.69 230.73 339.23 231.61 339.23 230.23 C339.23 228.86 339.19 228.73 340.57 228.73 zM349.4 232.07 C350.77 232.07 352.07 234.02 352.07 235.4 C352.07 236.77 349.11 239.23 347.73 239.23 C346.36 239.23 346.73 240.11 346.73 238.73 C346.73 237.36 348.02 232.07 349.4 232.07 zM343.73 246.4 C345.11 246.4 347.4 246.02 347.4 247.4 C347.4 248.77 344.11 251.23 342.73 251.23 C341.36 251.23 341.73 252.11 341.73 250.73 C341.73 249.36 342.36 246.4 343.73 246.4 zM335.23 239.23 C336.61 239.23 336.23 239.36 336.23 240.73 C336.23 242.11 336.11 241.23 334.73 241.23 C333.36 241.23 333.73 242.11 333.73 240.73 C333.73 239.36 333.86 239.23 335.23 239.23 zM332.73 258.4 C334.11 258.4 335.4 260.02 335.4 261.4 C335.4 262.77 333.11 262.23 331.73 262.23 C330.36 262.23 330.73 263.11 330.73 261.73 C330.73 260.36 331.36 258.4 332.73 258.4 zM324.4 263.73 C325.77 263.73 325.07 265.36 325.07 266.73 C325.07 268.11 320.11 271.23 318.73 271.23 C317.36 271.23 317.73 272.11 317.73 270.73 C317.73 269.36 323.02 263.73 324.4 263.73 zM325.23 247.73 C326.61 247.73 326.23 247.86 326.23 249.23 C326.23 250.61 326.11 249.73 324.73 249.73 C323.36 249.73 323.73 250.61 323.73 249.23 C323.73 247.86 323.86 247.73 325.23 247.73 zM313.23 256.23 C314.61 256.23 319.07 258.02 319.07 259.4 C319.07 260.77 313.44 263.07 312.07 263.07 C310.69 263.07 309.73 260.77 309.73 259.4 C309.73 258.02 311.86 256.23 313.23 256.23 zM300.23 260.73 C301.61 260.73 301.23 260.86 301.23 262.23 C301.23 263.61 301.11 262.73 299.73 262.73 C298.36 262.73 298.73 263.61 298.73 262.23 C298.73 260.86 298.86 260.73 300.23 260.73 zM308.23 272.73 C309.61 272.73 309.23 272.86 309.23 274.23 C309.23 275.61 309.11 274.73 307.73 274.73 C306.36 274.73 306.73 275.61 306.73 274.23 C306.73 272.86 306.86 272.73 308.23 272.73 zM305.23 273.73 C306.61 273.73 306.23 273.86 306.23 275.23 C306.23 276.61 306.11 275.73 304.73 275.73 C303.36 275.73 303.73 276.61 303.73 275.23 C303.73 273.86 303.86 273.73 305.23 273.73 zM293.73 274.07 C294.65 274.07 295.73 275.48 295.73 276.4 C295.73 277.32 295.65 276.73 294.73 276.73 C293.82 276.73 291.4 277.98 291.4 277.07 C291.4 276.15 292.82 274.07 293.73 274.07 zM296.73 276.73 C297.65 276.73 297.4 276.82 297.4 277.73 C297.4 278.65 297.32 278.07 296.4 278.07 C295.48 278.07 295.73 278.65 295.73 277.73 C295.73 276.82 295.82 276.73 296.73 276.73 zM291.4 263.73 C292.32 263.73 293.73 267.15 293.73 268.07 C293.73 268.98 290.65 268.73 289.73 268.73 C288.82 268.73 287.4 265.98 287.4 265.07 C287.4 264.15 290.48 263.73 291.4 263.73 zM280.07 274.73 C281.44 274.73 281.23 274.86 281.23 276.23 C281.23 277.61 280.94 276.73 279.57 276.73 C278.19 276.73 278.73 277.61 278.73 276.23 C278.73 274.86 278.69 274.73 280.07 274.73 zM277.07 267.73 C278.44 267.73 276.4 271.02 276.4 272.4 C276.4 273.77 271.94 274.23 270.57 274.23 C269.19 274.23 271.73 272.44 271.73 271.07 C271.73 269.69 275.69 267.73 277.07 267.73 zM52.23 84.9 C56.7 85.46 60.73 85.9 61.73 80.4 C62.73 74.9 60.23 72.9 52.73 74.9 C45.23 76.9 40.23 83.4 52.23 84.9 zM88.73 88.4 C88.73 88.4 107.45 92.81 90.23 79.9 C82.23 73.9 81.73 78.9 81.23 81.9 C80.49 86.37 88.73 88.4 88.73 88.4 zM31.73 47.9 C40.08 46.23 39.73 41.4 30.73 39.4 C29.27 39.07 26.73 48.9 31.73 47.9 zM26.73 47.9 C24.23 47.4 20.23 48.4 19.73 51.9 C19.23 55.4 23.23 57.4 25.73 55.4 C28.23 53.4 29.23 48.4 26.73 47.9 zM32.73 58.9 C30.23 57.9 22.73 59.4 23.23 62.4 C23.73 65.4 29.73 65.9 32.23 64.4 C34.73 62.9 35.23 59.9 32.73 58.9 zM31.73 76.4 C28.73 73.9 25.23 76.4 24.23 77.9 C23.23 79.4 28.23 81.4 29.73 81.9 C31.23 82.4 34.73 78.9 31.73 76.4 zM20.23 39.4 C20.23 39.4 16.23 39.4 17.23 40.9 C18.23 42.4 21.23 42.4 21.23 42.4 zM14.23 48.4 C14.23 48.4 10.23 48.4 11.23 49.9 C12.23 51.4 15.23 51.4 15.23 51.4 zM46.73 96.4 C46.73 96.4 41.73 98.4 42.73 99.9 C43.73 101.4 45.23 103.9 48.73 100.4 C52.23 96.9 46.73 96.4 46.73 96.4 zM60.23 115.9 C57.23 113.4 53.73 115.9 52.73 117.4 C51.73 118.9 56.73 120.9 58.23 121.4 C59.73 121.9 63.23 118.4 60.23 115.9 zM58.23 105.9 C55.23 103.4 52.73 106.9 51.73 108.4 C50.73 109.9 54.73 110.9 56.23 111.4 C57.73 111.9 61.23 108.4 58.23 105.9 zM75.23 72.4 C78.8 72.6 84.73 70.9 75.73 64.9 C67.41 59.35 67.73 60.9 67.23 63.9 C66.49 68.37 71.66 72.2 75.23 72.4 zM105.73 81.4 C105.73 81.4 109.23 78.4 102.23 72.4 C94.64 65.89 95.73 68.4 95.23 71.4 C94.49 75.87 105.73 81.4 105.73 81.4 zM74.73 54.9 C74.73 54.9 68.73 53.9 69.73 55.4 C70.73 56.9 73.23 62.4 76.73 58.9 C80.23 55.4 74.73 54.9 74.73 54.9 zM41.23 85.4 C39.86 85.4 38.73 86.53 38.73 87.9 C38.73 89.28 39.86 90.4 41.23 90.4 C42.61 90.4 43.73 89.28 43.73 87.9 C43.73 86.53 42.61 85.4 41.23 85.4 zM46.23 109.9 C44.86 109.9 43.73 111.03 43.73 112.4 C43.73 113.78 44.86 114.9 46.23 114.9 C47.61 114.9 48.73 113.78 48.73 112.4 C48.73 111.03 47.61 109.9 46.23 109.9 zM50.23 119.9 C48.86 119.9 47.73 121.03 47.73 122.4 C47.73 123.78 48.86 124.9 50.23 124.9 C51.61 124.9 52.73 123.78 52.73 122.4 C52.73 121.03 51.61 119.9 50.23 119.9 zM66.23 126.4 C64.86 126.4 63.73 127.53 63.73 128.9 C63.73 130.28 64.86 131.4 66.23 131.4 C67.61 131.4 68.73 130.28 68.73 128.9 C68.73 127.53 67.61 126.4 66.23 126.4 zM57.73 127.9 C56.36 127.9 53.73 130.03 53.73 131.4 C53.73 132.78 56.36 132.9 57.73 132.9 C59.11 132.9 60.23 131.78 60.23 130.4 C60.23 129.03 59.11 127.9 57.73 127.9 zM33.73 88.9 C32.36 88.9 31.23 90.03 31.23 91.4 C31.23 92.78 32.36 93.9 33.73 93.9 C35.11 93.9 36.23 92.78 36.23 91.4 C36.23 90.03 35.11 88.9 33.73 88.9 zM20.23 65.4 C18.86 65.4 17.73 66.53 17.73 67.9 C17.73 69.28 18.86 70.4 20.23 70.4 C21.61 70.4 22.73 69.28 22.73 67.9 C22.73 66.53 21.61 65.4 20.23 65.4 zM115.23 73.4 C112.91 74.33 101.73 66.9 105.23 65.9 C108.73 64.9 117.73 72.4 115.23 73.4 zM96.23 60.4 C93.73 60.9 86.23 57.9 89.73 56.9 C93.23 55.9 98.87 59.87 96.23 60.4 zM144.23 90.9 C138.73 87.9 123.23 80.4 130.73 81.4 C138.23 82.4 148.96 93.48 144.23 90.9 zM51.73 41.4 C49.23 41.9 41.73 38.9 45.23 37.9 C48.73 36.9 54.37 40.87 51.73 41.4 zM123.73 77.9 C121.23 78.4 116.23 75.9 119.73 74.9 C123.23 73.9 126.37 77.37 123.73 77.9 zM60.73 140.4 C59.36 140.4 58.23 142.03 58.23 143.4 C58.23 144.78 58.86 144.9 60.23 144.9 C61.61 144.9 62.73 143.78 62.73 142.4 C62.73 141.03 62.11 140.4 60.73 140.4 zM68.23 139.9 C66.86 139.9 64.73 140.53 64.73 141.9 C64.73 143.28 67.36 142.9 68.73 142.9 C70.11 142.9 71.23 141.78 71.23 140.4 C71.23 139.03 69.61 139.9 68.23 139.9 zM66.23 154.4 C64.86 154.4 62.23 156.53 62.23 157.9 C62.23 159.28 64.86 159.4 66.23 159.4 C67.61 159.4 68.73 158.28 68.73 156.9 C68.73 155.53 67.61 154.4 66.23 154.4 zM78.23 174.9 C74.23 173.9 74.23 175.9 73.23 179.4 C72.23 182.9 65.17 194.28 76.73 180.4 C79.23 177.4 82.23 175.9 78.23 174.9 zM66.23 186.9 C64.86 186.9 63.73 188.02 63.73 189.4 C63.73 190.77 64.86 191.9 66.23 191.9 C67.61 191.9 68.73 190.77 68.73 189.4 C68.73 188.02 67.61 186.9 66.23 186.9 zM63.73 195.9 C62.36 195.9 61.23 197.02 61.23 198.4 C61.23 199.77 62.36 200.9 63.73 200.9 C65.11 200.9 66.23 199.77 66.23 198.4 C66.23 197.02 65.11 195.9 63.73 195.9 zM63.57 204.9 C62.19 204.9 60.23 208.02 60.23 209.4 C60.23 210.77 61.36 211.9 62.73 211.9 C64.11 211.9 66.9 210.27 66.9 208.9 C66.9 207.52 64.94 204.9 63.57 204.9 zM62.23 220.9 C60.86 220.9 61.23 221.02 61.23 222.4 C61.23 223.77 61.36 222.9 62.73 222.9 C64.11 222.9 63.73 223.77 63.73 222.4 C63.73 221.02 63.61 220.9 62.23 220.9 zM75.73 187.9 C74.36 187.9 74.73 188.02 74.73 189.4 C74.73 190.77 74.86 189.9 76.23 189.9 C77.61 189.9 77.23 190.77 77.23 189.4 C77.23 188.02 77.11 187.9 75.73 187.9 zM72.73 200.4 C71.36 200.4 71.73 200.52 71.73 201.9 C71.73 203.27 71.53 206.9 72.9 206.9 C74.28 206.9 74.23 203.27 74.23 201.9 C74.23 200.52 74.11 200.4 72.73 200.4 zM69.23 214.4 C67.86 214.4 68.23 214.52 68.23 215.9 C68.23 217.27 68.36 216.4 69.73 216.4 C71.11 216.4 70.73 217.27 70.73 215.9 C70.73 214.52 70.61 214.4 69.23 214.4 zM75.4 227.9 C74.03 227.9 74.23 228.02 74.23 229.4 C74.23 230.77 74.53 229.9 75.9 229.9 C77.28 229.9 76.73 230.77 76.73 229.4 C76.73 228.02 76.78 227.9 75.4 227.9 zM66.57 231.23 C65.19 231.23 63.9 233.19 63.9 234.57 C63.9 235.94 66.86 238.4 68.23 238.4 C69.61 238.4 69.23 239.27 69.23 237.9 C69.23 236.52 67.94 231.23 66.57 231.23 zM72.23 245.57 C70.86 245.57 68.57 245.19 68.57 246.57 C68.57 247.94 71.86 250.4 73.23 250.4 C74.61 250.4 74.23 251.27 74.23 249.9 C74.23 248.52 73.61 245.57 72.23 245.57 zM80.73 238.4 C79.36 238.4 79.73 238.52 79.73 239.9 C79.73 241.27 79.86 240.4 81.23 240.4 C82.61 240.4 82.23 241.27 82.23 239.9 C82.23 238.52 82.11 238.4 80.73 238.4 zM83.23 257.57 C81.86 257.57 80.57 259.19 80.57 260.57 C80.57 261.94 82.86 261.4 84.23 261.4 C85.61 261.4 85.23 262.27 85.23 260.9 C85.23 259.52 84.61 257.57 83.23 257.57 zM91.57 262.9 C90.19 262.9 90.9 264.52 90.9 265.9 C90.9 267.27 95.86 270.4 97.23 270.4 C98.61 270.4 98.23 271.27 98.23 269.9 C98.23 268.52 92.94 262.9 91.57 262.9 zM90.73 246.9 C89.36 246.9 89.73 247.02 89.73 248.4 C89.73 249.77 89.86 248.9 91.23 248.9 C92.61 248.9 92.23 249.77 92.23 248.4 C92.23 247.02 92.11 246.9 90.73 246.9 zM102.73 255.4 C101.36 255.4 96.9 257.19 96.9 258.57 C96.9 259.94 102.53 262.23 103.9 262.23 C105.28 262.23 106.23 259.94 106.23 258.57 C106.23 257.19 104.11 255.4 102.73 255.4 zM115.73 259.9 C114.36 259.9 114.73 260.02 114.73 261.4 C114.73 262.77 114.86 261.9 116.23 261.9 C117.61 261.9 117.23 262.77 117.23 261.4 C117.23 260.02 117.11 259.9 115.73 259.9 zM107.73 271.9 C106.36 271.9 106.73 272.02 106.73 273.4 C106.73 274.77 106.86 273.9 108.23 273.9 C109.61 273.9 109.23 274.77 109.23 273.4 C109.23 272.02 109.11 271.9 107.73 271.9 zM110.73 272.9 C109.36 272.9 109.73 273.02 109.73 274.4 C109.73 275.77 109.86 274.9 111.23 274.9 C112.61 274.9 112.23 275.77 112.23 274.4 C112.23 273.02 112.11 272.9 110.73 272.9 zM122.23 273.23 C121.32 273.23 120.23 274.65 120.23 275.57 C120.23 276.48 120.32 275.9 121.23 275.9 C122.15 275.9 124.57 277.15 124.57 276.23 C124.57 275.32 123.15 273.23 122.23 273.23 zM119.23 275.9 C118.32 275.9 118.57 275.98 118.57 276.9 C118.57 277.82 118.65 277.23 119.57 277.23 C120.48 277.23 120.23 277.82 120.23 276.9 C120.23 275.98 120.15 275.9 119.23 275.9 zM124.57 262.9 C123.65 262.9 122.23 266.32 122.23 267.23 C122.23 268.15 125.32 267.9 126.23 267.9 C127.15 267.9 128.57 265.15 128.57 264.23 C128.57 263.32 125.48 262.9 124.57 262.9 zM135.9 273.9 C134.53 273.9 134.73 274.02 134.73 275.4 C134.73 276.77 135.03 275.9 136.4 275.9 C137.78 275.9 137.23 276.77 137.23 275.4 C137.23 274.02 137.28 273.9 135.9 273.9 zM138.9 266.9 C137.53 266.9 139.57 270.19 139.57 271.57 C139.57 272.94 144.03 273.4 145.4 273.4 C146.78 273.4 144.23 271.61 144.23 270.23 C144.23 268.86 140.28 266.9 138.9 266.9 zM211 134.8 C209.63 134.8 209.83 134.93 209.83 136.3 C209.83 137.68 210.13 136.8 211.5 136.8 C212.88 136.8 212.33 137.68 212.33 136.3 C212.33 134.93 212.38 134.8 211 134.8 zM205.5 134.8 C204.13 134.8 204.33 134.93 204.33 136.3 C204.33 137.68 204.63 136.8 206 136.8 C207.38 136.8 206.83 137.68 206.83 136.3 C206.83 134.93 206.88 134.8 205.5 134.8 zM211 143.8 C209.63 143.8 209.83 143.93 209.83 145.3 C209.83 146.68 210.13 145.8 211.5 145.8 C212.88 145.8 212.33 146.68 212.33 145.3 C212.33 143.93 212.38 143.8 211 143.8 zM204.9 143.7 C203.53 143.7 203.73 143.83 203.73 145.2 C203.73 146.58 204.03 145.7 205.4 145.7 C206.78 145.7 206.23 146.58 206.23 145.2 C206.23 143.83 206.28 143.7 204.9 143.7 zM213 154.3 C211.63 154.3 212 155.43 212 156.8 C212 158.18 212.42 161.3 213.8 161.3 C215.17 161.3 214.33 157.18 214.33 155.8 C214.33 154.43 214.38 154.3 213 154.3 zM204 154.3 C202.63 154.3 202.6 155.53 202.6 156.9 C202.6 158.28 201.63 161.5 203 161.5 C204.38 161.5 204.8 157.68 204.8 156.3 C204.8 154.93 205.38 154.3 204 154.3 z").setFill("rgb(255,246,227)");
+ //surface.createLine({x1: 0, y1: 350, x2: 700, y2: 350}).setStroke("green");
+ //surface.createLine({y1: 0, x1: 350, y2: 700, x2: 350}).setStroke("green");
+ dojo.connect(dijit.byId("rotatingSlider"), "onChange", rotatingEvent);
+ dojo.connect(dijit.byId("scalingSlider"), "onChange", scalingEvent);
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+<style type="text/css">
+ td.pad { padding: 0px 5px 0px 5px; }
+</style>
+</head>
+<body class="tundra">
+ <h1>dojox.gfx: Butterfly</h1>
+ <p>This example was directly converted from SVG file.</p>
+ <p>This is a slightly modified version of a sample that shipped with JASC's WebDraw (www.jasc.com). Generated by Jasc WebDraw PR4(tm) on 06/07/01 12:18:39.</p>
+ <table>
+ <tr><td align="center" class="pad">Rotation (<span id="rotationValue">0</span>)</td></tr>
+ <tr><td>
+ <div id="rotatingSlider" dojoType="dijit.form.HorizontalSlider"
+ value="0" minimum="-180" maximum="180" discreteValues="72" showButtons="false" intermediateChanges="true"
+ style="width: 600px;">
+ <div dojoType="dijit.form.HorizontalRule" container="topDecoration" count="73" style="height:5px;"></div>
+ <div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count="9" style="height:5px;"></div>
+ <div dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" labels="-180,-135,-90,-45,0,45,90,135,180" style="height:1.2em;font-size:75%;color:gray;"></div>
+ </div>
+ </td></tr>
+ <tr><td align="center" class="pad">Scaling (<span id="scaleValue">1.000</span>)</td></tr>
+ <tr><td>
+ <div id="scalingSlider" dojoType="dijit.form.HorizontalSlider" intermediateChanges="true"
+ value="1" minimum="0" maximum="1" showButtons="false" style="width: 600px;">
+ <div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count="5" style="height:5px;"></div>
+ <div dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" labels="10%,18%,32%,56%,100%" style="height:1.2em;font-size:75%;color:gray;"></div>
+ </div>
+ </td></tr>
+ </table>
+ <div id="gfx_holder" style="width: 700px; height: 700px;"></div>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/demos/career_test.html b/includes/js/dojox/gfx/demos/career_test.html
new file mode 100644
index 0000000..3958395
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/career_test.html
@@ -0,0 +1,467 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
+<head>
+<title>dojox.gfx: Career Aptitude Test</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+
+<!--
+<script type="text/javascript" src="../Mover.js"></script>
+<script type="text/javascript" src="../Moveable.js"></script>
+<script type="text/javascript" src="../move.js"></script>
+<script type="text/javascript" src="../fx.js"></script>
+<script type="text/javascript" src="../shape.js"></script>
+-->
+
+<script type="text/javascript">
+
+dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.move");
+dojo.require("dojox.gfx.fx");
+dojo.require("dojo.colors");
+dojo.require("dojo.fx");
+
+var g = dojox.gfx, m = g.matrix;
+
+var container, surface, surface_size,
+ vat, freezer, broiler, score, startTime, endTime;
+
+var totalItems = 10, goodItems = 0, badItems = 0;
+
+var radius = 30, // pixels
+ slowRate = 10, // speed in ms per pixel
+ fastRate = 2, // speed in ms per pixel
+ freezeTime = 5000, // ms
+ frostTime = 2000, // ms
+ broilTime = 5000, // ms
+ burnTime = 2000, // ms
+ pulseTime = 200; // ms
+
+function getRand(from, to){
+ return Math.random() * (to - from) + from;
+}
+
+function inRect(rect, crd){
+ return rect.x <= crd.x && crd.x < rect.x + rect.width &&
+ rect.y <= crd.y && crd.y < rect.y + rect.height;
+}
+
+function getCenter(circle){
+ var shape = circle.getShape(), matrix = circle.getTransform();
+ return m.multiplyPoint(matrix ? matrix : m.identity, shape.cx, shape.cy);
+}
+
+function getDuration(x1, y1, x2, y2, rate){
+ return Math.floor(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) * rate);
+}
+
+function updateScore(){
+ var shape = score.getShape();
+ endTime = (new Date()).getTime();
+ shape.text = goodItems + " item" + (goodItems != 1 ? "s" : "") +
+ " in " + ((endTime - startTime) / 1000) + "s"
+ score.setShape(shape);
+
+ if(goodItems + badItems != totalItems){ return; }
+
+ var rating = goodItems / (endTime - startTime) * 60000 * (40 - radius) / 10;
+ dojo.byId("result_pass").style.display = badItems || rating < 5 ? "none" : "";
+ dojo.byId("result_dollar").innerHTML = rating.toFixed(2);
+ dojo.byId("result_but").style.display = badItems ? "" : "none";
+ dojo.byId("result_waste").innerHTML = (badItems * 5).toFixed(2);
+ dojo.byId("result_and").style.display = badItems ? "none" : "";
+ dojo.byId("result_fail").style.display = badItems ? "" : "none";
+ if(!badItems){
+ var pos;
+ if(rating < 1){
+ pos = "Junior Speciment Flipper";
+ }else if(rating < 2){
+ pos = "Senior Speciment Flipper";
+ }else if(rating < 4){
+ pos = "Shift Supervisor";
+ }else if(rating < 6){
+ pos = "Joint Manager";
+ }else if(rating < 8){
+ pos = "Night Director";
+ }else if(rating < 10){
+ pos = "Morning Director";
+ }else if(rating < 12){
+ pos = "Vice President";
+ }else if(rating < 14){
+ pos = "Senior Vice President";
+ }else if(rating < 16){
+ pos = "Chief of Something";
+ }else{
+ pos = "Nominal President";
+ }
+ dojo.byId("result_pos").innerHTML = pos;
+ }
+ var anim1 = dojo.fx.wipeOut({
+ node: "gfx_holder",
+ duration: 500,
+ delay: 1000
+ }),
+ anim2 = dojo.fx.wipeIn({
+ node: "result",
+ duration: 500,
+ delay: 1000
+ });
+ anim1.play();
+ anim2.play();
+}
+
+function showStatus(circle, text){
+ var c = getCenter(circle),
+ status = surface.createText({});
+ status.moveToBack().setFill(new dojo.Color([0, 0, 0, 0.5]))
+ .setFont({family: "serif", variant: "small-caps", weight: "bold"})
+ .setShape({x: c.x, y: c.y, text: text, align: "middle"});
+ var anim = dojo.fx.combine([
+ g.fx.animateFill({
+ shape: status,
+ duration: 3000,
+ color: {end: "transparent"}
+ }),
+ g.fx.animateTransform({
+ shape: status,
+ duration: 3000,
+ transform: [
+ {name: "translate", start: [0, 0], end: [0, 300]},
+ {name: "original"}
+ ]
+ })
+ ]);
+ dojo.connect(anim, "onEnd", function(){ status.removeShape(); });
+ anim.play();
+}
+
+function moveToPile(shape, bad){
+ if(shape.moveable){
+ shape.moveable.destroy();
+ delete shape.moveable;
+ }
+
+ var oldColor = shape.getFill(), c = getCenter(shape),
+ newX = 80 + (bad ? badItems++ : goodItems++) * 2.25 * 10,
+ newY = bad ? 445 : 415,
+ duration = getDuration(newX, newY, c.x, c.y, fastRate),
+ anim = dojo.fx.chain([
+ g.fx.animateFill({
+ shape: shape,
+ duration: 250,
+ color: {end: "transparent"}
+ }),
+ g.fx.animateTransform({
+ shape: shape,
+ duration: duration,
+ transform: [
+ {name: "translate", start: [0, 0], end: [newX - c.x, newY - c.y]},
+ {name: "original"}
+ ]
+ }),
+ g.fx.animateFill({
+ shape: shape,
+ duration: 250,
+ color: {end: oldColor}
+ }),
+ g.fx.animateTransform({
+ shape: shape,
+ duration: duration,
+ transform: [
+ {name: "scaleAt", start: [1, newX, newY], end: [10 / radius, newX, newY]},
+ {name: "original"}
+ ]
+ })
+ ]);
+ dojo.connect(anim, "onEnd", updateScore);
+ anim.play();
+}
+
+function repeatMove(){
+ var rect = vat.getShape(), c = getCenter(this),
+ x = getRand(rect.x + radius, rect.x + rect.width - radius),
+ y = getRand(rect.y + radius, rect.y + rect.height - radius),
+ duration = getDuration(x, y, c.x, c.y, slowRate);
+ this.anim = g.fx.animateTransform({
+ duration: duration,
+ shape: this,
+ transform: [
+ {name: "translate", start: [0, 0], end: [x - c.x, y - c.y]},
+ {name: "original"}
+ ]
+ });
+ dojo.connect(this.anim, "onEnd", this, repeatMove);
+ this.anim.play();
+}
+
+function repeatFrost(){
+ this.status = "frozen";
+ this.setStroke({color: "orange", width: 3});
+ showStatus(this, "Ready");
+ this.anim = g.fx.animateFill({
+ duration: frostTime,
+ shape: this,
+ color: {end: "white"}
+ });
+ // calculate a shift
+ var dx = getRand(-radius, radius) / 2, dy = getRand(-radius, radius) / 2, sign = 1;
+ this.applyLeftTransform({dx: -dx / 2, dy: -dy / 2});
+ dojo.connect(this.anim, "onAnimate", this, function(){
+ this.applyLeftTransform({dx: sign * dx, dy: sign * dy});
+ sign = -sign;
+ });
+ dojo.connect(this.anim, "onEnd", this, function(){
+ showStatus(this, "Frozen");
+ moveToPile(this, true);
+ });
+ this.anim.play();
+}
+
+function repeatFreeze(){
+ this.status = "freezing";
+ this.setStroke({color: "black", width: 3});
+ this.anim = g.fx.animateFill({
+ duration: freezeTime,
+ shape: this,
+ color: {end: "blue"}
+ });
+ // calculate a shift
+ var dx = getRand(-radius, radius) / 2, dy = getRand(-radius, radius) / 2, sign = 1;
+ this.applyLeftTransform({dx: -dx / 2, dy: -dy / 2});
+ dojo.connect(this.anim, "onAnimate", this, function(){
+ this.applyLeftTransform({dx: sign * dx, dy: sign * dy});
+ sign = -sign;
+ });
+ dojo.connect(this.anim, "onEnd", this, repeatFrost);
+ this.anim.play();
+}
+
+function repeatBurn(){
+ this.status = "burnt";
+ this.setStroke({color: "orange", width: 3});
+ showStatus(this, "Done");
+ var anim1 = g.fx.animateFill({
+ duration: burnTime,
+ shape: this,
+ color: {end: "black"}
+ });
+ var anim2 = new dojo._Animation({
+ duration: freezeTime,
+ curve: [0, freezeTime]
+ });
+ var matrix = this.getTransform(), c = getCenter(this);
+ dojo.connect(anim2, "onAnimate", this, function(val){
+ var scale = (val % pulseTime) / pulseTime / 4 + 1;
+ this.setTransform([m.scaleAt(scale, c), matrix]);
+ });
+ this.anim = dojo.fx.combine([anim1, anim2]);
+ dojo.connect(this.anim, "onEnd", this, function(){
+ showStatus(this, "Burnt");
+ moveToPile(this, true);
+ });
+ this.anim.play();
+}
+
+function repeatBroil(){
+ this.status = "broiling";
+ this.setStroke({color: "black", width: 3});
+ var anim1 = g.fx.animateFill({
+ duration: broilTime,
+ shape: this,
+ color: {end: "red"}
+ });
+ var anim2 = new dojo._Animation({
+ duration: freezeTime,
+ curve: [0, freezeTime]
+ });
+ var matrix = this.getTransform(), c = getCenter(this);
+ dojo.connect(anim2, "onAnimate", this, function(val){
+ var scale = (val % pulseTime) / pulseTime / 4 + 1;
+ this.setTransform([m.scaleAt(scale, c), matrix]);
+ });
+ this.anim = dojo.fx.combine([anim1, anim2]);
+ dojo.connect(this.anim, "onEnd", this, repeatBurn);
+ this.anim.play();
+}
+
+function drag(mover){
+ var shape = mover.shape;
+ shape.anim.stop();
+ shape.anim = null;
+}
+
+function drop(mover){
+ var c = getCenter(mover.shape);
+ do{ // break block
+ if(inRect(vat.getShape(), c)){
+ if(mover.shape.status == "fresh"){
+ repeatMove.call(mover.shape);
+ return;
+ }
+ break;
+ }
+ if(inRect(freezer.getShape(), c)){
+ if(mover.shape.status == "fresh"){
+ repeatFreeze.call(mover.shape);
+ return;
+ }
+ break;
+ }
+ if(inRect(broiler.getShape(), c)){
+ if(mover.shape.status == "frozen"){
+ repeatBroil.call(mover.shape);
+ return;
+ }
+ break;
+ }
+ if(mover.shape.status == "burnt"){
+ moveToPile(mover.shape, false); // good
+ return;
+ }
+ }while(false);
+ moveToPile(mover.shape, true); // bad
+}
+
+function makePatties(n){
+ var rect = vat.getShape();
+ for(var i = 0; i < n; ++i){
+ var cx = getRand(rect.x + radius, rect.x + rect.width - radius),
+ cy = getRand(rect.y + radius, rect.y + rect.height - radius),
+ patty = surface.createCircle({
+ cx: cx, cy: cy, r: radius
+ }).setFill("green").setStroke({
+ color: "black",
+ width: 3
+ });
+ patty.status = "fresh";
+ patty.moveable = new g.Moveable(patty);
+ repeatMove.call(patty);
+ }
+}
+
+function initGfx(){
+ container = dojo.byId("gfx_holder");
+ surface = g.createSurface(container, 500, 500);
+ surface_size = {width: 500, height: 500};
+
+ vat = surface.createRect({x: 10, y: 210, width: 480, height: 180})
+ .setStroke({color: "black", width: 7, join: "round"});
+ surface.createText({x: 15, y: 230, text: "Ye Olde Vat v3.2"})
+ .setFill("black");
+
+ freezer = surface.createRect({x: 10, y: 10, width: 230, height: 180})
+ .setStroke({color: "blue", width: 7, join: "round"});
+ surface.createText({x: 15, y: 30, text: "Deep Freeze 7000"})
+ .setFill("blue");
+
+ broiler = surface.createRect({x: 260, y: 10, width: 230, height: 180})
+ .setStroke({color: "red", width: 7, join: "round"});
+ surface.createText({x: 265, y: 30, text: "Hellfire Broiler A4"})
+ .setFill("red");
+
+ surface.createText({x: 15, y: 420, text: "Good:"})
+ .setFont({weight: "bold"}).setFill("green");
+ surface.createText({x: 15, y: 450, text: "Bad:"})
+ .setFont({weight: "bold"}).setFill("red");
+ surface.createText({x: 15, y: 480, text: "Total:"})
+ .setFont({weight: "bold"}).setFill("black");
+ score = surface.createText({x: 80, y: 485, text: "0"})
+ .setFont({weight: "bold", size: "24pt"}).setFill("black");
+ surface.createText({x: 120, y: 460, text: "DROP HERE!"})
+ .setFont({size: "50px"})
+ .setFill(new dojo.Color([0, 0, 0, 0.1])).moveToBack();
+
+ dojo.subscribe("/gfx/move/start", drag);
+ dojo.subscribe("/gfx/move/stop", drop);
+ makePatties(totalItems);
+
+ startTime = (new Date()).getTime();
+
+ // cancel text selection and text dragging
+ dojo.connect(container, "ondragstart", dojo, "stopEvent");
+ dojo.connect(container, "onselectstart", dojo, "stopEvent");
+}
+
+//dojo.addOnLoad(initGfx);
+
+function startTest(level){
+ radius = level;
+ var anim = dojo.fx.wipeOut({
+ node: "explanation",
+ duration: 500
+ });
+ dojo.connect(anim, "onEnd", function(){
+ dojo.byId("gfx_holder").style.display = "";
+ initGfx();
+ });
+ anim.play();
+}
+
+</script>
+
+<style type="text/css">
+.movable { cursor: pointer; }
+</style>
+
+</head>
+<body>
+<h1>dojox.gfx: Career Aptitude Test</h1>
+<p>Warning: Canvas renderer doesn't implement event handling.</p>
+
+<div id="explanation">
+<p>Thank you for your interest in <em>"I can't believe it's manure" Eateries&trade;</em>
+and for submitting your resume for our review. While this is an automated response,
+please be assured that every resume is reviewed by us, and forwarded to the hiring
+managers if the skills fit our needs.</p>
+<p>In order order to evaluate your skills we ask you to take a career aptitude test.
+You will have an exciting chance to operate one of our state-of-the-art workstations
+remotely. Don't forget:
+</p>
+<ol>
+ <li>Fish out a live speciment of <em>dung-42</em> from the container.</li>
+ <li>Freeze it until you see an orange glow to kill the elements and make it less green.</li>
+ <li>Broil it until you see the orange glow again, and drop it on the table below.</li>
+ <li>You have to process all items without wasting resources and in minimal time.</li>
+</ol>
+<p>Warnings: don't overfreeze, don't overheat, don't drop the speciment, don't change the sequence,
+don't touch the speciment in heating and freezing chambers until it is's ready.</p>
+<p>Use your head and your mouse!</p>
+<p>Please select the desired position:</p>
+<table>
+ <tr>
+ <td>Workstation Supervisor&nbsp;</td>
+ <td><button onclick="startTest(30);">Apply</button></td>
+ </tr>
+ <tr>
+ <td>Shift Director&nbsp;</td>
+ <td><button onclick="startTest(20);">Apply</button></td>
+ </tr>
+ <tr>
+ <td>Vice President #49653&nbsp;</td>
+ <td><button onclick="startTest(10);">Apply</button></td>
+ </tr>
+</table>
+</div>
+
+<div id="gfx_holder" style="width: 500px; height: 500px; display: none;"></div>
+
+<div id="result" style="display: none;">
+<p id="result_pass"><strong>Impressive! Please contact us immediately.</strong></p>
+<p>You have made $<span id="result_dollar"></span> per minute for us.
+<span id="result_but">But you wasted $<span id="result_waste"></span> in materials.</span>
+<span id="result_and">It qualifies you to be a <em id="result_pos"></em>.</span>
+</p>
+<p id="result_fail">Should our hiring managers have an interest in your skills and
+capabilities, they will contact you directly. In addition, we will keep
+your resume on file for one year.</p>
+</div>
+
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/demos/circles.html b/includes/js/dojox/gfx/demos/circles.html
new file mode 100644
index 0000000..ce4d0cd
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/circles.html
@@ -0,0 +1,90 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
+<head>
+<title>dojox.gfx: 100 draggable circles</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+
+dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.move");
+
+var container = null,
+ surface = null,
+ surface_size = null;
+
+function getRand(from, to){
+ return Math.random() * (to - from) + from;
+}
+
+var skew_stat_factor = 15;
+
+function getRandSkewed(from, to){
+ // let skew stats to smaller values
+ var seed = 0;
+ for(var i = 0; i < skew_stat_factor; ++i){
+ seed += Math.random();
+ }
+ seed = 2 * Math.abs(seed / skew_stat_factor - 0.5);
+ return seed * (to - from) + from;
+}
+
+function randColor(alpha){
+ var red = Math.floor(getRand(0, 255)),
+ green = Math.floor(getRand(0, 255)),
+ blue = Math.floor(getRand(0, 255)),
+ opacity = alpha ? getRand(0.1, 1) : 1;
+ return [red, green, blue, opacity];
+}
+
+var gShapes = {}
+var gShapeCounter = 0;
+
+function makeCircleGrid(itemCount){
+ var minR = 10, maxR = surface_size.width / 3;
+ for(var j = 0; j < itemCount; ++j){
+ var r = getRandSkewed(minR, maxR),
+ cx = getRand(r, surface_size.width - r),
+ cy = getRand(r, surface_size.height - r),
+ shape = surface.createCircle({cx: cx, cy: cy, r: r})
+ .setFill(randColor(true))
+ .setStroke({color: randColor(true), width: getRand(0, 3)})
+ ;
+ new dojox.gfx.Moveable(shape);
+ }
+}
+
+function initGfx(){
+ container = dojo.byId("gfx_holder");
+ surface = dojox.gfx.createSurface(container, 500, 500);
+ surface_size = {width: 500, height: 500};
+
+ makeCircleGrid(100);
+
+ // cancel text selection and text dragging
+ dojo.connect(container, "ondragstart", dojo, "stopEvent");
+ dojo.connect(container, "onselectstart", dojo, "stopEvent");
+}
+
+dojo.addOnLoad(initGfx);
+
+</script>
+
+<style type="text/css">
+.movable { cursor: pointer; }
+</style>
+
+</head>
+<body>
+<h1>dojox.gfx: 100 draggable circles</h1>
+<p>Warning: Canvas renderer doesn't implement event handling.</p>
+<div id="gfx_holder" style="width: 500px; height: 500px;"></div>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/demos/clock.html b/includes/js/dojox/gfx/demos/clock.html
new file mode 100644
index 0000000..8d4d8c1
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/clock.html
@@ -0,0 +1,253 @@
+<html>
+<head>
+<title>dojox.gfx: interactive analog clock</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverlight.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+
+dojo.require("dojox.gfx");
+dojo.require("dojo.date.locale");
+
+var current_time = new Date();
+
+var hour_hand = null;
+var minute_hand = null;
+var second_hand = null;
+
+var hour_shadow = null;
+var minute_shadow = null;
+var second_shadow = null;
+
+var center = {x: 385 / 2, y: 385 / 2};
+
+var hour_shadow_shift = {dx: 2, dy: 2};
+var minute_shadow_shift = {dx: 3, dy: 3};
+var second_shadow_shift = {dx: 4, dy: 4};
+
+var selected_hand = null;
+var container = null;
+var container_position = null;
+var text_time = null;
+var diff_time = new Date();
+
+placeHand = function(shape, angle, shift){
+ var move = {dx: center.x + (shift ? shift.dx : 0), dy: center.y + (shift ? shift.dy : 0)};
+ return shape.setTransform([move, dojox.gfx.matrix.rotateg(angle)]);
+};
+
+placeHourHand = function(h, m, s){
+ var angle = 30 * (h % 12 + m / 60 + s / 3600);
+ placeHand(hour_hand, angle);
+ placeHand(hour_shadow, angle, hour_shadow_shift);
+};
+
+placeMinuteHand = function(m, s){
+ var angle = 6 * (m + s / 60);
+ placeHand(minute_hand, angle);
+ placeHand(minute_shadow, angle, minute_shadow_shift);
+};
+
+placeSecondHand = function(s){
+ var angle = 6 * s;
+ placeHand(second_hand, angle);
+ placeHand(second_shadow, angle, second_shadow_shift);
+};
+
+reflectTime = function(time, hold_second_hand, hold_minute_hand, hold_hour_hand){
+ if(!time) time = current_time;
+ var h = time.getHours();
+ var m = time.getMinutes();
+ var s = time.getSeconds();
+ if(!hold_hour_hand) placeHourHand(h, m, s);
+ if(!hold_minute_hand) placeMinuteHand(m, s);
+ if(!hold_second_hand) placeSecondHand(s);
+ text_time.innerHTML = dojo.date.locale.format(
+ time, {selector: "time", timePattern: "h:mm:ss a"});
+};
+
+resetTime = function(){
+ current_time = new Date();
+ reflectTime();
+};
+
+tick = function(){
+ current_time.setSeconds(current_time.getSeconds() + 1);
+ reflectTime();
+};
+
+advanceTime = function(){
+ if(!selected_hand) {
+ tick();
+ }
+};
+
+normalizeAngle = function(angle){
+ if(angle > Math.PI) {
+ angle -= 2 * Math.PI;
+ } else if(angle < -Math.PI) {
+ angle += 2 * Math.PI;
+ }
+ return angle;
+};
+
+calculateAngle = function(x, y, handAngle){
+ try {
+ return normalizeAngle(Math.atan2(y - center.y, x - center.x) - handAngle);
+ } catch(e) {
+ // supress
+ }
+ return 0;
+};
+
+getSecondAngle = function(time){
+ if(!time) time = current_time;
+ return (6 * time.getSeconds() - 90) / 180 * Math.PI;
+};
+
+getMinuteAngle = function(time){
+ if(!time) time = current_time;
+ return (6 * (time.getMinutes() + time.getSeconds() / 60) - 90) / 180 * Math.PI;
+};
+
+getHourAngle = function(time){
+ if(!time) time = current_time;
+ return (30 * (time.getHours() + (time.getMinutes() + time.getSeconds() / 60) / 60) - 90) / 180 * Math.PI;
+};
+
+onMouseDown = function(evt){
+ selected_hand = evt.target;
+ diff_time.setTime(current_time.getTime());
+ dojo.stopEvent(evt);
+};
+
+onMouseMove = function(evt){
+ if(!selected_hand) return;
+ if(evt.target == second_hand.getEventSource() ||
+ evt.target == minute_hand.getEventSource() ||
+ evt.target == hour_hand.getEventSource()){
+ dojo.stopEvent(evt);
+ return;
+ }
+ if(dojox.gfx.equalSources(selected_hand, second_hand.getEventSource())){
+ var angle = calculateAngle(
+ evt.clientX - container_position.x,
+ evt.clientY - container_position.y,
+ normalizeAngle(getSecondAngle())
+ );
+ var diff = Math.round(angle / Math.PI * 180 / 6); // in whole seconds
+ current_time.setSeconds(current_time.getSeconds() + Math.round(diff));
+ reflectTime();
+ }else if(dojox.gfx.equalSources(selected_hand, minute_hand.getEventSource())){
+ var angle = calculateAngle(
+ evt.clientX - container_position.x,
+ evt.clientY - container_position.y,
+ normalizeAngle(getMinuteAngle(diff_time))
+ );
+ var diff = Math.round(angle / Math.PI * 180 / 6 * 60); // in whole seconds
+ diff_time.setTime(diff_time.getTime() + 1000 * diff);
+ reflectTime(diff_time, true);
+
+ }else if(dojox.gfx.equalSources(selected_hand, hour_hand.getEventSource())){
+ var angle = calculateAngle(
+ evt.clientX - container_position.x,
+ evt.clientY - container_position.y,
+ normalizeAngle(getHourAngle(diff_time))
+ );
+ var diff = Math.round(angle / Math.PI * 180 / 30 * 60 * 60); // in whole seconds
+ diff_time.setTime(diff_time.getTime() + 1000 * diff);
+ reflectTime(diff_time, true, true);
+ }else{
+ return;
+ }
+ dojo.stopEvent(evt);
+};
+
+onMouseUp = function(evt){
+ if(selected_hand && !dojox.gfx.equalSources(selected_hand, second_hand.getEventSource())){
+ current_time.setTime(diff_time.getTime());
+ reflectTime();
+ }
+ selected_hand = null;
+ dojo.stopEvent(evt);
+};
+
+makeShapes = function(){
+ // prerequisites
+ container = dojo.byId("gfx_holder");
+ container_position = dojo.coords(container, true);
+ text_time = dojo.byId("time");
+ var surface = dojox.gfx.createSurface(container, 385, 385);
+ surface.createImage({width: 385, height: 385, src: "images/clock_face.jpg"});
+
+ // hand shapes
+ var hour_hand_points = [{x: -7, y: 15}, {x: 7, y: 15}, {x: 0, y: -60}, {x: -7, y: 15}];
+ var minute_hand_points = [{x: -5, y: 15}, {x: 5, y: 15}, {x: 0, y: -100}, {x: -5, y: 15}];
+ var second_hand_points = [{x: -2, y: 15}, {x: 2, y: 15}, {x: 2, y: -105}, {x: 6, y: -105}, {x: 0, y: -116}, {x: -6, y: -105}, {x: -2, y: -105}, {x: -2, y: 15}];
+
+ // create shapes
+ hour_shadow = surface.createPolyline(hour_hand_points)
+ .setFill([0, 0, 0, 0.1])
+ ;
+ hour_hand = surface.createPolyline(hour_hand_points)
+ .setStroke({color: "black", width: 2})
+ .setFill("#889")
+ ;
+ minute_shadow = surface.createPolyline(minute_hand_points)
+ .setFill([0, 0, 0, 0.1])
+ ;
+ minute_hand = surface.createPolyline(minute_hand_points)
+ .setStroke({color: "black", width: 2})
+ .setFill("#ccd")
+ ;
+ second_shadow = surface.createPolyline(second_hand_points)
+ .setFill([0, 0, 0, 0.1])
+ ;
+ second_hand = surface.createPolyline(second_hand_points)
+ .setStroke({color: "#800", width: 1})
+ .setFill("#d00")
+ ;
+
+ // next 3 lines kill Silverlight because its nodes do not support CSS
+ //dojox.gfx._addClass(hour_hand .getEventSource(), "movable");
+ //dojox.gfx._addClass(minute_hand.getEventSource(), "movable");
+ //dojox.gfx._addClass(second_hand.getEventSource(), "movable");
+
+ surface.createCircle({r: 1}).setFill("black").setTransform({dx: 192.5, dy: 192.5});
+
+ // attach events
+ hour_hand .connect("onmousedown", onMouseDown);
+ minute_hand.connect("onmousedown", onMouseDown);
+ second_hand.connect("onmousedown", onMouseDown);
+ dojo.connect(container, "onmousemove", onMouseMove);
+ dojo.connect(container, "onmouseup", onMouseUp);
+ dojo.connect(dojo.byId("reset"), "onclick", resetTime);
+
+ // start the clock
+ resetTime();
+ window.setInterval(advanceTime, 1000);
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+<style type="text/css">
+.movable { cursor: hand; }
+</style>
+</head>
+<body>
+<h1>dojox.gfx: interactive analog clock</h1>
+<p>Grab hands and set your own time.</p>
+<p>Warning: Canvas renderer doesn't implement event handling.</p>
+<div id="gfx_holder" style="width: 385px; height: 385px;"></div>
+<p>Current time: <span id="time"></span>.</p>
+<p><button id="reset">Reset</button></p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/demos/clockWidget.html b/includes/js/dojox/gfx/demos/clockWidget.html
new file mode 100644
index 0000000..409523c
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/clockWidget.html
@@ -0,0 +1,332 @@
+<html>
+<head>
+<title>dojox.gfx: interactive analog clock</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/themes/dijit.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverlight.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:true"></script>
+<script type="text/javascript">
+ dojo.require("dijit._Widget");
+ dojo.require("dijit._Templated");
+ dojo.require("dojox.gfx");
+ dojo.require("dojo.date.locale");
+ dojo.declare("demo.Clock",dijit._Widget,{
+
+ time:"",
+
+ img:"images/clock_face_black.jpg",
+
+ postCreate:function(){
+ this.inherited(arguments);
+ if(!this.time){ this.current_time = new Date(); }else{
+ this.current_time = this.time;
+ }
+ dojo.mixin(this,{
+
+ diff_time: new Date(),
+
+ hour_hand:null,
+ hour_shadow:null,
+ hour_shadow_shift:{dx: 2, dy: 2},
+
+ minute_hand:null,
+ minute_shadow:null,
+ minute_shadow_shift:{dx: 3, dy: 3},
+
+ second_hand:null,
+ second_shadow:null,
+ second_shadow_shift:{dx: 4, dy: 4},
+
+ container_position: null
+
+ });
+
+ this._setSize();
+
+ this._init();
+ },
+
+ _setSize:function(){
+
+ this.container_position = dojo.coords(this.domNode, true);
+ this.mb = dojo.marginBox(this.domNode);
+ this.center = {
+ x: (this.mb.w / 2),
+ y: (this.mb.h / 2)
+ };
+
+ },
+
+ _init:function(){
+
+ this.surface = dojox.gfx.createSurface(this.domNode, this.mb.w, this.mb.h);
+ this.group = this.surface.createGroup();
+ this.group.createImage({
+ width: this.center.x * 2,
+ height:this.center.y * 2,
+ src: this.img
+ });
+
+ // hand shapes
+ var _off = 15;
+ var mar = ((this.mb.w / 2) - _off) * -1;
+ var _c = mar * 0.7; // -105;
+ var _a = mar * 0.5; //-60;
+ var _b = mar * 0.75; // -100;
+ var _d = mar * 0.8; // -116;
+ var _e = mar * 0.0523; // -7ish
+ var _f = mar * 0.042;
+ var _g = mar * 0.01234;
+
+ var hour_hand_points = [{x: _e, y: _off }, {x: _e * -1, y: _off }, {x: 0, y: _a }, {x: _e, y: _off }];
+ var minute_hand_points = [{x: _f, y: _off }, {x: _f * -1, y: _off }, {x: 0, y: _b }, {x: _f, y: _off }];
+ var second_hand_points = [
+ {x: _g, y: _off }, {x: _g * -1, y: _off }, {x: _g * -1, y: _c },
+ {x: _e * -1, y: _c }, {x: 0, y: _d }, {x: _e, y: _c },
+ {x: _g, y: _c }, {x: _g, y: _off }
+ ];
+
+ // create shapes
+ this.hour_shadow = this.group.createPolyline(hour_hand_points)
+ .setFill([0, 0, 0, 0.1])
+ ;
+ this.hour_hand = this.group.createPolyline(hour_hand_points)
+ .setStroke({color: "black", width: 2})
+ .setFill("#889")
+ ;
+ this.minute_shadow = this.group.createPolyline(minute_hand_points)
+ .setFill([0, 0, 0, 0.1])
+ ;
+ this.minute_hand = this.group.createPolyline(minute_hand_points)
+ .setStroke({color: "black", width: 2})
+ .setFill("#ccd")
+ ;
+ this.second_shadow = this.group.createPolyline(second_hand_points)
+ .setFill([0, 0, 0, 0.1])
+ ;
+ this.second_hand = this.group.createPolyline(second_hand_points)
+ .setStroke({color: "#800", width: 1})
+ .setFill("#d00")
+ ;
+
+ this.group.createCircle({r: 1}).setFill("black").setTransform({dx: this.center.x, dy: this.center.y });
+
+ // start the clock
+ this.resetTime();
+
+ window.setInterval(dojo.hitch(this,"advanceTime"), 1000);
+ },
+
+ placeHand: function(shape, angle, shift){
+ var move = {dx: this.center.x + (shift ? shift.dx : 0), dy: this.center.y + (shift ? shift.dy : 0)};
+ return shape.setTransform([move, dojox.gfx.matrix.rotateg(angle)]);
+ },
+
+ placeHourHand: function(h, m, s){
+ var angle = 30 * (h % 12 + m / 60 + s / 3600);
+ this.placeHand(this.hour_hand, angle);
+ this.placeHand(this.hour_shadow, angle, this.hour_shadow_shift);
+ },
+
+ placeMinuteHand: function(m, s){
+ var angle = 6 * (m + s / 60);
+ this.placeHand(this.minute_hand, angle);
+ this.placeHand(this.minute_shadow, angle, this.minute_shadow_shift);
+ },
+
+ placeSecondHand:function(s){
+ var angle = 6 * s;
+ this.placeHand(this.second_hand, angle);
+ this.placeHand(this.second_shadow, angle, this.second_shadow_shift);
+ },
+
+ reflectTime: function(time, hold_second_hand, hold_minute_hand, hold_hour_hand){
+ if(!time){ time = this.current_time; }
+ var h = time.getHours();
+ var m = time.getMinutes();
+ var s = time.getSeconds();
+
+ if(!hold_hour_hand) this.placeHourHand(h, m, s);
+ if(!hold_minute_hand) this.placeMinuteHand(m, s);
+ if(!hold_second_hand) this.placeSecondHand(s);
+
+ this.text_time = dojo.date.locale.format(
+ time, {selector: "time", timePattern: "h:mm:ss a"}
+ );
+ },
+
+ resetTime: function(){
+ this.current_time = new Date();
+ this.reflectTime();
+ },
+
+ tick: function(){
+ this.current_time.setSeconds(this.current_time.getSeconds()+1);
+ this.reflectTime();
+ },
+
+ advanceTime: function(){
+ if(!this.selected_hand){
+ this.tick();
+ }
+ },
+
+ normalizeAngle: function(angle){
+ if(angle > Math.PI) {
+ angle -= 2 * Math.PI;
+ } else if(angle < -Math.PI) {
+ angle += 2 * Math.PI;
+ }
+ return angle;
+ },
+
+ calculateAngle: function(x, y, handAngle){
+ try {
+ return this.normalizeAngle(Math.atan2(y - this.center.y, x - this.center.x) - handAngle);
+ }catch(e){ /* supress */ }
+ return 0;
+ },
+
+ getSecondAngle: function(time){
+ if(!time) time = this.current_time;
+ return (6 * time.getSeconds() - 90) / 180 * Math.PI;
+ },
+
+ getMinuteAngle: function(time){
+ if(!time) time = this.current_time;
+ return (6 * (time.getMinutes() + time.getSeconds() / 60) - 90) / 180 * Math.PI;
+ },
+
+ getHourAngle: function(time){
+ if(!time) time = this.current_time;
+ return (30 * (time.getHours() + (time.getMinutes() + time.getSeconds() / 60) / 60) - 90) / 180 * Math.PI;
+ },
+
+ resize: function(size){
+ this.surface.setDimensions(size.w, size.h);
+ this.group.setTransform(dojox.gfx.matrix.scale(size.w/this.mb.w, size.h/this.mb.h));
+ this._setSize();
+ }
+
+ });
+
+ dojo.declare("demo.InteractiveClock",demo.Clock,{
+
+ _init: function(){
+ this.inherited(arguments);
+ // attach events
+ this.diff_time = new Date();
+ this.hour_hand .connect("onmousedown", this,"onMouseDown");
+ this.minute_hand.connect("onmousedown", this,"onMouseDown");
+ this.second_hand.connect("onmousedown", this,"onMouseDown");
+ this.connect(this.domNode, "onmousemove", "onMouseMove");
+ this.connect(this.domNode, "onmouseup", "onMouseUp");
+
+ },
+
+ onMouseDown: function(evt){
+ this.selected_hand = evt.target;
+ this.diff_time.setTime(this.current_time.getTime());
+ dojo.stopEvent(evt);
+ },
+
+ onMouseMove: function(evt){
+ if(!this.selected_hand) return;
+ if(evt.target == this.second_hand.getEventSource() ||
+ evt.target == this.minute_hand.getEventSource() ||
+ evt.target == this.hour_hand.getEventSource()){
+ dojo.stopEvent(evt);
+ return;
+ }
+ if(dojox.gfx.equalSources(this.selected_hand, this.second_hand.getEventSource())){
+ var angle = this.calculateAngle(
+ evt.clientX - this.container_position.x,
+ evt.clientY - this.container_position.y,
+ this.normalizeAngle(this.getSecondAngle())
+ );
+ var diff = Math.round(angle / Math.PI * 180 / 6); // in whole seconds
+ this.current_time.setSeconds(this.current_time.getSeconds() + Math.round(diff));
+ this.reflectTime();
+ }else if(dojox.gfx.equalSources(this.selected_hand, this.minute_hand.getEventSource())){
+ var angle = this.calculateAngle(
+ evt.clientX - this.container_position.x,
+ evt.clientY - this.container_position.y,
+ this.normalizeAngle(this.getMinuteAngle(this.diff_time))
+ );
+ var diff = Math.round(angle / Math.PI * 180 / 6 * 60); // in whole seconds
+ this.diff_time.setTime(this.diff_time.getTime() + 1000 * diff);
+ this.reflectTime(this.diff_time, true);
+
+ }else if(dojox.gfx.equalSources(this.selected_hand, this.hour_hand.getEventSource())){
+ var angle = this.calculateAngle(
+ evt.clientX - this.container_position.x,
+ evt.clientY - this.container_position.y,
+ this.normalizeAngle(this.getHourAngle(this.diff_time))
+ );
+ var diff = Math.round(angle / Math.PI * 180 / 30 * 60 * 60); // in whole seconds
+ this.diff_time.setTime(this.diff_time.getTime() + 1000 * diff);
+ this.reflectTime(this.diff_time, true, true);
+ }else{
+ return;
+ }
+ dojo.stopEvent(evt);
+ },
+
+ onMouseUp:function(evt){
+ if(this.selected_hand && !dojox.gfx.equalSources(this.selected_hand, this.second_hand.getEventSource())){
+ this.current_time.setTime(this.diff_time.getTime());
+ this.reflectTime();
+ }
+ this.selected_hand = null;
+ dojo.stopEvent(evt);
+ }
+ });
+ dojo.require("dijit.form.Button");
+ dojo.addOnLoad(function(){
+ var n = dojo.doc.createElement('div');
+ dojo.body().appendChild(n);
+ dojo.style(n,{
+ height:"200px", width:"200px",
+ border:"5px solid #ededed"
+ });
+ new demo.Clock({},n);
+ });
+
+</script>
+<style type="text/css">
+.movable { cursor: hand; }
+</style>
+</head>
+<body>
+<h1>dojox.gfx: interactive analog clock</h1>
+<p>Grab hands and set your own time.</p>
+<p>Warning: Canvas renderer doesn't implement event handling.</p>
+
+<button dojoType="dijit.form.Button">
+ Resize
+ <script type="dojo/method" event="onClick">
+ dijit.byId("one").resize({ w:250, h:250 });
+ </script>
+</button>
+
+<hr noshade size="0" />
+
+<div class="dijitInline" dojoType="demo.Clock" id="gfx_holder" style="width: 300px; height: 300px;"></div>
+<div class="dijitInline" img="images/clock_face.jpg" dojoType="demo.InteractiveClock" style="width: 225px; height: 225px;"></div>
+<div class="dijitInline" id="one" dojoType="demo.Clock" style="width: 150px; height: 150px;"></div>
+<div class="dijitInline" dojoType="demo.Clock" style="width: 75px; height: 75px;"></div>
+
+<hr noshade size="0" />
+
+
+
+
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/demos/clock_black.html b/includes/js/dojox/gfx/demos/clock_black.html
new file mode 100644
index 0000000..4c72770
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/clock_black.html
@@ -0,0 +1,253 @@
+<html>
+<head>
+<title>dojox.gfx: interactive analog clock</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverlight.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+
+dojo.require("dojox.gfx");
+dojo.require("dojo.date.locale");
+
+var current_time = new Date();
+
+var hour_hand = null;
+var minute_hand = null;
+var second_hand = null;
+
+var hour_shadow = null;
+var minute_shadow = null;
+var second_shadow = null;
+
+var center = {x: 385 / 2, y: 385 / 2};
+
+var hour_shadow_shift = {dx: 2, dy: 2};
+var minute_shadow_shift = {dx: 3, dy: 3};
+var second_shadow_shift = {dx: 4, dy: 4};
+
+var selected_hand = null;
+var container = null;
+var container_position = null;
+var text_time = null;
+var diff_time = new Date();
+
+placeHand = function(shape, angle, shift){
+ var move = {dx: center.x + (shift ? shift.dx : 0), dy: center.y + (shift ? shift.dy : 0)};
+ return shape.setTransform([move, dojox.gfx.matrix.rotateg(angle)]);
+};
+
+placeHourHand = function(h, m, s){
+ var angle = 30 * (h % 12 + m / 60 + s / 3600);
+ placeHand(hour_hand, angle);
+ placeHand(hour_shadow, angle, hour_shadow_shift);
+};
+
+placeMinuteHand = function(m, s){
+ var angle = 6 * (m + s / 60);
+ placeHand(minute_hand, angle);
+ placeHand(minute_shadow, angle, minute_shadow_shift);
+};
+
+placeSecondHand = function(s){
+ var angle = 6 * s;
+ placeHand(second_hand, angle);
+ placeHand(second_shadow, angle, second_shadow_shift);
+};
+
+reflectTime = function(time, hold_second_hand, hold_minute_hand, hold_hour_hand){
+ if(!time) time = current_time;
+ var h = time.getHours();
+ var m = time.getMinutes();
+ var s = time.getSeconds();
+ if(!hold_hour_hand) placeHourHand(h, m, s);
+ if(!hold_minute_hand) placeMinuteHand(m, s);
+ if(!hold_second_hand) placeSecondHand(s);
+ text_time.innerHTML = dojo.date.locale.format(
+ time, {selector: "time", timePattern: "h:mm:ss a"});
+};
+
+resetTime = function(){
+ current_time = new Date();
+ reflectTime();
+};
+
+tick = function(){
+ current_time.setSeconds(current_time.getSeconds() + 1);
+ reflectTime();
+};
+
+advanceTime = function(){
+ if(!selected_hand) {
+ tick();
+ }
+};
+
+normalizeAngle = function(angle){
+ if(angle > Math.PI) {
+ angle -= 2 * Math.PI;
+ } else if(angle < -Math.PI) {
+ angle += 2 * Math.PI;
+ }
+ return angle;
+};
+
+calculateAngle = function(x, y, handAngle){
+ try {
+ return normalizeAngle(Math.atan2(y - center.y, x - center.x) - handAngle);
+ } catch(e) {
+ // supress
+ }
+ return 0;
+};
+
+getSecondAngle = function(time){
+ if(!time) time = current_time;
+ return (6 * time.getSeconds() - 90) / 180 * Math.PI;
+};
+
+getMinuteAngle = function(time){
+ if(!time) time = current_time;
+ return (6 * (time.getMinutes() + time.getSeconds() / 60) - 90) / 180 * Math.PI;
+};
+
+getHourAngle = function(time){
+ if(!time) time = current_time;
+ return (30 * (time.getHours() + (time.getMinutes() + time.getSeconds() / 60) / 60) - 90) / 180 * Math.PI;
+};
+
+onMouseDown = function(evt){
+ selected_hand = evt.target;
+ diff_time.setTime(current_time.getTime());
+ dojo.stopEvent(evt);
+};
+
+onMouseMove = function(evt){
+ if(!selected_hand) return;
+ if(evt.target == second_hand.getEventSource() ||
+ evt.target == minute_hand.getEventSource() ||
+ evt.target == hour_hand.getEventSource()){
+ dojo.stopEvent(evt);
+ return;
+ }
+ if(dojox.gfx.equalSources(selected_hand, second_hand.getEventSource())){
+ var angle = calculateAngle(
+ evt.clientX - container_position.x,
+ evt.clientY - container_position.y,
+ normalizeAngle(getSecondAngle())
+ );
+ var diff = Math.round(angle / Math.PI * 180 / 6); // in whole seconds
+ current_time.setSeconds(current_time.getSeconds() + Math.round(diff));
+ reflectTime();
+ }else if(dojox.gfx.equalSources(selected_hand, minute_hand.getEventSource())){
+ var angle = calculateAngle(
+ evt.clientX - container_position.x,
+ evt.clientY - container_position.y,
+ normalizeAngle(getMinuteAngle(diff_time))
+ );
+ var diff = Math.round(angle / Math.PI * 180 / 6 * 60); // in whole seconds
+ diff_time.setTime(diff_time.getTime() + 1000 * diff);
+ reflectTime(diff_time, true);
+
+ }else if(dojox.gfx.equalSources(selected_hand, hour_hand.getEventSource())){
+ var angle = calculateAngle(
+ evt.clientX - container_position.x,
+ evt.clientY - container_position.y,
+ normalizeAngle(getHourAngle(diff_time))
+ );
+ var diff = Math.round(angle / Math.PI * 180 / 30 * 60 * 60); // in whole seconds
+ diff_time.setTime(diff_time.getTime() + 1000 * diff);
+ reflectTime(diff_time, true, true);
+ }else{
+ return;
+ }
+ dojo.stopEvent(evt);
+};
+
+onMouseUp = function(evt){
+ if(selected_hand && !dojox.gfx.equalSources(selected_hand, second_hand.getEventSource())){
+ current_time.setTime(diff_time.getTime());
+ reflectTime();
+ }
+ selected_hand = null;
+ dojo.stopEvent(evt);
+};
+
+makeShapes = function(){
+ // prerequisites
+ container = dojo.byId("gfx_holder");
+ container_position = dojo.coords(container, true);
+ text_time = dojo.byId("time");
+ var surface = dojox.gfx.createSurface(container, 385, 385);
+ surface.createImage({width: 385, height: 385, src: "images/clock_face_black.jpg"});
+
+ // hand shapes
+ var hour_hand_points = [{x: -7, y: 15}, {x: 7, y: 15}, {x: 0, y: -60}, {x: -7, y: 15}];
+ var minute_hand_points = [{x: -5, y: 15}, {x: 5, y: 15}, {x: 0, y: -100}, {x: -5, y: 15}];
+ var second_hand_points = [{x: -2, y: 15}, {x: 2, y: 15}, {x: 2, y: -105}, {x: 6, y: -105}, {x: 0, y: -116}, {x: -6, y: -105}, {x: -2, y: -105}, {x: -2, y: 15}];
+
+ // create shapes
+ hour_shadow = surface.createPolyline(hour_hand_points)
+ .setFill([0, 0, 0, 0.1])
+ ;
+ hour_hand = surface.createPolyline(hour_hand_points)
+ .setStroke({color: "black", width: 2})
+ .setFill("#889")
+ ;
+ minute_shadow = surface.createPolyline(minute_hand_points)
+ .setFill([0, 0, 0, 0.1])
+ ;
+ minute_hand = surface.createPolyline(minute_hand_points)
+ .setStroke({color: "black", width: 2})
+ .setFill("#ccd")
+ ;
+ second_shadow = surface.createPolyline(second_hand_points)
+ .setFill([0, 0, 0, 0.1])
+ ;
+ second_hand = surface.createPolyline(second_hand_points)
+ .setStroke({color: "#800", width: 1})
+ .setFill("#d00")
+ ;
+
+ // next 3 lines kill Silverlight because its nodes do not support CSS
+ //dojox.gfx._addClass(hour_hand .getEventSource(), "movable");
+ //dojox.gfx._addClass(minute_hand.getEventSource(), "movable");
+ //dojox.gfx._addClass(second_hand.getEventSource(), "movable");
+
+ surface.createCircle({r: 1}).setFill("black").setTransform({dx: 192.5, dy: 192.5});
+
+ // attach events
+ hour_hand .connect("onmousedown", onMouseDown);
+ minute_hand.connect("onmousedown", onMouseDown);
+ second_hand.connect("onmousedown", onMouseDown);
+ dojo.connect(container, "onmousemove", onMouseMove);
+ dojo.connect(container, "onmouseup", onMouseUp);
+ dojo.connect(dojo.byId("reset"), "onclick", resetTime);
+
+ // start the clock
+ resetTime();
+ window.setInterval(advanceTime, 1000);
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+<style type="text/css">
+.movable { cursor: hand; }
+</style>
+</head>
+<body>
+<h1>dojox.gfx: interactive analog clock</h1>
+<p>Grab hands and set your own time.</p>
+<p>Warning: Canvas renderer doesn't implement event handling.</p>
+<div id="gfx_holder" style="width: 385px; height: 385px;"></div>
+<p>Current time: <span id="time"></span>.</p>
+<p><button id="reset">Reset</button></p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/demos/creator.html b/includes/js/dojox/gfx/demos/creator.html
new file mode 100644
index 0000000..48ddf5b
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/creator.html
@@ -0,0 +1,123 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
+<head>
+<title>Create DojoX GFX JSON</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+ td.cell { padding: 1em 1em 0em 0em; }
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.utils");
+
+surface = null;
+grid_size = 500;
+grid_step = 50;
+
+init = function(){
+ // initialize graphics
+ var container = dojo.byId("gfx");
+ surface = dojox.gfx.createSurface(container, 500, 500);
+ // create a picture
+
+ // make a grid
+ var grid = surface.createGroup();
+ for(var i = 0; i <= grid_size; i += grid_step){
+ grid.createLine({x1: 0, x2: grid_size, y1: i, y2: i}).setStroke("black");
+ grid.createLine({y1: 0, y2: grid_size, x1: i, x2: i}).setStroke("black");
+ }
+
+ // make a checkerboard
+ var board = surface.createGroup(), gs2 = grid_step * 2;
+ for(var i = 0; i < grid_size; i += grid_step){
+ for(var j = 0; j < grid_size; j += grid_step){
+ if(i % gs2 == j % gs2) {
+ board.createRect({x: i, y: j, width: grid_step, height: grid_step}).setFill([255, 0, 0, 0.1]);
+ }
+ }
+ }
+
+ // draw test_transform shapes
+ var g1 = surface.createGroup();
+ var r1 = g1.createShape({type: "rect", x: 200, y: 200})
+ .setFill("green")
+ .setStroke({})
+ ;
+ var r2 = surface.createShape({type: "rect"}).setStroke({})
+ .setFill({type: "linear", to: {x: 50, y: 100},
+ colors: [{offset: 0, color: "green"}, {offset: 0.5, color: "red"}, {offset: 1, color: "blue"}] })
+ .setTransform({dx: 100, dy: 100})
+ ;
+ var r3 = surface.createRect().setStroke({})
+ .setFill({ type: "linear" })
+ ;
+ var r4 = g1.createShape({type: "rect"})
+ .setFill("blue")
+ .setTransform([dojox.gfx.matrix.rotategAt(-30, 350, 250), { dx: 300, dy: 200 }])
+ ;
+ var p1 = g1.createShape({type: "path"})
+ .setStroke({})
+ .moveTo(300, 100)
+ .lineTo(400, 200)
+ .lineTo(400, 300)
+ .lineTo(300, 400)
+ .curveTo(400, 300, 400, 200, 300, 100)
+ .setTransform({})
+ ;
+ var p2 = g1.createShape(p1.getShape())
+ .setStroke({color: "red", width: 2})
+ .setTransform({dx: 100})
+ ;
+ var p3 = g1.createShape({type: "path"})
+ .setStroke({color: "blue", width: 2})
+ .moveTo(300, 100)
+ .setAbsoluteMode(false)
+ .lineTo ( 100, 100)
+ .lineTo ( 0, 100)
+ .lineTo (-100, 100)
+ .curveTo( 100, -100, 100, -200, 0, -300)
+ //.setTransform(dojox.gfx.matrix.rotategAt(135, 250, 250))
+ .setTransform(dojox.gfx.matrix.rotategAt(180, 250, 250))
+ ;
+ g1.moveToFront();
+ g1.setTransform(dojox.gfx.matrix.rotategAt(-15, 250, 250));
+
+ // dump everything
+ dump();
+};
+
+dump = function(){
+ var objects = dojox.gfx.utils.serialize(surface);
+ // name top-level objects
+ for(var i = 0; i < objects.length; ++i){
+ objects[i].name = "shape" + i;
+ }
+ // format and show
+ dojo.byId("io").value = dojo.toJson(objects, dojo.byId("pprint").checked);
+};
+
+dojo.addOnLoad(init);
+</script>
+</head>
+<body>
+ <h1>Create DojoX GFX JSON</h1>
+ <p>This is a helper file, which serves as a template to generate static pictures.</p>
+ <table>
+ <tr>
+ <td align="left" valign="top" class="cell">
+ <div id="gfx" style="width: 500px; height: 500px; border: solid 1px black;">
+ </div>
+ </td>
+ </tr>
+ </table>
+ <p><textarea id="io" cols="80" rows="10" wrap="off"></textarea></p>
+ <p><button onclick="dump()">Dump!</button>
+ &nbsp;&nbsp;&nbsp;<input type="checkbox" id="pprint" checked="checked" />&nbsp;<label for="pprint">Pretty-print JSON</label></p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/demos/data/Lars.json b/includes/js/dojox/gfx/demos/data/Lars.json
new file mode 100644
index 0000000..320feb0
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/Lars.json
@@ -0,0 +1,1823 @@
+[
+ {
+ "name": "torso",
+ "children": [
+ {
+ "name": "leftArm",
+ "shape": {
+ "type": "path",
+ "path": "M156.007,292.674c2.737,1.779,5.563,3.322,8.752,3.947c7.098,1.39,19.25-5.666,23.136-11.699 c1.572-2.441,8.077-21.031,11.177-14.271c1.224,2.67-1.59,4-1.399,6.462c3.108-1.425,5.48-5.242,8.918-2.182 c0.672,4.019-4.472,4.343-3.918,7.669c1.376,0.218,5.394-1.595,6.285-0.535c1.707,2.027-2.933,3.561-4.072,4.018 c-1.852,0.741-4.294,1.233-5.988,2.369c-2.636,1.768-4.766,5.143-7.034,7.4c-11.657,11.604-26.183,10.553-40.646,5.515 c-4.713-1.642-17.399-4.472-18.655-9.427c-1.647-6.502,5.523-7.999,10.184-6.74C147.658,286.528,151.725,289.891,156.007,292.674z"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "leftArmThumb",
+ "shape": {
+ "type": "path",
+ "path": "M188.257,284.902c-1.932-1.391-3.314-4.206-3.506-6.494c-0.149-1.786,0.59-6.522,3.199-3.95c0.792,0.78,0.083,2.155,0.558,2.943 c0.885,1.47,1.071,0.493,2.748,1.002c1.406,0.426,3.827,2.05,4.251,3.499"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "rightArm",
+ "shape": {
+ "type": "path",
+ "path": "M57.05,283.306c-5.502,5.354-13.185,8.541-18.249,14.221c-4.303,4.827-7.721,11.575-11.138,17.112 c-6.752,10.939-10.794,26.076-19.912,35.185c-3.869,3.866-7.637,5.721-7.251,12.032c0.932,0.372,1.548,0.589,2.418,0.683 c0.605-2.746,2.569-4.199,5.362-3.799c-0.14,3.365-3.512,5.941-3.228,9.235c0.364,4.223,3.983,5.968,7.181,2.662 c2.61-2.699,0.192-7.848,3.338-10.179c5.535-4.103,2.889,2.998,4.13,5.514c5.19,10.519,8.634-1.859,7.35-7.996 c-2.336-11.159-3.003-15.126,3.267-24.416c6.358-9.419,12.194-18.708,19.399-27.588c1.116-1.375,2.08-2.728,3.333-4"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "shirt",
+ "children": [
+ {
+ "name": "tShirt",
+ "shape": {
+ "type": "path",
+ "path": "M96.509,268.264 c-2.301,0.323-4.69,0.205-6.945,0.72c-2.234,0.509-4.5,0.8-6.749,1.249c-4.369,0.872-8.206,3.265-12.3,5.024 c-3.259,1.401-6.644,2.571-9.763,4.26c-1.923,1.041-3.688,2.616-5.487,3.97c-1.543,1.16-3.495,2.11-4.854,3.562 c-2.205,2.354,0.896,7.408,1.854,9.873c0.92,2.368,2.149,4.82,2.749,7.29c0.228,0.937,0.235,2.058,0.875,2.873 c0.644,0.821,0.64,0.735,1.822,0.048c1.513-0.878,2.873-1.993,4.329-2.993c2.431-1.67,5.462-2.848,7.434-5.111 c-3.335,1.652-5.335,4.679-6.931,8.012c-1.398,2.92-4.482,35.854-5.389,38.947c-0.195,0.003-0.775,0.003-0.749,0.013 c20.561,0,41.123-0.07,61.684,0c2.1,0.007,3.607-0.497,5.529-1.252c0.715-0.281,2.257-0.356,2.807-0.745 c1.412-0.998-0.094-3.916-0.646-5.302c-1.425-3.579-2.111-37.767-4.726-40.543c1.842,0.057,4.127,1.311,5.937,1.95 c1.351,0.478,2.633,1.092,3.956,1.66c1.39,0.597,3.667,1.927,5.168,1.858c0.296-1.873,1.045-3.286,1.839-5.02 c0.943-2.061,1.155-4.214,1.528-6.415c0.351-2.07,0.898-3.787,1.939-5.635c0.531-0.942,1.356-1.73,1.693-2.768 c-0.443-0.402-1.043-0.907-1.603-1.125c-0.56-0.219-1.292-0.111-1.908-0.33c-1.237-0.438-2.44-1.089-3.669-1.576 c-3.773-1.499-7.519-2.983-11.319-4.466c-3.575-1.396-6.977-3.239-10.784-3.872c-1.735-0.289-3.467-0.529-5.073-0.906"
+ },
+ "fill": "#4459A5",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round"
+ }
+ },
+ {
+ "name": "shirtNeck",
+ "shape": {
+ "type": "path",
+ "path": "M99.759,268.889 c-0.984,0.152-1.746-0.549-2.75-0.5c-1.369,0.066-1.649,0.872-2.153,2c-1.037,2.325-2.442,4.974,0.064,6.946 c2.53,1.991,6.964,1.717,9.829,0.803c1.616-0.516,3.045-1.24,3.825-2.867c0.508-1.061,0.935-2.771,0.149-3.598 c-0.231-0.243-0.562-0.376-0.84-0.534"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round"
+ }
+ },
+ {
+ "name": "shirtLogo",
+ "children": [
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M104.864,296.92c-0.151-0.003,7.101,0.41,7.052,0.404c0.132,0.028-0.172,0.633-0.021,0.632 c-0.226,0.028-7.244-0.454-7.28-0.464C104.657,297.518,104.776,296.904,104.864,296.92z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M90.071,295.919c-0.199,0.004,6.792,0.43,6.79,0.446c0.153,0.005-0.031,0.663,0.012,0.665 c0.272,0.015-6.79-0.471-6.875-0.459C89.881,296.56,89.796,295.899,90.071,295.919z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M84.407,306.476c0.2-0.159,0.322-1.04,0.254,0.057 c-0.542-0.356-2.02,2.083-4.215,2.001c-1.887-1.706-4.559-3.384-4.302-7.092c0.652-2.599,3.082-4.084,5.213-3.942 c1.889,0.377,2.899,0.716,4,1.318c-0.497,0.957-0.175,0.866-0.459,0.703c0.456-2.398,0.598-5.75,0.312-7.855 c0.594-0.554,0.714,0.125,1.249,0.941c0.502-0.727,0.509-1.425,0.875-0.571c-0.207,1.328-0.809,7.186-0.711,10.174 c-0.126,2.797-0.375,4.354-0.051,4.985c-0.718,0.613-0.667,1.006-0.981,1.381c-0.72-1.33-1.056-0.132-1.339-0.157 C84.632,308.442,84.493,305.791,84.407,306.476z M81.186,307.176c2.403,0.206,3.734-2.164,3.841-4.222 c0.269-2.72-0.896-5.104-3.198-5.04c-1.972,0.437-3.46,2.188-3.331,4.638C78.171,306.265,79.847,306.961,81.186,307.176z"
+ },
+ "stroke": {
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M93.321,297.766c2.592,0.148,5.688,2.315,5.696,5.627 c-0.611,4.576-3.69,5.316-6.158,5.581c-2.68-0.76-5.708-1.872-5.413-6.472C88.086,299.394,90.653,297.875,93.321,297.766z M92.939,307.46c2.531,0.735,3.706-1.297,3.666-3.935c0.114-2.219-0.641-4.584-3.389-4.896c-2.29-0.552-3.366,2.188-3.661,4.688 C89.339,305.264,89.934,307.95,92.939,307.46z"
+ },
+ "stroke": {
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M99.688,303.916c0.03-1.511,0.055-4.731,0.022-4.646 c0.481-1.355,0.658-0.556,1.034-1.297c0.263,1.473,0.653,0.326,1.186,0.066c-0.386,2.517-0.513,3.347-0.574,4.949 c-0.068-0.47-0.128,2.28-0.238,2.188c-0.055,1.935-0.036,2.201-0.047,4.219c-0.079,0.914-0.28,2.412-1.126,3.831 c-0.61,1.212-1.73,1.146-3.24,1.651c0.073-0.945-0.065-1.242-0.096-1.822c0.098,0.138,0.213,0.604,0.225,0.398 c1.892,0.228,2.209-1.896,2.362-3.366c0.042,0.304,0.512-6.933,0.415-7.061C99.73,302.636,99.75,303.178,99.688,303.916z M100.978,295.564c0.717,0.14,1.11,0.61,1.099,1.156c0.052,0.552-0.595,0.993-1.286,1.015c-0.541-0.074-1.025-0.548-1.022-1.054 C99.813,296.084,100.292,295.643,100.978,295.564z"
+ },
+ "stroke": {
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M108.115,298.791c3.028-0.067,5.283,1.359,5.256,5.757 c-0.264,3.479-3.366,4.63-5.883,5.12c-2.429-0.034-5.619-2.241-5.16-5.811C102.322,300.085,105.715,298.845,108.115,298.791z M107.351,309.232c2.675-0.132,3.839-2.333,3.841-4.497c0.246-2.344-0.263-4.833-2.923-5.396 c-2.844,0.299-3.974,1.917-4.053,4.48C104.136,306.655,104.854,308.372,107.351,309.232z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "heads",
+ "children": [
+ {
+ "name": "head1",
+ "children": [
+ {
+ "name": "leftEart",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M201.557,195.474 c7.734-4.547,16.591-5.012,18.405,4.443c2.43,12.659-3.317,13.328-14.598,13.328"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M211.711,203.09 c0.523,0.004,0.946-0.208,1.27-0.635"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M211.076,197.377 c3.062,3.013,5.489,5.624,4.443,10.155"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ }
+ ]
+ },
+ {
+ "name": "bgHairTop",
+ "shape": {
+ "type": "path",
+ "path": "M54.384,199.306c-5.253-4.402-7.511-11.061-15.779-10.632c3.449-1.277,7.116-2.397,10.911-2.666 c-2.873-1.397-5.865-2.575-8.231-4.718c3.986-1.119,11.47-1.817,14.864,0.75c-5.183-2.758-8.397-7.816-13.062-10.598 c6.014-0.643,12.377,0.978,18.022,2.265c-2.547-4.486-6.682-10.83-10.523-14.297c5.033,1.052,10.647,4.518,15.062,7.177 c-1.614-4.176-5.634-8.406-7.859-12.513c10.312-1.125,12.522,4.919,19.7,9.932c-0.412-0.127-1.114-0.113-1.527,0.015 c0.875-7.261,3.058-12.8,8.258-18.566c6.771-7.507,17.812-9.131,24.095-15.381c-4.699,1.821-4.518,23.765-4.875,28.955"
+ },
+ "fill": "#FFF471",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "bgHairLeft",
+ "shape": {
+ "type": "path",
+ "path": "M92.384,243.972c-6.334,7.929-12.601,12.241-22.465,15.362c3.65-1.263,7.735-5.86,7.695-9.928 c-2.208,0.218-4.49,0.605-6.498,1.097c1.244-1.097,2.087-3.239,3.198-4.396c-5.77,0.001-12.131,1.133-18.396,1.23 c5.013-2.809,10.665-3.25,12.398-9.246c-3.59,0.313-7.233,1.606-11.033,1.097c1.731-2.022,3.953-3.995,5.049-6.447 c-3.781,0.056-6.665,3.098-10.547,2.465c0.962-2.863,3.187-5.208,4.531-7.766c-5.59-0.273-11.658,2.45-17.732,2.564 c5.494-2.857,8.967-7.819,12.3-12.718c5.233-7.693,10.625-9.96,20.349-9.981c11.059-0.024,15.558,6.714,20.984,16 c2.786,4.767,7.249,14.375,0.832,18"
+ },
+ "fill": "#FFF471",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "bgHair",
+ "shape": {
+ "type": "path",
+ "path": "M142.384,255.306c2.984,6.076,3.567,11.856,10.531,14.6c-0.134-3.114-0.094-6.664,1.619-9.033 c1.605,1.968,3.122,4.211,5.048,5.698c-0.29-1.769,0.412-4.024,0.233-5.828c3.445,0.26,4.979,3.965,8.468,4.479 c0.066-2.78,0.427-5.151,0.868-7.813c2.687,0.2,4.768,1.565,7.132,2.997c0.452-4.921-0.409-10.579-0.667-15.666 c-5.795-0.756-12.291,2.827-17.899,3.899c-4.414,0.844-14.136,0.524-15.333,6"
+ },
+ "fill": "#FFF471",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "neck",
+ "shape": {
+ "type": "path",
+ "path": "M106.989,254.499c-2.932,6.063-4.613,11.997-8.947,17.137c7.288,10.195,16.311-10.9,15.183-17.026 c-1.926-1.138-3.928-1.589-6.236-1.38"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "headShape",
+ "shape": {
+ "type": "path",
+ "path": "M210.941,207.665c-0.843,3.985-2.081,7.982-3.769,11.783c-3.374,7.604-8.543,14.427-16.052,18.899 c-2.94,2.13-5.983,4.167-9.109,6.085c-25.013,15.342-55.353,23.08-82.254,10.57c-3.433-1.557-6.785-3.431-10.053-5.66 c-1.821-1.184-3.592-2.46-5.308-3.832c-1.715-1.373-3.375-2.842-4.972-4.412c-2.352-2.148-4.576-4.425-6.631-6.814 c-6.168-7.169-10.823-15.358-12.87-24.185c-0.649-3.284-0.84-6.634-0.5-9.975c4.48-13.743,14.22-24.364,26.109-32.149 c2.973-1.946,6.079-3.715,9.271-5.309c30.581-15.027,69.581-10.027,95.851,12.209c2.564,2.254,4.988,4.651,7.244,7.178 c4.513,5.054,8.354,10.626,11.312,16.64C210.178,201.505,210.798,204.496,210.941,207.665z"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "rightEar",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M64.857,195.606 c-6.59-7.181-15.047-10.664-19.467,3.676c-1.235,4.007-1.87,14.468,1.29,17.786c4.223,4.435,13.591,0.529,19.055-0.015"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M52.407,196.743 c-1.702,3.613-1.257,7.505-1.27,11.424"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M51.772,209.437 c-3.39-4.661,0.922-5.769,5.078-6.347"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ }
+ ]
+ },
+ {
+ "name": "fgHair",
+ "shape": {
+ "type": "path",
+ "path": "M90.384,154.639c8.453-11.353,15.678-13.458,28.581-15.915c-1.382,3.376-3.89,7.352-5.179,11.16 c5.01-1.816,9.571-6.545,15.218-8.413c11.355-3.755,23.852-1.903,35.671-2.213c-3.004,3.712-4.912,7.88-2.026,11.447 c5.856-2.212,13.37-6.871,19.635-6.646c0.263,4.561-0.024,9.278,0.201,13.841c3.509-1.201,6.015-3.04,8.277-5.148 s3.761-4.049,4.942-5.2c1.063,2.408,2.134,5.334,2.24,8.494c-0.182,3.462-0.866,6.794-2.66,9.291 c3.663,0.65,6.098-2.021,8.35-4.479c-0.655,4.349-3.164,8.604-3.851,13.013c2.178-0.072,4.382,0.216,6.367-0.48 c-1.389,3.093-3.069,7.287-6.616,8.414c-4.475,1.423-4.354-0.992-7.315-4.332c-4.892-5.518-9.774-6.791-15.872-9.464 c-6.585-2.887-10.983-6.47-17.963-8.219c-8.994-2.255-19.864-3.867-28.093-5.196c2.466,1.967,1.138,5.594,0.659,8.625 c-2.729-0.645-4.41-3.813-6.301-5.158c0.953,3.195,0.983,6.953-2.134,8.491c-6.145-5.226-9.199-9.721-17.527-11.647 c1,1.83,1.728,4.208,1.396,6.402c-0.751,4.971-0.289,3.134-3.836,2.466c-5.192-0.977-9.953-3.677-15.815-4.496 c3.292,2.002,5.469,5.017,7.418,8.21c-2.651,0.404-6.238,0.257-8.382,1.671c2.456,0.38,3.44,2.166,3.197,4.714 c-7.45,0.386-13.623,0.731-19.915,5.434"
+ },
+ "fill": "#FFF471",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "eyes",
+ "children": [
+ {
+ "name": "eyes1",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M123.163,176.668 c-5.066,1.17-9.01,7.888-13.666,10.335c-4.238,2.227-8.648,6.636-7.009,12.332c1.971,6.848,12.042,3.991,16.261,1.165 c5.282-3.539,9.59-8.517,12.006-14.524c1.523-3.787,2.568-7.272-1.509-9.391c-2.905-1.51-8.174-1.386-11.417-0.583"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M182.545,179.865 c-3.533,0.169-4.854-1.166-8.408-0.001c-3,0.983-6.24,1.936-8.852,3.743c-3.938,2.725-7.46,5.555-4.73,13.592 c1.973,5.811,8.791,7.571,14.656,6.667c5.537-0.854,9.078-4.977,11.408-10.007c3.666-7.918,0.943-11.639-6.742-13.659"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M108.829,183.668c-1.308-1.03-4.557,0.011-5.6-1.733 c-1.056-1.765,1.735-5.409,2.984-6.192c5.684-3.562,15.946-0.39,19.95-6.742"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M163.877,167.198c2.369,1.282,6.539,0.307,9.408,0.815 c3.449,0.612,7.066,2.657,10.592,2.851"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M127.496,192.002c-4.917-2.12-9.188-1.708-8.608,4.942 c3.132,1.734,5.428-2.82,7.275-4.942"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M174.852,203.143c-0.293,0.12-0.307,0.577-0.943,0.282 c-1.605-3.188-0.404-6.507,2.676-8.192c2.15-1.176,5.67-1.759,7.471,0.359c0.199,0.234,0.412,0.521,0.514,0.813 c0.229,0.649-0.285,0.95-0.285,0.95s-3.988,6.009-3.285,1.934c0.438,1.743-5.537,5.743-2.287,1.653 c-1.955,2.583-2.525,1.977-3.859,2.868"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "eyes2",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M98.668,186.108c0.668-8.915,15.545-13.749,22.667-15"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M169.667,178.108 c5.307,3.436,16.928,5.632,19.668,12.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M105.334,197.775c8.085-4.283,17.059-2.8,25-6.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M164.001,198.775c4.656-0.417,9.664,1.805,14.334,2.017 c3.951,0.18,5.773,0.189,9,2.316"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M124.001,188.108c3.039-0.258,4.594,2.571,5.301,4.983 c-1.096,1.242-2.065,2.646-2.968,4.017"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M168.335,194.108c-1.77,2.293-4.869,3.271-6.299,5.91 c1.377,0.991,3.02,2.122,3.965,3.424"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "beard",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M96.05,213.639 c-0.366,0.21-0.783,0.389-1.167,0.5"
+ },
+ "fill": "#AFA8A5",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M102.55,211.972 c0.314-0.01,0.554-0.198,0.667-0.5"
+ },
+ "fill": "#AFA8A5",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M105.717,208.805 c0.164-0.109,0.336-0.224,0.5-0.333"
+ },
+ "fill": "#AFA8A5",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M111.05,207.972 c-0.651-1.81,0.859-2.262,2.333-1.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M117.717,209.805 c1.738,0,3.653,0.369,5.333,0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M132.717,214.472 c0.104-0.21,0.162-0.435,0.167-0.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M139.551,216.972 c0.215-0.175,0.465-0.426,0.666-0.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M144.551,213.305 c0.277-0.056,0.556-0.111,0.833-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M147.884,216.639 c0.195,0.045,0.369-0.013,0.5-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M148.384,214.139 c0.112-0.168,0.222-0.332,0.333-0.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M98.217,219.305c1.697-1.772,4.233-2.109,5.967-4.046c1.519-1.696,3.812-3.001,4.2-5.454"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M152.717,216.139 c0.611,0,1.223,0,1.834,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M160.384,217.472 c0.333,0,0.667,0,1,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M163.217,215.972 c0.321-0.042,0.658-0.175,0.834-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M164.217,218.805 c0.167,0,0.333,0,0.5,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M168.384,217.972 c0.056-0.056,0.111-0.111,0.167-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M169.884,225.805 c0.491-0.397,0.882-0.926,1.167-1.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M172.717,221.972 c0.056,0,0.111,0,0.167,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M171.717,229.805 c0.334,0.075,0.659,0.025,0.834-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M190.051,227.805 c0.163-0.242,0.398-0.423,0.666-0.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M197.384,221.472 c0.258-0.007,0.485-0.125,0.667-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M199.384,214.972 c-0.04-0.333,0.075-0.609,0.333-0.833"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M117.884,257.305 c0.056,0,0.111,0,0.167,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M142.717,252.472 c0.358,0.069,0.71,0.016,1-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M137.884,256.472 c0.277,0,0.556,0,0.833,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M160.884,252.972 c0.366-0.138,0.765-0.402,1-0.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M171.384,250.139 c0.235-0.263,0.475-0.561,0.667-0.834"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M89.384,243.972 c0.537,0.378,1.329,0.876,1.833,1.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M79.05,225.472 c0.087,0.272,0.143,0.55,0.167,0.833"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M73.884,222.639 c0,0.167,0,0.333,0,0.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M72.55,219.805c0.466-0.325,0.875-0.797,1.167-1.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M71.717,211.972c0.422-0.553,0.776-1.305,1-2"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M78.55,214.472c0-0.111,0-0.222,0-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M79.384,218.805c-0.001-0.137,0.055-0.248,0.167-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M80.217,221.139c0.111,0,0.222,0,0.333,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M75.55,226.472c0.103-0.5,0.156-0.977,0.167-1.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M78.55,230.139c0.111,0,0.222,0,0.333,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M83.384,227.639c0.118-0.059,0.215-0.107,0.333-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M81.55,237.139c0.056,0,0.111,0,0.167,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M86.217,233.805c0.056,0,0.111,0,0.167,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M87.884,230.472c0.595-0.181,1.219-0.527,1.833-0.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M88.717,222.139 c-0.929,2.359-1.615,4.865-2.667,7.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M89.05,216.139 c0.784-0.736,1.709-1.565,2.833-1.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M94.217,210.139 c1.599-0.089,3.199-0.167,4.833-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M94.884,224.639 c0.052-0.588-0.004-1.155-0.167-1.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M92.384,228.305 c0.585-0.062,1.244-0.132,1.667-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M88.717,240.139 c0.111,0,0.222,0,0.333,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M95.884,243.305 c0.526,0.1,1.017-0.015,1.333-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M98.55,248.305 c0.069-0.24,0.265-0.926,0.333-1.166"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M96.55,249.805 c0.125,0.014,0.18-0.042,0.167-0.166"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M104.55,250.139 c0.01-0.238,0.126-0.428,0.333-0.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M106.884,251.972 c0.195,0.045,0.37-0.013,0.5-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M113.884,254.805 c0.758-0.586,1.595-1.171,2.382-1.774c0.072,0.376,0.418,0.685,0.48,1.079c0.833,0.265,1.624-0.021,1.638-0.971"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M122.217,254.639 c0.063-0.165,0.179-0.288,0.333-0.334"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M125.884,255.805 c1.13-0.745,2.783-0.962,3.667-2"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M132.217,255.972 c0.638-0.492,1.104-1.173,1.141-1.975c-1.11,0.062-1.449-0.888-1.475-1.858"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M129.717,249.305 c-0.045,0.154-0.168,0.271-0.333,0.334"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M136.551,252.305 c0.222,0,0.444,0,0.666,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M110.217,251.305 c0.056-0.056,0.111-0.11,0.167-0.166"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M140.717,251.805 c0.111,0,0.223,0,0.334,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M150.051,249.472 c0.111,0,0.222,0,0.333,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M143.217,255.472 c1.022-0.313,1.724-1.175,2.646-1.654c0.203,0.321,0.44,0.626,0.521,0.987"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M152.217,253.472 c0.165-0.063,0.288-0.179,0.334-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M155.051,254.639 c0.222,0,0.444,0,0.666,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M157.717,256.472 c0.326-0.027,0.546-0.073,0.834-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M163.217,252.639 c0.552-0.891,2.082-1.512,2.341-2.334c0.37-1.177-1.156-3.069-1.007-4.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M167.384,235.972 c0.118-0.54,0.353-1.064,0.667-1.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M170.717,242.805 c0-0.333,0-0.667,0-1"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M170.217,236.972 c0-0.333,0-0.667,0-1"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M179.051,235.805 c0.378-0.101,0.738-0.35,1-0.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M185.051,232.805 c0.379-0.319,0.656-0.702,0.833-1.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M188.051,231.139 c0.063-0.39,0.178-0.792,0.333-1.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M197.884,223.305 c-0.166,0.277-0.334,0.556-0.5,0.833"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ }
+ ]
+ },
+ {
+ "name": "mouths",
+ "children": [
+ {
+ "name": "mouth1",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M177.122,216.821c-0.515,2.282-5.213,3.21-7.433,3.854 c-3.254,0.945-6.596,1.345-9.895,1.851c-3.26,0.5-6.665,0.671-10.107,0.671c-3.596,0-6.645,0.559-10.107,0.671 c-3.105,0.1-6.898-0.474-9.694-1.3c-3.527-1.043-6.672-1.666-10.096-3.062c-2.823-1.152-5.746-1.876-8.462-3.143 c-2.594-1.209-6.084-1.994-8.221-3.552c-1.068,1.834-5.867,3.748-8.1,4.546c-2.444,0.874-8.881,2.725-7.817,5.512 c0.457,1.195,1.948,2.273,2.63,3.385c0.774,1.261,1.139,2.601,2.057,3.859c1.83,2.5,4.506,4.773,6,7.34 c1.308,2.249,2.096,4.74,4.01,6.67c2.214,2.233,5.792,2.634,9.231,2.399c7.028-0.479,13.982-2.129,20.481-3.983 c3.295-0.941,6.699-1.536,10.087-2.686c3.272-1.111,6.641-3,9.402-4.777c5.248-3.377,10.278-6.409,14.283-10.705 c1.479-1.587,3.429-2.503,5.15-3.859"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M135.25,241.319 c0.723-4.757-10.487-8.47-14.898-9.526c-3.09-0.74-6.68-1.17-9.858-1.712c-2.758-0.47-6.865-0.836-9.437,0.369 c-1.385,0.649-2.843,1.724-4.141,2.513c2.156,3.964,4.728,8.861,9.468,11.506c3.229,1.801,5.511,0.777,8.859,0.373 c3.045-0.369,6.046-0.703,9.029-1.72c3.479-1.186,7.228-2.385,10.978-2.475"
+ },
+ "fill": "#FFC0C0",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M148.656,225.547c1.267,0.697,1.301,2.838,0.671,3.9 c-0.702,1.182-2.063,1.4-3.306,2.01c-2.271,1.116-4.581,2.624-7.482,2.638c-4.619,0.023-2.143-4.067-0.253-5.869 c2.405-2.292,5.057-2.72,8.72-2.512c0.588,0.034,1.095,0.041,1.65,0.168"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M130.299,223.365 c2.687,0.437,5.619,4.384,3.727,6.422c-1.234,1.33-7.94,1.391-9.915,1.296c-4.896-0.233-2.502-2.445-0.613-4.525 c1.604-1.767,5.088-3.249,7.833-3.36"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M113.178,217.157 c2.56,0.958,4.922,5.057,5.352,7.215c0.377,1.885-0.324,2.106-2.526,2.643c-1.366,0.333-3.636,0.723-5.105,0.385 c-2.506-0.577-5.883-5.051-4.909-7.223c1.03-2.298,5.944-2.923,8.427-2.852"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M99.359,217.661 c2.038,0.432,4.015,4.279,2.468,5.625c-1.083,0.943-5.221,1.795-6.799,1.589c-4.032-0.526-2.265-4.102-0.866-5.872 c0.706-0.894,1.049-1.976,2.514-2.186c1.627-0.233,2.501,0.99,3.921,1.346"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M181.815,222.895c-3.101-2.75-4.764-8.777-9.282-10.403"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "mouth2",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M87.57,221.951c5.563-1.759,11.066-1.32,16.694-1.782c2.93-0.24,5.228-1.14,8.309-0.927c3.142,0.217,6.085-0.235,9.289,0.176 c7.136,0.914,13.96,0.598,21.112,1.506c3.654,0.464,7.218,0.609,10.81,0.869c4.017,0.291,7.646,1.582,11.433,2.623 c2.948,0.812,6.347,1.618,9.011,2.99c2.521,1.298,6.354,2.856,8.3,4.72c-2.775,0.027-5.601,2.603-8.021,3.769 c-2.93,1.412-5.741,2.949-8.656,4.432c-5.599,2.849-11.885,5.468-18.104,6.53c-6.793,1.161-13.195,2.107-20.067,2.197 c-7.699,0.102-14.313-4.705-20.735-8.396c-2.071-1.19-4.69-2.182-6.504-3.666c-1.792-1.466-3.469-3.386-5.154-4.984 c-2.703-2.564-7.519-5.649-8.13-9.438"
+ },
+ "stroke": {
+ "color": "#000000",
+ "width": "3",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M87.785,228.193 c-5.907-3.235-0.344-9.531,3.971-11.424"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M184.679,227.228c-1.534,2.583-2.548,5.334-4.025,7.889"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M106.862,219.528 c-3.071-0.74-5.608,2.166-6.318,4.738c-0.379,1.375-0.494,2.55,0.748,3.337c1.519,0.962,2.905-0.052,4.418-0.332 c2.518-0.467,7.293,0.053,6.461-4.248c-0.568-2.938-3.743-3.682-6.338-3.335c-0.451,0.06-0.758,0.212-1.205,0.229"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M119.764,218.479 c-2.648,1.243-4.657,3.518-5.346,6.377c-0.866,3.594,3.9,3.711,6.356,2.865c2.64-0.91,4.77-3.351,3.299-6.133 c-1.01-1.91-3.979-2.548-6.026-2.823"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M130.388,219.492 c-1.753,1.382-4.069,4.525-4.835,6.61c-1.159,3.156,2.296,3.371,4.868,3.348c3.061-0.028,6.6-1.148,5.022-4.78 c-1.168-2.691-2.552-4.85-5.551-5.241"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M142.954,221.087 c-1.502,0.337-5.418,3.249-5.638,4.997c-0.292,2.311,4.856,4.536,6.854,4.234c2.503-0.377,4.384-3.175,3.167-5.65 c-0.92-1.873-3.36-2.252-4.508-3.932"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M155.354,222.663 c-2.039,0.426-4.212,2.287-4.766,4.444c-0.723,2.821,3.225,3.383,5.458,3.331c2.541-0.059,5.126-1.752,3.249-4.32 c-1.394-1.908-3.707-3.189-5.304-4.636"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M168.367,237.924 c-1.554-1.217-3.302-2.557-5.203-2.976c-2.973-0.654-3.537,2.131-3.377,4.406c0.205,2.913,1.032,3.883,3.901,2.344 c1.988-1.066,4.272-1.997,4.599-4.456"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M151.524,246.202 c-1.912-0.166-4.003-4.491-2.91-6.25c0.771-1.239,5.456-1.688,6.858-1.292c0.271,0.917,0.979,1.841,0.829,2.771 c-0.088,0.54-0.994,1.645-1.296,2.188c-1.08,1.951-2.133,1.866-3.998,2.684"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M145.911,241.457 c-0.209,1.649-0.215,2.702-1.528,3.801c-0.885,0.739-1.773,1.19-2.54,2.1c-0.786,0.933-1.226,2.38-2.792,1.812 c-1.042-0.377-1.959-2.318-2.138-3.311c-0.299-1.676-1.003-5.228,0.783-6.158c1.155-0.603,7.067-0.18,7.43,1.32"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M133.12,238.991 c-1.495-0.087-2.253-1.33-3.918-0.964c-1.42,0.311-2.489,1.354-2.54,2.836c-0.052,1.527,0.99,5.581,1.852,6.956 c2.363,3.771,4.329-1.535,5.516-3.159c1.117-1.526,2.643-2.053,2.271-3.958c-0.318-1.632-1.118-2.047-2.766-2.329 c-0.382-0.065-0.773-0.095-1.158-0.147"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M116.853,237.429 c-1.049,2.211-0.173,5.147,0.047,7.566c0.357,3.929,3.827,2.028,5.831,0.067c1.575-1.541,4.599-4.86,2.209-6.484 c-1.881-1.279-5.727-2.458-7.756-1.107"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M107.455,233.38 c-0.813,2.487-1.704,5.049,0.073,7.364c1.91,2.486,4.009,1.229,5.537-0.939c1.056-1.5,3.316-4.481,1.563-6.017 c-1.347-1.179-6.468-1.518-7.854-0.325"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "mouth3",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M99.05,218.972 c1.691-0.875,3.313-2.39,4.833-3.537c1.231-0.928,2.782-1.671,3.5-3.072c1.846,3.486,7.661,4.669,11.003,6.067 c3.553,1.486,7.174,3.066,10.784,4.166c4.271,1.301,9.277,1.67,13.721,2.343c4.155,0.629,9.979,1.365,14.162,0.496 c1.181-0.245,2.343-1.024,3.462-1.446c0.162,1.905-3.637,3.023-4.933,3.487c-2.435,0.871-4.18,2.541-6.362,3.871 c-1.623,0.989-2.974,1.669-4.755,2.117c-1.77,0.445-3.353,0.806-4.825,1.878c-5.915,4.311-15.264,3.247-22.424,3.13 c-5.384-0.088-6.719-5.372-9.337-9c-1.437-1.991-2.843-3.854-3.796-6.138c-0.871-2.086-1.119-4.582-2.033-6.528"
+ },
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M107.217,227.972 c1.182-2.033,4.375-2.176,6.5-1.963c2.879,0.289,4.124,1.217,6.168,3.167c1.834,1.749,5.906,5.509,5.64,8.271 c-2.808,0.89-7.847,0.402-10.346-1.104c-1.334-0.804-1.151-2.256-2.246-3.588c-0.712-0.866-1.836-2.673-2.855-3.311 c-0.209-0.94-2.106-1.499-3.028-1.805"
+ },
+ "fill": "#F4BDBD",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "personalProps",
+ "children": [
+ {
+ "name": "hat",
+ "children": [
+ {
+ "children": [
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M88.374,173.144c0.474-0.074,16.606,2.725,18.01,5.879 c1.145,2.572,28.184,4.568,28.184,4.568l35.971-5.618l5.025,1.132l7.211,0.315l9.295,0.851l10.188,3.248l5.75,2.935 l1.615-1.832l-0.264-5.27l-3.967-7.087c0,0-22.045-13.031-23.273-13.703c-1.229-0.669-4.941-2.294-6.484-4.542 c-8.584-12.528-8.404-18.05-3.371-6.461c0,0,2.662-7.592,2.52-8.575c-0.143-0.982,0.355-5.031,0.355-5.031l2.396-6.832 c0,0-1.379-5.341-2.738-7.19c-1.357-1.844-15.793-4.078-18.162-4.011c-24.933,0.706-3.783,0.071-25.567,0.724 c-24.317,0.728-0.882-2.591-24.068,3.551c-24.228,6.418-5.35-1.298-23.187,6.142c-18.301,7.633-16.67,7.186-16.704,10.685 c-0.034,3.499-3.057-4.884-0.034,3.499c3.023,8.381,3.037-3.871,3.023,8.381c-0.015,12.252,6.696,4.557,1.678,12.373 c-5.017,7.813-3.831,7.91-0.179,8.543c17.017,2.953,4.157,4.378,17.427,3.175"
+ },
+ "fill": "#FF0000",
+ "stroke": {
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M156.605,114.92l-13.936,0.381l-11.633,0.343c-10.646,0.319-11.973-0.155-12.021-0.175l-0.599-0.238 l-0.577,0.514l0.049-0.047c-0.118,0.09-1.43,0.957-11.145,3.53c-9.989,2.646-12.812,2.931-13.421,2.704 c-0.822-0.306-0.821-0.306-7.791,2.604l-2.104,0.878c-16.037,6.689-17.342,7.324-17.342,10.316c0,0.019,0.001,0.041,0.001,0.06 c-0.224-0.108-0.459-0.199-0.787-0.04c-0.357,0.173-0.565,0.275-0.565,0.672c0,0.557,0.411,1.697,1.399,4.438 c0.924,2.561,1.71,3.671,2.714,3.833c0.083,0.014,0.164,0.02,0.241,0.02c0.007,0.584,0.01,1.339,0.01,2.313 c0,0.561-0.001,1.902-0.001,1.916c0,6.908,2.176,8.105,3.347,8.749c0,0,0.075,0.045,0.151,0.09 c-0.095,0.332-0.47,1.1-1.661,2.955c-2.509,3.908-3.516,5.931-3.516,7.303c0,0.358,0.068,0.671,0.196,0.962 c0.544,1.237,1.926,1.477,3.677,1.78l0.135,0.023c8.138,1.412,9.14,2.422,9.568,2.854c0.923,0.931,1.511,0.928,7.224,0.413 c0.06,0.014,0.102,0.068,0.165,0.071c2.167,0.105,16.131,3.138,17.087,5.288c1.147,2.578,16.416,4.228,29.023,5.159 l0.115,0.009c0,0,35.523-5.548,35.896-5.606c0.345,0.078,4.927,1.11,4.927,1.11l7.3,0.319c0,0,8.927,0.818,9.139,0.837 c0.202,0.064,9.854,3.142,10.006,3.19c0.143,0.073,6.368,3.251,6.368,3.251l2.398-2.719l-0.296-5.911l-4.213-7.526 l-0.232-0.137c-0.9-0.532-22.073-13.047-23.303-13.72c-0.001,0-0.735-0.38-0.735-0.38c-1.48-0.752-4.238-2.151-5.404-3.85 c-1.357-1.982-2.451-3.729-3.355-5.268c0.022-0.064,0.104-0.296,0.104-0.296c1.193-3.402,2.576-7.619,2.576-8.885 c0-0.063-0.004-0.118-0.011-0.165c-0.012-0.083-0.017-0.204-0.017-0.356c0-0.909,0.194-2.911,0.363-4.307 c0.072-0.205,2.46-7.013,2.46-7.013l-0.076-0.294c-0.146-0.566-1.468-5.584-2.9-7.532 C173.721,116.784,158.242,114.874,156.605,114.92z M131.097,117.643l11.614-0.342l13.951-0.382 c2.575-0.073,16.104,2.238,17.336,3.614c0.956,1.3,2.058,4.938,2.49,6.549c-0.188,0.536-2.33,6.642-2.33,6.642l-0.013,0.107 c-0.073,0.592-0.387,3.224-0.387,4.658c0,0.258,0.011,0.477,0.034,0.639c-0.006,0.493-0.768,3.026-1.659,5.709 c-2.14-4.566-2.792-4.606-3.242-4.629l-0.62-0.031l-0.354,0.571c-0.069,0.124-0.102,0.29-0.102,0.492 c0,2.273,4.134,9.172,6.993,13.346c1.456,2.12,4.509,3.669,6.149,4.501l0.682,0.353c1.138,0.622,20.813,12.25,23.011,13.549 c0.239,0.427,3.513,6.275,3.721,6.647c0.02,0.393,0.199,3.971,0.231,4.629c-0.23,0.262-0.472,0.535-0.832,0.944 c-1.07-0.546-5.132-2.619-5.132-2.619l-10.369-3.306l-9.404-0.86c0,0-6.995-0.307-7.169-0.315 c-0.168-0.038-5.124-1.155-5.124-1.155s-35.814,5.594-36.044,5.63c-12.419-0.922-25.993-2.687-27.285-4.058 c-1.366-3.097-13.245-5.574-17.517-6.211c-0.203-0.212-0.479-0.346-0.793-0.318c-3.083,0.28-5.996,0.544-6.4,0.369 c0-0.003-0.12-0.117-0.12-0.117c-0.703-0.708-1.879-1.895-10.646-3.416l-0.135-0.023c-0.827-0.143-2.075-0.359-2.188-0.614 c-0.021-0.048-0.033-0.111-0.033-0.193c0-0.592,0.632-2.179,3.205-6.187c1.488-2.318,2.024-3.388,2.024-4.188 c0-0.15-0.019-0.291-0.054-0.428c-0.181-0.712-0.758-1.03-1.179-1.261c-0.865-0.476-2.311-1.271-2.311-6.993 c0-0.014,0.001-1.098,0.001-1.56c0-4.969-0.065-4.992-0.833-5.258c-0.424-0.146-0.816,0.001-1.178,0.377 c-0.208-0.289-0.558-0.898-1.073-2.324c-0.205-0.568-0.385-1.068-0.542-1.506c0.587-0.423,0.632-1.277,0.636-1.644 l-0.014-0.825c-0.004-0.119-0.007-0.231-0.007-0.338c0-1.702,0.899-2.264,16.109-8.608l2.105-0.878 c4.165-1.739,5.948-2.482,6.375-2.562c0.817,0.296,2.292,0.597,14.579-2.658c8.169-2.164,10.697-3.187,11.58-3.704 C120.451,117.773,124.529,117.84,131.097,117.643z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M155.146,147.929c4.879-9.398-5.344-20.199-12.65-21.176 c-12.05-1.61-13.404,10.426-13.684,21.258c3.73,2.016,8.915,3.425,11.721,6.534"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M133.446,127.979c-4.599,3.921-5.426,11.933-5.635,20.006l-0.017,0.654l4.415,2.067 c2.849,1.244,5.793,2.529,7.581,4.509c0.371,0.41,1.004,0.442,1.412,0.072c0.219-0.197,0.33-0.469,0.33-0.743 c0-0.239-0.084-0.479-0.258-0.67c-2.076-2.299-5.222-3.673-8.266-5.001c0,0-2.377-1.112-3.174-1.486 c0.223-7.385,1.021-14.572,4.909-17.887c1.892-1.614,4.386-2.189,7.621-1.757c4.143,0.554,9.086,4.472,11.5,9.113 c1.348,2.591,2.51,6.535,0.395,10.611c-0.254,0.49-0.064,1.093,0.426,1.348c0.49,0.254,1.094,0.063,1.35-0.427 c1.959-3.775,1.818-8.199-0.395-12.456c-2.732-5.251-8.203-9.53-13.012-10.172C138.853,125.257,135.763,126,133.446,127.979z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M154.077,146.278c-2.156,1.18-4.24,2.619-6.256,4.01c-3.635,2.509-7.068,4.878-10.941,5.924 c-2.991,0.808-6.055,1.058-9.3,1.324c-3.222,0.263-6.553,0.536-9.783,1.406c-2.027,0.546-4.117,1.397-6.137,2.221 c-3.491,1.423-7.102,2.895-10.528,2.866c-0.552-0.005-1.004,0.439-1.009,0.991s0.439,1.004,0.991,1.009 c3.828,0.033,7.627-1.516,11.301-3.014c2.054-0.837,3.994-1.628,5.902-2.142c3.054-0.823,6.292-1.088,9.425-1.344 c3.191-0.261,6.492-0.531,9.659-1.386c4.205-1.135,7.941-3.714,11.557-6.208c1.973-1.362,4.014-2.771,6.08-3.901 c0.484-0.265,0.662-0.873,0.396-1.357S154.562,146.013,154.077,146.278z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M156.458,153.549c-2.619,0.064-5.709,0.812-8.98,1.604c-4.279,1.035-8.701,2.104-11.902,1.536 c-0.543-0.096-1.063,0.267-1.159,0.81c-0.097,0.544,0.267,1.063,0.81,1.16c3.613,0.641,8.24-0.481,12.72-1.562 c3.166-0.766,6.154-1.489,8.561-1.548c5.664-0.141,7.961,0.698,13.508,2.724c0.518,0.189,1.094-0.077,1.281-0.596 c0.189-0.519-0.076-1.091-0.596-1.282C165.069,154.337,162.501,153.399,156.458,153.549z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "textSurface",
+ "children": [
+ {
+ "name": "spokenBubble",
+ "children": [
+ {
+ "name": "textContainer",
+ "shape": {
+ "type": "path",
+ "path": "M225.719,45.306c0-6.627,5.373-12,12-12h181.333 c6.627,0,12,5.373,12,12V150.64c0,6.627-5.373,12-12,12H237.719c-6.627,0-12-5.373-12-12V45.306z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "textArrowBelow",
+ "shape": {
+ "type": "path",
+ "path": "M249.052,160.639 c-0.775,14.251-1.676,18.525-9.1,30.565c9.705-0.79,21.952-21.605,25.1-30.045"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "thoughtBubble",
+ "children": [
+ {
+ "name": "textContainer_1_",
+ "shape": {
+ "type": "path",
+ "path": "M202.698,21.089 c19.686-26.45,59.686-24.45,79.747-0.084c2.697,1.349,5.571,1.709,7.472,0.781c15.28-13.888,33.272-14.043,49.893-7.839 c2.771,1.034,5.478,2.219,8.031,3.421c28.543-21.729,75.543-10.729,83.166,27.658c0,0-1.324,3.889,1.165,6.603 c18.212,11.011,26.212,32.011,22.212,53.011c-1,5.333-3.223,9.667-6.037,13.52c-2.814,3.854-1.381,0-2.613-0.591 c-1.35-0.929-3.35-0.929-4.35-1.929c16,7,27,22,30,39c2,21-8,41-27,50c-16,7.5-32.5,5.5-45.745-2.556 c-2.532-1.384-4.229-1.856-5.336-1.551c-1.919,0.107-3.919,2.107-5.919,2.107c4-1,6-5,10-6c-15,11-35,12-52,3c-13-7-20-20-24-34 c1,5,3,9,3.299,13.505c-0.397,0.708-3.423,2.219-6.655,3.466c-22.627,8.729-49.423,1.729-65.241-19.971 c-3.453,0-6.263,0.589-8.723,0.879c-17.3,3.2-32.381-7.709-40.771-22.689c-1.678-2.996-3.089-6.153-4.195-9.396 c-15.714-7.795-29.714-18.795-33.714-37.795c-5-25,11-45,29.842-57.667c0.719-2.335,1.697-4.636,3.006-6.896 C201.159,23.306,202.698,21.089,202.698,21.089z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M269.719,186.306c0,4.602-4.179,8.333-9.333,8.333c-5.155,0-9.334-3.731-9.334-8.333 c0-4.603,4.179-8.333,9.334-8.333C265.54,177.973,269.719,181.704,269.719,186.306z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ }
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M269.719,186.306c0,4.602-4.179,8.333-9.333,8.333c-5.155,0-9.334-3.731-9.334-8.333 c0-4.603,4.179-8.333,9.334-8.333C265.54,177.973,269.719,181.704,269.719,186.306z"
+ },
+ "fill": "none",
+ "stroke": {
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M268.225,186.165c-0.564,8.736-13.982,9.286-15.633,0.853 c-1.785-9.125,15.017-10.254,15.649-0.451c0.125,1.929,3.078,1.388,2.955-0.521c-0.814-12.597-20.828-12.412-21.639,0.119 c-0.827,12.813,20.831,13.028,21.655,0.283C271.337,184.518,268.35,184.235,268.225,186.165z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M260.386,188.306c0,3.498-2.985,6.333-6.667,6.333 s-6.667-2.835-6.667-6.333c0-3.498,2.985-6.333,6.667-6.333S260.386,184.808,260.386,188.306z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M238.386,196.973c0,1.289-1.045,2.333-2.334,2.333 c-1.288,0-2.333-1.045-2.333-2.333s1.045-2.333,2.333-2.333C237.341,194.639,238.386,195.684,238.386,196.973z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M285.719,179.973c0,4.602-4.253,8.333-9.5,8.333 s-9.5-3.731-9.5-8.333c0-4.603,4.253-8.333,9.5-8.333S285.719,175.371,285.719,179.973z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "yellBubble",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M251.156,176.051 l40.228-15.992"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M280.932,149.385 l-40.667,36.42"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "textContainer_2_",
+ "shape": {
+ "type": "path",
+ "path": "M217.778,34.643 c8.609,6.684,9.952,3.684,7.987-5.785c6.308,5.125,9.308,3.782,10.188-4.309c2.433,8.091,5.266,8.091,9.12-1.703 c6.063,9.793,13.146,9.793,24.043,3.878c6.103,5.915,16.02,5.915,20.094-4.64c17.178,10.555,28.511,10.555,45.233-5.505 c5.941,16.06,17.273,16.06,18.835,1.458c19.688,14.603,29.605,14.603,46.749-17.802c-0.144,32.405,6.939,32.405,29.26,16.182 c-12.403,16.223-9.57,16.223,4.813,6.576c-11.07,9.646-8.07,10.99,4.333,9.089c-8.061,6.244-6.717,9.244,2.533,11.068 c-9.25,1.489-9.25,5.703-0.315,13.07c-8.935,6.115-8.935,15.385,7.513,10.932c-16.447,24.677-16.447,35.631,14.938,36.553 c-31.385,19.303-31.385,28.571-4.39,40.526c-26.995,1.528-26.995,5.741-5.942,17.857c-21.053-8.801-22.396-5.802-9.526,11.916 c-17.213-13.374-20.213-12.03-12.048,8.029c-11.479-20.06-14.312-20.06-10.553,3.532c-13.676-23.591-20.759-23.591-29.814-2.664 c-7.944-20.927-17.861-20.927-27.072,12.467c-12.039-33.395-23.373-33.395-23.148-1.581 c-22.89-31.814-34.224-31.814-61.517-8.479c6.042-23.335-3.874-23.335-11.9-9.703c-8.975-13.632-16.058-13.632-23.926,4.361 c-2.049-17.993-4.882-17.993-10.51-1.486c2.314-16.508-0.686-17.851-12.385-5.019c7.356-17.175,6.013-20.176-10.27-7.879 c16.283-15.61,16.283-19.824-9.255-12.972c25.538-20.334,25.538-29.603,1.919-46.578c23.619-3.249,23.619-14.204-0.313-25.522 c23.933-8.905,23.933-18.175,7.798-37.429C226.385,48.854,226.385,44.64,217.778,34.643z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+] \ No newline at end of file
diff --git a/includes/js/dojox/gfx/demos/data/Lars.svg b/includes/js/dojox/gfx/demos/data/Lars.svg
new file mode 100644
index 0000000..7295501
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/Lars.svg
@@ -0,0 +1,531 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/">
+ <g id="torso" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#000000000000">
+ <path id="leftArm" i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M156.007,292.674c2.737,1.779,5.563,3.322,8.752,3.947c7.098,1.39,19.25-5.666,23.136-11.699
+ c1.572-2.441,8.077-21.031,11.177-14.271c1.224,2.67-1.59,4-1.399,6.462c3.108-1.425,5.48-5.242,8.918-2.182
+ c0.672,4.019-4.472,4.343-3.918,7.669c1.376,0.218,5.394-1.595,6.285-0.535c1.707,2.027-2.933,3.561-4.072,4.018
+ c-1.852,0.741-4.294,1.233-5.988,2.369c-2.636,1.768-4.766,5.143-7.034,7.4c-11.657,11.604-26.183,10.553-40.646,5.515
+ c-4.713-1.642-17.399-4.472-18.655-9.427c-1.647-6.502,5.523-7.999,10.184-6.74C147.658,286.528,151.725,289.891,156.007,292.674z
+ "/>
+ <path id="leftArmThumb" i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M188.257,284.902c-1.932-1.391-3.314-4.206-3.506-6.494c-0.149-1.786,0.59-6.522,3.199-3.95c0.792,0.78,0.083,2.155,0.558,2.943
+ c0.885,1.47,1.071,0.493,2.748,1.002c1.406,0.426,3.827,2.05,4.251,3.499"/>
+ <path id="rightArm" i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M57.05,283.306c-5.502,5.354-13.185,8.541-18.249,14.221c-4.303,4.827-7.721,11.575-11.138,17.112
+ c-6.752,10.939-10.794,26.076-19.912,35.185c-3.869,3.866-7.637,5.721-7.251,12.032c0.932,0.372,1.548,0.589,2.418,0.683
+ c0.605-2.746,2.569-4.199,5.362-3.799c-0.14,3.365-3.512,5.941-3.228,9.235c0.364,4.223,3.983,5.968,7.181,2.662
+ c2.61-2.699,0.192-7.848,3.338-10.179c5.535-4.103,2.889,2.998,4.13,5.514c5.19,10.519,8.634-1.859,7.35-7.996
+ c-2.336-11.159-3.003-15.126,3.267-24.416c6.358-9.419,12.194-18.708,19.399-27.588c1.116-1.375,2.08-2.728,3.333-4"/>
+ <g id="shirt" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F008000FFFF">
+ <path id="tShirt" i:knockout="Off" fill="#4459A5" stroke="#000000" stroke-linecap="round" d="M96.509,268.264
+ c-2.301,0.323-4.69,0.205-6.945,0.72c-2.234,0.509-4.5,0.8-6.749,1.249c-4.369,0.872-8.206,3.265-12.3,5.024
+ c-3.259,1.401-6.644,2.571-9.763,4.26c-1.923,1.041-3.688,2.616-5.487,3.97c-1.543,1.16-3.495,2.11-4.854,3.562
+ c-2.205,2.354,0.896,7.408,1.854,9.873c0.92,2.368,2.149,4.82,2.749,7.29c0.228,0.937,0.235,2.058,0.875,2.873
+ c0.644,0.821,0.64,0.735,1.822,0.048c1.513-0.878,2.873-1.993,4.329-2.993c2.431-1.67,5.462-2.848,7.434-5.111
+ c-3.335,1.652-5.335,4.679-6.931,8.012c-1.398,2.92-4.482,35.854-5.389,38.947c-0.195,0.003-0.775,0.003-0.749,0.013
+ c20.561,0,41.123-0.07,61.684,0c2.1,0.007,3.607-0.497,5.529-1.252c0.715-0.281,2.257-0.356,2.807-0.745
+ c1.412-0.998-0.094-3.916-0.646-5.302c-1.425-3.579-2.111-37.767-4.726-40.543c1.842,0.057,4.127,1.311,5.937,1.95
+ c1.351,0.478,2.633,1.092,3.956,1.66c1.39,0.597,3.667,1.927,5.168,1.858c0.296-1.873,1.045-3.286,1.839-5.02
+ c0.943-2.061,1.155-4.214,1.528-6.415c0.351-2.07,0.898-3.787,1.939-5.635c0.531-0.942,1.356-1.73,1.693-2.768
+ c-0.443-0.402-1.043-0.907-1.603-1.125c-0.56-0.219-1.292-0.111-1.908-0.33c-1.237-0.438-2.44-1.089-3.669-1.576
+ c-3.773-1.499-7.519-2.983-11.319-4.466c-3.575-1.396-6.977-3.239-10.784-3.872c-1.735-0.289-3.467-0.529-5.073-0.906"/>
+ <path id="shirtNeck" i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" d="M99.759,268.889
+ c-0.984,0.152-1.746-0.549-2.75-0.5c-1.369,0.066-1.649,0.872-2.153,2c-1.037,2.325-2.442,4.974,0.064,6.946
+ c2.53,1.991,6.964,1.717,9.829,0.803c1.616-0.516,3.045-1.24,3.825-2.867c0.508-1.061,0.935-2.771,0.149-3.598
+ c-0.231-0.243-0.562-0.376-0.84-0.534"/>
+ <g id="shirtLogo" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F008000FFFF">
+ <g i:knockout="Off">
+ <path i:knockout="Off" d="M104.864,296.92c-0.151-0.003,7.101,0.41,7.052,0.404c0.132,0.028-0.172,0.633-0.021,0.632
+ c-0.226,0.028-7.244-0.454-7.28-0.464C104.657,297.518,104.776,296.904,104.864,296.92z"/>
+ </g>
+ <g i:knockout="Off">
+ <path i:knockout="Off" d="M90.071,295.919c-0.199,0.004,6.792,0.43,6.79,0.446c0.153,0.005-0.031,0.663,0.012,0.665
+ c0.272,0.015-6.79-0.471-6.875-0.459C89.881,296.56,89.796,295.899,90.071,295.919z"/>
+ </g>
+ <path i:isolated="yes" i:knockout="Off" enable-background="new " d="M84.407,306.476c0.2-0.159,0.322-1.04,0.254,0.057
+ c-0.542-0.356-2.02,2.083-4.215,2.001c-1.887-1.706-4.559-3.384-4.302-7.092c0.652-2.599,3.082-4.084,5.213-3.942
+ c1.889,0.377,2.899,0.716,4,1.318c-0.497,0.957-0.175,0.866-0.459,0.703c0.456-2.398,0.598-5.75,0.312-7.855
+ c0.594-0.554,0.714,0.125,1.249,0.941c0.502-0.727,0.509-1.425,0.875-0.571c-0.207,1.328-0.809,7.186-0.711,10.174
+ c-0.126,2.797-0.375,4.354-0.051,4.985c-0.718,0.613-0.667,1.006-0.981,1.381c-0.72-1.33-1.056-0.132-1.339-0.157
+ C84.632,308.442,84.493,305.791,84.407,306.476z M81.186,307.176c2.403,0.206,3.734-2.164,3.841-4.222
+ c0.269-2.72-0.896-5.104-3.198-5.04c-1.972,0.437-3.46,2.188-3.331,4.638C78.171,306.265,79.847,306.961,81.186,307.176z"/>
+ <path i:isolated="yes" i:knockout="Off" enable-background="new " d="M93.321,297.766c2.592,0.148,5.688,2.315,5.696,5.627
+ c-0.611,4.576-3.69,5.316-6.158,5.581c-2.68-0.76-5.708-1.872-5.413-6.472C88.086,299.394,90.653,297.875,93.321,297.766z
+ M92.939,307.46c2.531,0.735,3.706-1.297,3.666-3.935c0.114-2.219-0.641-4.584-3.389-4.896c-2.29-0.552-3.366,2.188-3.661,4.688
+ C89.339,305.264,89.934,307.95,92.939,307.46z"/>
+ <path i:isolated="yes" i:knockout="Off" enable-background="new " d="M99.688,303.916c0.03-1.511,0.055-4.731,0.022-4.646
+ c0.481-1.355,0.658-0.556,1.034-1.297c0.263,1.473,0.653,0.326,1.186,0.066c-0.386,2.517-0.513,3.347-0.574,4.949
+ c-0.068-0.47-0.128,2.28-0.238,2.188c-0.055,1.935-0.036,2.201-0.047,4.219c-0.079,0.914-0.28,2.412-1.126,3.831
+ c-0.61,1.212-1.73,1.146-3.24,1.651c0.073-0.945-0.065-1.242-0.096-1.822c0.098,0.138,0.213,0.604,0.225,0.398
+ c1.892,0.228,2.209-1.896,2.362-3.366c0.042,0.304,0.512-6.933,0.415-7.061C99.73,302.636,99.75,303.178,99.688,303.916z
+ M100.978,295.564c0.717,0.14,1.11,0.61,1.099,1.156c0.052,0.552-0.595,0.993-1.286,1.015c-0.541-0.074-1.025-0.548-1.022-1.054
+ C99.813,296.084,100.292,295.643,100.978,295.564z"/>
+ <path i:isolated="yes" i:knockout="Off" enable-background="new " d="M108.115,298.791c3.028-0.067,5.283,1.359,5.256,5.757
+ c-0.264,3.479-3.366,4.63-5.883,5.12c-2.429-0.034-5.619-2.241-5.16-5.811C102.322,300.085,105.715,298.845,108.115,298.791z
+ M107.351,309.232c2.675-0.132,3.839-2.333,3.841-4.497c0.246-2.344-0.263-4.833-2.923-5.396
+ c-2.844,0.299-3.974,1.917-4.053,4.48C104.136,306.655,104.854,308.372,107.351,309.232z"/>
+ </g>
+ </g>
+ </g>
+ <g id="heads" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F004F00FFFF">
+ <g id="head1" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFFFFFF4F00">
+ <g id="leftEart" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFFFFFF4F00">
+ <path i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M201.557,195.474
+ c7.734-4.547,16.591-5.012,18.405,4.443c2.43,12.659-3.317,13.328-14.598,13.328"/>
+ <path i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M211.711,203.09
+ c0.523,0.004,0.946-0.208,1.27-0.635"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M211.076,197.377
+ c3.062,3.013,5.489,5.624,4.443,10.155"/>
+ </g>
+ <path id="bgHairTop" i:knockout="Off" fill="#FFF471" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M54.384,199.306c-5.253-4.402-7.511-11.061-15.779-10.632c3.449-1.277,7.116-2.397,10.911-2.666
+ c-2.873-1.397-5.865-2.575-8.231-4.718c3.986-1.119,11.47-1.817,14.864,0.75c-5.183-2.758-8.397-7.816-13.062-10.598
+ c6.014-0.643,12.377,0.978,18.022,2.265c-2.547-4.486-6.682-10.83-10.523-14.297c5.033,1.052,10.647,4.518,15.062,7.177
+ c-1.614-4.176-5.634-8.406-7.859-12.513c10.312-1.125,12.522,4.919,19.7,9.932c-0.412-0.127-1.114-0.113-1.527,0.015
+ c0.875-7.261,3.058-12.8,8.258-18.566c6.771-7.507,17.812-9.131,24.095-15.381c-4.699,1.821-4.518,23.765-4.875,28.955"/>
+ <path id="bgHairLeft" i:knockout="Off" fill="#FFF471" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M92.384,243.972c-6.334,7.929-12.601,12.241-22.465,15.362c3.65-1.263,7.735-5.86,7.695-9.928
+ c-2.208,0.218-4.49,0.605-6.498,1.097c1.244-1.097,2.087-3.239,3.198-4.396c-5.77,0.001-12.131,1.133-18.396,1.23
+ c5.013-2.809,10.665-3.25,12.398-9.246c-3.59,0.313-7.233,1.606-11.033,1.097c1.731-2.022,3.953-3.995,5.049-6.447
+ c-3.781,0.056-6.665,3.098-10.547,2.465c0.962-2.863,3.187-5.208,4.531-7.766c-5.59-0.273-11.658,2.45-17.732,2.564
+ c5.494-2.857,8.967-7.819,12.3-12.718c5.233-7.693,10.625-9.96,20.349-9.981c11.059-0.024,15.558,6.714,20.984,16
+ c2.786,4.767,7.249,14.375,0.832,18"/>
+ <path id="bgHair" i:knockout="Off" fill="#FFF471" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M142.384,255.306c2.984,6.076,3.567,11.856,10.531,14.6c-0.134-3.114-0.094-6.664,1.619-9.033
+ c1.605,1.968,3.122,4.211,5.048,5.698c-0.29-1.769,0.412-4.024,0.233-5.828c3.445,0.26,4.979,3.965,8.468,4.479
+ c0.066-2.78,0.427-5.151,0.868-7.813c2.687,0.2,4.768,1.565,7.132,2.997c0.452-4.921-0.409-10.579-0.667-15.666
+ c-5.795-0.756-12.291,2.827-17.899,3.899c-4.414,0.844-14.136,0.524-15.333,6"/>
+ <path id="neck" i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M106.989,254.499c-2.932,6.063-4.613,11.997-8.947,17.137c7.288,10.195,16.311-10.9,15.183-17.026
+ c-1.926-1.138-3.928-1.589-6.236-1.38"/>
+ <path id="headShape" i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M210.941,207.665c-0.843,3.985-2.081,7.982-3.769,11.783c-3.374,7.604-8.543,14.427-16.052,18.899
+ c-2.94,2.13-5.983,4.167-9.109,6.085c-25.013,15.342-55.353,23.08-82.254,10.57c-3.433-1.557-6.785-3.431-10.053-5.66
+ c-1.821-1.184-3.592-2.46-5.308-3.832c-1.715-1.373-3.375-2.842-4.972-4.412c-2.352-2.148-4.576-4.425-6.631-6.814
+ c-6.168-7.169-10.823-15.358-12.87-24.185c-0.649-3.284-0.84-6.634-0.5-9.975c4.48-13.743,14.22-24.364,26.109-32.149
+ c2.973-1.946,6.079-3.715,9.271-5.309c30.581-15.027,69.581-10.027,95.851,12.209c2.564,2.254,4.988,4.651,7.244,7.178
+ c4.513,5.054,8.354,10.626,11.312,16.64C210.178,201.505,210.798,204.496,210.941,207.665z"/>
+ <g id="rightEar" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFFFFFF4F00">
+ <path i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M64.857,195.606
+ c-6.59-7.181-15.047-10.664-19.467,3.676c-1.235,4.007-1.87,14.468,1.29,17.786c4.223,4.435,13.591,0.529,19.055-0.015"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M52.407,196.743
+ c-1.702,3.613-1.257,7.505-1.27,11.424"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M51.772,209.437
+ c-3.39-4.661,0.922-5.769,5.078-6.347"/>
+ </g>
+ <path id="fgHair" i:knockout="Off" fill="#FFF471" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M90.384,154.639c8.453-11.353,15.678-13.458,28.581-15.915c-1.382,3.376-3.89,7.352-5.179,11.16
+ c5.01-1.816,9.571-6.545,15.218-8.413c11.355-3.755,23.852-1.903,35.671-2.213c-3.004,3.712-4.912,7.88-2.026,11.447
+ c5.856-2.212,13.37-6.871,19.635-6.646c0.263,4.561-0.024,9.278,0.201,13.841c3.509-1.201,6.015-3.04,8.277-5.148
+ s3.761-4.049,4.942-5.2c1.063,2.408,2.134,5.334,2.24,8.494c-0.182,3.462-0.866,6.794-2.66,9.291
+ c3.663,0.65,6.098-2.021,8.35-4.479c-0.655,4.349-3.164,8.604-3.851,13.013c2.178-0.072,4.382,0.216,6.367-0.48
+ c-1.389,3.093-3.069,7.287-6.616,8.414c-4.475,1.423-4.354-0.992-7.315-4.332c-4.892-5.518-9.774-6.791-15.872-9.464
+ c-6.585-2.887-10.983-6.47-17.963-8.219c-8.994-2.255-19.864-3.867-28.093-5.196c2.466,1.967,1.138,5.594,0.659,8.625
+ c-2.729-0.645-4.41-3.813-6.301-5.158c0.953,3.195,0.983,6.953-2.134,8.491c-6.145-5.226-9.199-9.721-17.527-11.647
+ c1,1.83,1.728,4.208,1.396,6.402c-0.751,4.971-0.289,3.134-3.836,2.466c-5.192-0.977-9.953-3.677-15.815-4.496
+ c3.292,2.002,5.469,5.017,7.418,8.21c-2.651,0.404-6.238,0.257-8.382,1.671c2.456,0.38,3.44,2.166,3.197,4.714
+ c-7.45,0.386-13.623,0.731-19.915,5.434"/>
+ </g>
+ </g>
+ <g id="eyes" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFF4F00FFFF">
+ <g id="eyes1" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#4F00FFFFFFFF" display="none">
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M123.163,176.668
+ c-5.066,1.17-9.01,7.888-13.666,10.335c-4.238,2.227-8.648,6.636-7.009,12.332c1.971,6.848,12.042,3.991,16.261,1.165
+ c5.282-3.539,9.59-8.517,12.006-14.524c1.523-3.787,2.568-7.272-1.509-9.391c-2.905-1.51-8.174-1.386-11.417-0.583"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" stroke-linecap="round" d="M182.545,179.865
+ c-3.533,0.169-4.854-1.166-8.408-0.001c-3,0.983-6.24,1.936-8.852,3.743c-3.938,2.725-7.46,5.555-4.73,13.592
+ c1.973,5.811,8.791,7.571,14.656,6.667c5.537-0.854,9.078-4.977,11.408-10.007c3.666-7.918,0.943-11.639-6.742-13.659"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M108.829,183.668c-1.308-1.03-4.557,0.011-5.6-1.733
+ c-1.056-1.765,1.735-5.409,2.984-6.192c5.684-3.562,15.946-0.39,19.95-6.742"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M163.877,167.198c2.369,1.282,6.539,0.307,9.408,0.815
+ c3.449,0.612,7.066,2.657,10.592,2.851"/>
+ <path i:knockout="Off" display="inline" stroke="#000000" d="M127.496,192.002c-4.917-2.12-9.188-1.708-8.608,4.942
+ c3.132,1.734,5.428-2.82,7.275-4.942"/>
+ <path i:knockout="Off" display="inline" stroke="#000000" d="M174.852,203.143c-0.293,0.12-0.307,0.577-0.943,0.282
+ c-1.605-3.188-0.404-6.507,2.676-8.192c2.15-1.176,5.67-1.759,7.471,0.359c0.199,0.234,0.412,0.521,0.514,0.813
+ c0.229,0.649-0.285,0.95-0.285,0.95s-3.988,6.009-3.285,1.934c0.438,1.743-5.537,5.743-2.287,1.653
+ c-1.955,2.583-2.525,1.977-3.859,2.868"/>
+ </g>
+ <g id="eyes2" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#800080008000" display="none">
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M98.668,186.108c0.668-8.915,15.545-13.749,22.667-15"
+ />
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M169.667,178.108
+ c5.307,3.436,16.928,5.632,19.668,12.333"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M105.334,197.775c8.085-4.283,17.059-2.8,25-6.333"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M164.001,198.775c4.656-0.417,9.664,1.805,14.334,2.017
+ c3.951,0.18,5.773,0.189,9,2.316"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M124.001,188.108c3.039-0.258,4.594,2.571,5.301,4.983
+ c-1.096,1.242-2.065,2.646-2.968,4.017"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M168.335,194.108c-1.77,2.293-4.869,3.271-6.299,5.91
+ c1.377,0.991,3.02,2.122,3.965,3.424"/>
+ </g>
+ </g>
+ <g id="beard" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFF4F00">
+ <path i:knockout="Off" fill="#AFA8A5" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M96.05,213.639
+ c-0.366,0.21-0.783,0.389-1.167,0.5"/>
+ <path i:knockout="Off" fill="#AFA8A5" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M102.55,211.972
+ c0.314-0.01,0.554-0.198,0.667-0.5"/>
+ <path i:knockout="Off" fill="#AFA8A5" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M105.717,208.805
+ c0.164-0.109,0.336-0.224,0.5-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M111.05,207.972
+ c-0.651-1.81,0.859-2.262,2.333-1.5"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M117.717,209.805
+ c1.738,0,3.653,0.369,5.333,0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M132.717,214.472
+ c0.104-0.21,0.162-0.435,0.167-0.667"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M139.551,216.972
+ c0.215-0.175,0.465-0.426,0.666-0.667"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M144.551,213.305
+ c0.277-0.056,0.556-0.111,0.833-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M147.884,216.639
+ c0.195,0.045,0.369-0.013,0.5-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M148.384,214.139
+ c0.112-0.168,0.222-0.332,0.333-0.5"/>
+ <path i:knockout="Off" display="none" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M98.217,219.305c1.697-1.772,4.233-2.109,5.967-4.046c1.519-1.696,3.812-3.001,4.2-5.454"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M152.717,216.139
+ c0.611,0,1.223,0,1.834,0"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M160.384,217.472
+ c0.333,0,0.667,0,1,0"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M163.217,215.972
+ c0.321-0.042,0.658-0.175,0.834-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M164.217,218.805
+ c0.167,0,0.333,0,0.5,0"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M168.384,217.972
+ c0.056-0.056,0.111-0.111,0.167-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M169.884,225.805
+ c0.491-0.397,0.882-0.926,1.167-1.5"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M172.717,221.972
+ c0.056,0,0.111,0,0.167,0"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M171.717,229.805
+ c0.334,0.075,0.659,0.025,0.834-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M190.051,227.805
+ c0.163-0.242,0.398-0.423,0.666-0.5"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M197.384,221.472
+ c0.258-0.007,0.485-0.125,0.667-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M199.384,214.972
+ c-0.04-0.333,0.075-0.609,0.333-0.833"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M117.884,257.305
+ c0.056,0,0.111,0,0.167,0"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M142.717,252.472
+ c0.358,0.069,0.71,0.016,1-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M137.884,256.472
+ c0.277,0,0.556,0,0.833,0"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M160.884,252.972
+ c0.366-0.138,0.765-0.402,1-0.667"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M171.384,250.139
+ c0.235-0.263,0.475-0.561,0.667-0.834"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M89.384,243.972
+ c0.537,0.378,1.329,0.876,1.833,1.333"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M79.05,225.472
+ c0.087,0.272,0.143,0.55,0.167,0.833"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M73.884,222.639
+ c0,0.167,0,0.333,0,0.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M72.55,219.805c0.466-0.325,0.875-0.797,1.167-1.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M71.717,211.972c0.422-0.553,0.776-1.305,1-2"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M78.55,214.472c0-0.111,0-0.222,0-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M79.384,218.805c-0.001-0.137,0.055-0.248,0.167-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M80.217,221.139c0.111,0,0.222,0,0.333,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M75.55,226.472c0.103-0.5,0.156-0.977,0.167-1.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M78.55,230.139c0.111,0,0.222,0,0.333,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M83.384,227.639c0.118-0.059,0.215-0.107,0.333-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M81.55,237.139c0.056,0,0.111,0,0.167,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M86.217,233.805c0.056,0,0.111,0,0.167,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M87.884,230.472c0.595-0.181,1.219-0.527,1.833-0.667"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M88.717,222.139
+ c-0.929,2.359-1.615,4.865-2.667,7.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M89.05,216.139
+ c0.784-0.736,1.709-1.565,2.833-1.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M94.217,210.139
+ c1.599-0.089,3.199-0.167,4.833-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M94.884,224.639
+ c0.052-0.588-0.004-1.155-0.167-1.667"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M92.384,228.305
+ c0.585-0.062,1.244-0.132,1.667-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M88.717,240.139
+ c0.111,0,0.222,0,0.333,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M95.884,243.305
+ c0.526,0.1,1.017-0.015,1.333-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M98.55,248.305
+ c0.069-0.24,0.265-0.926,0.333-1.166"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M96.55,249.805
+ c0.125,0.014,0.18-0.042,0.167-0.166"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M104.55,250.139
+ c0.01-0.238,0.126-0.428,0.333-0.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M106.884,251.972
+ c0.195,0.045,0.37-0.013,0.5-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M113.884,254.805
+ c0.758-0.586,1.595-1.171,2.382-1.774c0.072,0.376,0.418,0.685,0.48,1.079c0.833,0.265,1.624-0.021,1.638-0.971"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M122.217,254.639
+ c0.063-0.165,0.179-0.288,0.333-0.334"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M125.884,255.805
+ c1.13-0.745,2.783-0.962,3.667-2"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M132.217,255.972
+ c0.638-0.492,1.104-1.173,1.141-1.975c-1.11,0.062-1.449-0.888-1.475-1.858"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M129.717,249.305
+ c-0.045,0.154-0.168,0.271-0.333,0.334"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M136.551,252.305
+ c0.222,0,0.444,0,0.666,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M110.217,251.305
+ c0.056-0.056,0.111-0.11,0.167-0.166"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M140.717,251.805
+ c0.111,0,0.223,0,0.334,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M150.051,249.472
+ c0.111,0,0.222,0,0.333,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M143.217,255.472
+ c1.022-0.313,1.724-1.175,2.646-1.654c0.203,0.321,0.44,0.626,0.521,0.987"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M152.217,253.472
+ c0.165-0.063,0.288-0.179,0.334-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M155.051,254.639
+ c0.222,0,0.444,0,0.666,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M157.717,256.472
+ c0.326-0.027,0.546-0.073,0.834-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M163.217,252.639
+ c0.552-0.891,2.082-1.512,2.341-2.334c0.37-1.177-1.156-3.069-1.007-4.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M167.384,235.972
+ c0.118-0.54,0.353-1.064,0.667-1.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M170.717,242.805
+ c0-0.333,0-0.667,0-1"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M170.217,236.972
+ c0-0.333,0-0.667,0-1"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M179.051,235.805
+ c0.378-0.101,0.738-0.35,1-0.667"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M185.051,232.805
+ c0.379-0.319,0.656-0.702,0.833-1.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M188.051,231.139
+ c0.063-0.39,0.178-0.792,0.333-1.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M197.884,223.305
+ c-0.166,0.277-0.334,0.556-0.5,0.833"/>
+ </g>
+ <g id="mouths" i:isolated="yes" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFF4F004F00" enable-background="new ">
+ <g id="mouth1" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#4F00FFFF4F00" display="none">
+ <path i:knockout="Off" display="inline" stroke="#000000" d="M177.122,216.821c-0.515,2.282-5.213,3.21-7.433,3.854
+ c-3.254,0.945-6.596,1.345-9.895,1.851c-3.26,0.5-6.665,0.671-10.107,0.671c-3.596,0-6.645,0.559-10.107,0.671
+ c-3.105,0.1-6.898-0.474-9.694-1.3c-3.527-1.043-6.672-1.666-10.096-3.062c-2.823-1.152-5.746-1.876-8.462-3.143
+ c-2.594-1.209-6.084-1.994-8.221-3.552c-1.068,1.834-5.867,3.748-8.1,4.546c-2.444,0.874-8.881,2.725-7.817,5.512
+ c0.457,1.195,1.948,2.273,2.63,3.385c0.774,1.261,1.139,2.601,2.057,3.859c1.83,2.5,4.506,4.773,6,7.34
+ c1.308,2.249,2.096,4.74,4.01,6.67c2.214,2.233,5.792,2.634,9.231,2.399c7.028-0.479,13.982-2.129,20.481-3.983
+ c3.295-0.941,6.699-1.536,10.087-2.686c3.272-1.111,6.641-3,9.402-4.777c5.248-3.377,10.278-6.409,14.283-10.705
+ c1.479-1.587,3.429-2.503,5.15-3.859"/>
+ <path i:knockout="Off" display="inline" fill="#FFC0C0" stroke="#000000" d="M135.25,241.319
+ c0.723-4.757-10.487-8.47-14.898-9.526c-3.09-0.74-6.68-1.17-9.858-1.712c-2.758-0.47-6.865-0.836-9.437,0.369
+ c-1.385,0.649-2.843,1.724-4.141,2.513c2.156,3.964,4.728,8.861,9.468,11.506c3.229,1.801,5.511,0.777,8.859,0.373
+ c3.045-0.369,6.046-0.703,9.029-1.72c3.479-1.186,7.228-2.385,10.978-2.475"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M148.656,225.547c1.267,0.697,1.301,2.838,0.671,3.9
+ c-0.702,1.182-2.063,1.4-3.306,2.01c-2.271,1.116-4.581,2.624-7.482,2.638c-4.619,0.023-2.143-4.067-0.253-5.869
+ c2.405-2.292,5.057-2.72,8.72-2.512c0.588,0.034,1.095,0.041,1.65,0.168"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M130.299,223.365
+ c2.687,0.437,5.619,4.384,3.727,6.422c-1.234,1.33-7.94,1.391-9.915,1.296c-4.896-0.233-2.502-2.445-0.613-4.525
+ c1.604-1.767,5.088-3.249,7.833-3.36"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M113.178,217.157
+ c2.56,0.958,4.922,5.057,5.352,7.215c0.377,1.885-0.324,2.106-2.526,2.643c-1.366,0.333-3.636,0.723-5.105,0.385
+ c-2.506-0.577-5.883-5.051-4.909-7.223c1.03-2.298,5.944-2.923,8.427-2.852"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M99.359,217.661
+ c2.038,0.432,4.015,4.279,2.468,5.625c-1.083,0.943-5.221,1.795-6.799,1.589c-4.032-0.526-2.265-4.102-0.866-5.872
+ c0.706-0.894,1.049-1.976,2.514-2.186c1.627-0.233,2.501,0.99,3.921,1.346"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M181.815,222.895c-3.101-2.75-4.764-8.777-9.282-10.403
+ "/>
+ </g>
+ <g id="mouth2" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#4F00FFFF4F00" display="none">
+ <path i:knockout="Off" display="inline" stroke="#000000" stroke-width="3" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M87.57,221.951c5.563-1.759,11.066-1.32,16.694-1.782c2.93-0.24,5.228-1.14,8.309-0.927c3.142,0.217,6.085-0.235,9.289,0.176
+ c7.136,0.914,13.96,0.598,21.112,1.506c3.654,0.464,7.218,0.609,10.81,0.869c4.017,0.291,7.646,1.582,11.433,2.623
+ c2.948,0.812,6.347,1.618,9.011,2.99c2.521,1.298,6.354,2.856,8.3,4.72c-2.775,0.027-5.601,2.603-8.021,3.769
+ c-2.93,1.412-5.741,2.949-8.656,4.432c-5.599,2.849-11.885,5.468-18.104,6.53c-6.793,1.161-13.195,2.107-20.067,2.197
+ c-7.699,0.102-14.313-4.705-20.735-8.396c-2.071-1.19-4.69-2.182-6.504-3.666c-1.792-1.466-3.469-3.386-5.154-4.984
+ c-2.703-2.564-7.519-5.649-8.13-9.438"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" stroke-width="2" d="M87.785,228.193
+ c-5.907-3.235-0.344-9.531,3.971-11.424"/>
+
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M184.679,227.228c-1.534,2.583-2.548,5.334-4.025,7.889"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M106.862,219.528
+ c-3.071-0.74-5.608,2.166-6.318,4.738c-0.379,1.375-0.494,2.55,0.748,3.337c1.519,0.962,2.905-0.052,4.418-0.332
+ c2.518-0.467,7.293,0.053,6.461-4.248c-0.568-2.938-3.743-3.682-6.338-3.335c-0.451,0.06-0.758,0.212-1.205,0.229"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M119.764,218.479
+ c-2.648,1.243-4.657,3.518-5.346,6.377c-0.866,3.594,3.9,3.711,6.356,2.865c2.64-0.91,4.77-3.351,3.299-6.133
+ c-1.01-1.91-3.979-2.548-6.026-2.823"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M130.388,219.492
+ c-1.753,1.382-4.069,4.525-4.835,6.61c-1.159,3.156,2.296,3.371,4.868,3.348c3.061-0.028,6.6-1.148,5.022-4.78
+ c-1.168-2.691-2.552-4.85-5.551-5.241"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M142.954,221.087
+ c-1.502,0.337-5.418,3.249-5.638,4.997c-0.292,2.311,4.856,4.536,6.854,4.234c2.503-0.377,4.384-3.175,3.167-5.65
+ c-0.92-1.873-3.36-2.252-4.508-3.932"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M155.354,222.663
+ c-2.039,0.426-4.212,2.287-4.766,4.444c-0.723,2.821,3.225,3.383,5.458,3.331c2.541-0.059,5.126-1.752,3.249-4.32
+ c-1.394-1.908-3.707-3.189-5.304-4.636"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M168.367,237.924
+ c-1.554-1.217-3.302-2.557-5.203-2.976c-2.973-0.654-3.537,2.131-3.377,4.406c0.205,2.913,1.032,3.883,3.901,2.344
+ c1.988-1.066,4.272-1.997,4.599-4.456"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M151.524,246.202
+ c-1.912-0.166-4.003-4.491-2.91-6.25c0.771-1.239,5.456-1.688,6.858-1.292c0.271,0.917,0.979,1.841,0.829,2.771
+ c-0.088,0.54-0.994,1.645-1.296,2.188c-1.08,1.951-2.133,1.866-3.998,2.684"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M145.911,241.457
+ c-0.209,1.649-0.215,2.702-1.528,3.801c-0.885,0.739-1.773,1.19-2.54,2.1c-0.786,0.933-1.226,2.38-2.792,1.812
+ c-1.042-0.377-1.959-2.318-2.138-3.311c-0.299-1.676-1.003-5.228,0.783-6.158c1.155-0.603,7.067-0.18,7.43,1.32"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M133.12,238.991
+ c-1.495-0.087-2.253-1.33-3.918-0.964c-1.42,0.311-2.489,1.354-2.54,2.836c-0.052,1.527,0.99,5.581,1.852,6.956
+ c2.363,3.771,4.329-1.535,5.516-3.159c1.117-1.526,2.643-2.053,2.271-3.958c-0.318-1.632-1.118-2.047-2.766-2.329
+ c-0.382-0.065-0.773-0.095-1.158-0.147"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M116.853,237.429
+ c-1.049,2.211-0.173,5.147,0.047,7.566c0.357,3.929,3.827,2.028,5.831,0.067c1.575-1.541,4.599-4.86,2.209-6.484
+ c-1.881-1.279-5.727-2.458-7.756-1.107"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M107.455,233.38
+ c-0.813,2.487-1.704,5.049,0.073,7.364c1.91,2.486,4.009,1.229,5.537-0.939c1.056-1.5,3.316-4.481,1.563-6.017
+ c-1.347-1.179-6.468-1.518-7.854-0.325"/>
+ </g>
+ <g id="mouth3" i:isolated="yes" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFF4F00" enable-background="new ">
+ <path i:knockout="Off" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M99.05,218.972
+ c1.691-0.875,3.313-2.39,4.833-3.537c1.231-0.928,2.782-1.671,3.5-3.072c1.846,3.486,7.661,4.669,11.003,6.067
+ c3.553,1.486,7.174,3.066,10.784,4.166c4.271,1.301,9.277,1.67,13.721,2.343c4.155,0.629,9.979,1.365,14.162,0.496
+ c1.181-0.245,2.343-1.024,3.462-1.446c0.162,1.905-3.637,3.023-4.933,3.487c-2.435,0.871-4.18,2.541-6.362,3.871
+ c-1.623,0.989-2.974,1.669-4.755,2.117c-1.77,0.445-3.353,0.806-4.825,1.878c-5.915,4.311-15.264,3.247-22.424,3.13
+ c-5.384-0.088-6.719-5.372-9.337-9c-1.437-1.991-2.843-3.854-3.796-6.138c-0.871-2.086-1.119-4.582-2.033-6.528"/>
+ <path i:knockout="Off" fill="#F4BDBD" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M107.217,227.972
+ c1.182-2.033,4.375-2.176,6.5-1.963c2.879,0.289,4.124,1.217,6.168,3.167c1.834,1.749,5.906,5.509,5.64,8.271
+ c-2.808,0.89-7.847,0.402-10.346-1.104c-1.334-0.804-1.151-2.256-2.246-3.588c-0.712-0.866-1.836-2.673-2.855-3.311
+ c-0.209-0.94-2.106-1.499-3.028-1.805"/>
+ </g>
+ </g>
+ <g id="personalProps" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F004F00FFFF">
+ <g id="hat" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#FFFFFFFF4F00" display="none">
+ <g display="inline">
+ <g i:knockout="Off">
+ <path i:knockout="Off" fill="#FF0000" d="M88.374,173.144c0.474-0.074,16.606,2.725,18.01,5.879
+ c1.145,2.572,28.184,4.568,28.184,4.568l35.971-5.618l5.025,1.132l7.211,0.315l9.295,0.851l10.188,3.248l5.75,2.935
+ l1.615-1.832l-0.264-5.27l-3.967-7.087c0,0-22.045-13.031-23.273-13.703c-1.229-0.669-4.941-2.294-6.484-4.542
+ c-8.584-12.528-8.404-18.05-3.371-6.461c0,0,2.662-7.592,2.52-8.575c-0.143-0.982,0.355-5.031,0.355-5.031l2.396-6.832
+ c0,0-1.379-5.341-2.738-7.19c-1.357-1.844-15.793-4.078-18.162-4.011c-24.933,0.706-3.783,0.071-25.567,0.724
+ c-24.317,0.728-0.882-2.591-24.068,3.551c-24.228,6.418-5.35-1.298-23.187,6.142c-18.301,7.633-16.67,7.186-16.704,10.685
+ c-0.034,3.499-3.057-4.884-0.034,3.499c3.023,8.381,3.037-3.871,3.023,8.381c-0.015,12.252,6.696,4.557,1.678,12.373
+ c-5.017,7.813-3.831,7.91-0.179,8.543c17.017,2.953,4.157,4.378,17.427,3.175"/>
+ <path i:knockout="Off" d="M156.605,114.92l-13.936,0.381l-11.633,0.343c-10.646,0.319-11.973-0.155-12.021-0.175l-0.599-0.238
+ l-0.577,0.514l0.049-0.047c-0.118,0.09-1.43,0.957-11.145,3.53c-9.989,2.646-12.812,2.931-13.421,2.704
+ c-0.822-0.306-0.821-0.306-7.791,2.604l-2.104,0.878c-16.037,6.689-17.342,7.324-17.342,10.316c0,0.019,0.001,0.041,0.001,0.06
+ c-0.224-0.108-0.459-0.199-0.787-0.04c-0.357,0.173-0.565,0.275-0.565,0.672c0,0.557,0.411,1.697,1.399,4.438
+ c0.924,2.561,1.71,3.671,2.714,3.833c0.083,0.014,0.164,0.02,0.241,0.02c0.007,0.584,0.01,1.339,0.01,2.313
+ c0,0.561-0.001,1.902-0.001,1.916c0,6.908,2.176,8.105,3.347,8.749c0,0,0.075,0.045,0.151,0.09
+ c-0.095,0.332-0.47,1.1-1.661,2.955c-2.509,3.908-3.516,5.931-3.516,7.303c0,0.358,0.068,0.671,0.196,0.962
+ c0.544,1.237,1.926,1.477,3.677,1.78l0.135,0.023c8.138,1.412,9.14,2.422,9.568,2.854c0.923,0.931,1.511,0.928,7.224,0.413
+ c0.06,0.014,0.102,0.068,0.165,0.071c2.167,0.105,16.131,3.138,17.087,5.288c1.147,2.578,16.416,4.228,29.023,5.159
+ l0.115,0.009c0,0,35.523-5.548,35.896-5.606c0.345,0.078,4.927,1.11,4.927,1.11l7.3,0.319c0,0,8.927,0.818,9.139,0.837
+ c0.202,0.064,9.854,3.142,10.006,3.19c0.143,0.073,6.368,3.251,6.368,3.251l2.398-2.719l-0.296-5.911l-4.213-7.526
+ l-0.232-0.137c-0.9-0.532-22.073-13.047-23.303-13.72c-0.001,0-0.735-0.38-0.735-0.38c-1.48-0.752-4.238-2.151-5.404-3.85
+ c-1.357-1.982-2.451-3.729-3.355-5.268c0.022-0.064,0.104-0.296,0.104-0.296c1.193-3.402,2.576-7.619,2.576-8.885
+ c0-0.063-0.004-0.118-0.011-0.165c-0.012-0.083-0.017-0.204-0.017-0.356c0-0.909,0.194-2.911,0.363-4.307
+ c0.072-0.205,2.46-7.013,2.46-7.013l-0.076-0.294c-0.146-0.566-1.468-5.584-2.9-7.532
+ C173.721,116.784,158.242,114.874,156.605,114.92z M131.097,117.643l11.614-0.342l13.951-0.382
+ c2.575-0.073,16.104,2.238,17.336,3.614c0.956,1.3,2.058,4.938,2.49,6.549c-0.188,0.536-2.33,6.642-2.33,6.642l-0.013,0.107
+ c-0.073,0.592-0.387,3.224-0.387,4.658c0,0.258,0.011,0.477,0.034,0.639c-0.006,0.493-0.768,3.026-1.659,5.709
+ c-2.14-4.566-2.792-4.606-3.242-4.629l-0.62-0.031l-0.354,0.571c-0.069,0.124-0.102,0.29-0.102,0.492
+ c0,2.273,4.134,9.172,6.993,13.346c1.456,2.12,4.509,3.669,6.149,4.501l0.682,0.353c1.138,0.622,20.813,12.25,23.011,13.549
+ c0.239,0.427,3.513,6.275,3.721,6.647c0.02,0.393,0.199,3.971,0.231,4.629c-0.23,0.262-0.472,0.535-0.832,0.944
+ c-1.07-0.546-5.132-2.619-5.132-2.619l-10.369-3.306l-9.404-0.86c0,0-6.995-0.307-7.169-0.315
+ c-0.168-0.038-5.124-1.155-5.124-1.155s-35.814,5.594-36.044,5.63c-12.419-0.922-25.993-2.687-27.285-4.058
+ c-1.366-3.097-13.245-5.574-17.517-6.211c-0.203-0.212-0.479-0.346-0.793-0.318c-3.083,0.28-5.996,0.544-6.4,0.369
+ c0-0.003-0.12-0.117-0.12-0.117c-0.703-0.708-1.879-1.895-10.646-3.416l-0.135-0.023c-0.827-0.143-2.075-0.359-2.188-0.614
+ c-0.021-0.048-0.033-0.111-0.033-0.193c0-0.592,0.632-2.179,3.205-6.187c1.488-2.318,2.024-3.388,2.024-4.188
+ c0-0.15-0.019-0.291-0.054-0.428c-0.181-0.712-0.758-1.03-1.179-1.261c-0.865-0.476-2.311-1.271-2.311-6.993
+ c0-0.014,0.001-1.098,0.001-1.56c0-4.969-0.065-4.992-0.833-5.258c-0.424-0.146-0.816,0.001-1.178,0.377
+ c-0.208-0.289-0.558-0.898-1.073-2.324c-0.205-0.568-0.385-1.068-0.542-1.506c0.587-0.423,0.632-1.277,0.636-1.644
+ l-0.014-0.825c-0.004-0.119-0.007-0.231-0.007-0.338c0-1.702,0.899-2.264,16.109-8.608l2.105-0.878
+ c4.165-1.739,5.948-2.482,6.375-2.562c0.817,0.296,2.292,0.597,14.579-2.658c8.169-2.164,10.697-3.187,11.58-3.704
+ C120.451,117.773,124.529,117.84,131.097,117.643z"/>
+ </g>
+ <g i:knockout="Off">
+ <path i:knockout="Off" fill="#FFFFFF" d="M155.146,147.929c4.879-9.398-5.344-20.199-12.65-21.176
+ c-12.05-1.61-13.404,10.426-13.684,21.258c3.73,2.016,8.915,3.425,11.721,6.534"/>
+ <path i:knockout="Off" d="M133.446,127.979c-4.599,3.921-5.426,11.933-5.635,20.006l-0.017,0.654l4.415,2.067
+ c2.849,1.244,5.793,2.529,7.581,4.509c0.371,0.41,1.004,0.442,1.412,0.072c0.219-0.197,0.33-0.469,0.33-0.743
+ c0-0.239-0.084-0.479-0.258-0.67c-2.076-2.299-5.222-3.673-8.266-5.001c0,0-2.377-1.112-3.174-1.486
+ c0.223-7.385,1.021-14.572,4.909-17.887c1.892-1.614,4.386-2.189,7.621-1.757c4.143,0.554,9.086,4.472,11.5,9.113
+ c1.348,2.591,2.51,6.535,0.395,10.611c-0.254,0.49-0.064,1.093,0.426,1.348c0.49,0.254,1.094,0.063,1.35-0.427
+ c1.959-3.775,1.818-8.199-0.395-12.456c-2.732-5.251-8.203-9.53-13.012-10.172C138.853,125.257,135.763,126,133.446,127.979z"
+ />
+ </g>
+ <g i:knockout="Off">
+ <path i:knockout="Off" d="M154.077,146.278c-2.156,1.18-4.24,2.619-6.256,4.01c-3.635,2.509-7.068,4.878-10.941,5.924
+ c-2.991,0.808-6.055,1.058-9.3,1.324c-3.222,0.263-6.553,0.536-9.783,1.406c-2.027,0.546-4.117,1.397-6.137,2.221
+ c-3.491,1.423-7.102,2.895-10.528,2.866c-0.552-0.005-1.004,0.439-1.009,0.991s0.439,1.004,0.991,1.009
+ c3.828,0.033,7.627-1.516,11.301-3.014c2.054-0.837,3.994-1.628,5.902-2.142c3.054-0.823,6.292-1.088,9.425-1.344
+ c3.191-0.261,6.492-0.531,9.659-1.386c4.205-1.135,7.941-3.714,11.557-6.208c1.973-1.362,4.014-2.771,6.08-3.901
+ c0.484-0.265,0.662-0.873,0.396-1.357S154.562,146.013,154.077,146.278z"/>
+ </g>
+ <g i:knockout="Off">
+ <path i:knockout="Off" d="M156.458,153.549c-2.619,0.064-5.709,0.812-8.98,1.604c-4.279,1.035-8.701,2.104-11.902,1.536
+ c-0.543-0.096-1.063,0.267-1.159,0.81c-0.097,0.544,0.267,1.063,0.81,1.16c3.613,0.641,8.24-0.481,12.72-1.562
+ c3.166-0.766,6.154-1.489,8.561-1.548c5.664-0.141,7.961,0.698,13.508,2.724c0.518,0.189,1.094-0.077,1.281-0.596
+ c0.189-0.519-0.076-1.091-0.596-1.282C165.069,154.337,162.501,153.399,156.458,153.549z"/>
+ </g>
+ </g>
+ </g>
+ <g id="textSurface" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFFFFFF4F00">
+ <g id="spokenBubble" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFF4F00FFFF">
+ <path id="textContainer" i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M225.719,45.306c0-6.627,5.373-12,12-12h181.333
+ c6.627,0,12,5.373,12,12V150.64c0,6.627-5.373,12-12,12H237.719c-6.627,0-12-5.373-12-12V45.306z"/>
+ <path id="textArrowBelow" i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M249.052,160.639
+ c-0.775,14.251-1.676,18.525-9.1,30.565c9.705-0.79,21.952-21.605,25.1-30.045"/>
+ </g>
+ <g id="thoughtBubble" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#FFFF4F00FFFF" display="none">
+ <path id="textContainer_1_" i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M202.698,21.089
+ c19.686-26.45,59.686-24.45,79.747-0.084c2.697,1.349,5.571,1.709,7.472,0.781c15.28-13.888,33.272-14.043,49.893-7.839
+ c2.771,1.034,5.478,2.219,8.031,3.421c28.543-21.729,75.543-10.729,83.166,27.658c0,0-1.324,3.889,1.165,6.603
+ c18.212,11.011,26.212,32.011,22.212,53.011c-1,5.333-3.223,9.667-6.037,13.52c-2.814,3.854-1.381,0-2.613-0.591
+ c-1.35-0.929-3.35-0.929-4.35-1.929c16,7,27,22,30,39c2,21-8,41-27,50c-16,7.5-32.5,5.5-45.745-2.556
+ c-2.532-1.384-4.229-1.856-5.336-1.551c-1.919,0.107-3.919,2.107-5.919,2.107c4-1,6-5,10-6c-15,11-35,12-52,3c-13-7-20-20-24-34
+ c1,5,3,9,3.299,13.505c-0.397,0.708-3.423,2.219-6.655,3.466c-22.627,8.729-49.423,1.729-65.241-19.971
+ c-3.453,0-6.263,0.589-8.723,0.879c-17.3,3.2-32.381-7.709-40.771-22.689c-1.678-2.996-3.089-6.153-4.195-9.396
+ c-15.714-7.795-29.714-18.795-33.714-37.795c-5-25,11-45,29.842-57.667c0.719-2.335,1.697-4.636,3.006-6.896
+ C201.159,23.306,202.698,21.089,202.698,21.089z"/>
+ <g i:knockout="Off" display="inline">
+ <path i:knockout="Off" fill="#FFFFFF" d="M269.719,186.306c0,4.602-4.179,8.333-9.333,8.333c-5.155,0-9.334-3.731-9.334-8.333
+ c0-4.603,4.179-8.333,9.334-8.333C265.54,177.973,269.719,181.704,269.719,186.306z"/>
+ <g>
+ <path i:knockout="Off" fill="none" d="M269.719,186.306c0,4.602-4.179,8.333-9.333,8.333c-5.155,0-9.334-3.731-9.334-8.333
+ c0-4.603,4.179-8.333,9.334-8.333C265.54,177.973,269.719,181.704,269.719,186.306z"/>
+ <path i:knockout="Off" fill="#FFFFFF" d="M268.225,186.165c-0.564,8.736-13.982,9.286-15.633,0.853
+ c-1.785-9.125,15.017-10.254,15.649-0.451c0.125,1.929,3.078,1.388,2.955-0.521c-0.814-12.597-20.828-12.412-21.639,0.119
+ c-0.827,12.813,20.831,13.028,21.655,0.283C271.337,184.518,268.35,184.235,268.225,186.165z"/>
+ </g>
+ </g>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M260.386,188.306c0,3.498-2.985,6.333-6.667,6.333
+ s-6.667-2.835-6.667-6.333c0-3.498,2.985-6.333,6.667-6.333S260.386,184.808,260.386,188.306z"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M238.386,196.973c0,1.289-1.045,2.333-2.334,2.333
+ c-1.288,0-2.333-1.045-2.333-2.333s1.045-2.333,2.333-2.333C237.341,194.639,238.386,195.684,238.386,196.973z"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M285.719,179.973c0,4.602-4.253,8.333-9.5,8.333
+ s-9.5-3.731-9.5-8.333c0-4.603,4.253-8.333,9.5-8.333S285.719,175.371,285.719,179.973z"/>
+ </g>
+ <g id="yellBubble" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#FFFF4F00FFFF" display="none">
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M251.156,176.051
+ l40.228-15.992"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M280.932,149.385
+ l-40.667,36.42"/>
+ <path id="textContainer_2_" i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M217.778,34.643
+ c8.609,6.684,9.952,3.684,7.987-5.785c6.308,5.125,9.308,3.782,10.188-4.309c2.433,8.091,5.266,8.091,9.12-1.703
+ c6.063,9.793,13.146,9.793,24.043,3.878c6.103,5.915,16.02,5.915,20.094-4.64c17.178,10.555,28.511,10.555,45.233-5.505
+ c5.941,16.06,17.273,16.06,18.835,1.458c19.688,14.603,29.605,14.603,46.749-17.802c-0.144,32.405,6.939,32.405,29.26,16.182
+ c-12.403,16.223-9.57,16.223,4.813,6.576c-11.07,9.646-8.07,10.99,4.333,9.089c-8.061,6.244-6.717,9.244,2.533,11.068
+ c-9.25,1.489-9.25,5.703-0.315,13.07c-8.935,6.115-8.935,15.385,7.513,10.932c-16.447,24.677-16.447,35.631,14.938,36.553
+ c-31.385,19.303-31.385,28.571-4.39,40.526c-26.995,1.528-26.995,5.741-5.942,17.857c-21.053-8.801-22.396-5.802-9.526,11.916
+ c-17.213-13.374-20.213-12.03-12.048,8.029c-11.479-20.06-14.312-20.06-10.553,3.532c-13.676-23.591-20.759-23.591-29.814-2.664
+ c-7.944-20.927-17.861-20.927-27.072,12.467c-12.039-33.395-23.373-33.395-23.148-1.581
+ c-22.89-31.814-34.224-31.814-61.517-8.479c6.042-23.335-3.874-23.335-11.9-9.703c-8.975-13.632-16.058-13.632-23.926,4.361
+ c-2.049-17.993-4.882-17.993-10.51-1.486c2.314-16.508-0.686-17.851-12.385-5.019c7.356-17.175,6.013-20.176-10.27-7.879
+ c16.283-15.61,16.283-19.824-9.255-12.972c25.538-20.334,25.538-29.603,1.919-46.578c23.619-3.249,23.619-14.204-0.313-25.522
+ c23.933-8.905,23.933-18.175,7.798-37.429C226.385,48.854,226.385,44.64,217.778,34.643z"/>
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/includes/js/dojox/gfx/demos/data/LarsDreaming.json b/includes/js/dojox/gfx/demos/data/LarsDreaming.json
new file mode 100644
index 0000000..d4cd1ad
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/LarsDreaming.json
@@ -0,0 +1,1823 @@
+[
+ {
+ "name": "torso",
+ "children": [
+ {
+ "name": "leftArm",
+ "shape": {
+ "type": "path",
+ "path": "M156.007,292.675c2.737,1.778,5.563,3.321,8.752,3.946c7.099,1.391,19.25-5.666,23.136-11.698 c1.572-2.441,8.077-21.031,11.178-14.271c1.224,2.67-1.59,4-1.399,6.462c3.108-1.425,5.48-5.242,8.918-2.182 c0.672,4.019-4.472,4.343-3.918,7.669c1.376,0.218,5.395-1.595,6.285-0.535c1.707,2.027-2.933,3.561-4.072,4.018 c-1.852,0.741-4.294,1.233-5.988,2.369c-2.636,1.769-4.766,5.144-7.033,7.4c-11.657,11.604-26.184,10.553-40.646,5.515 c-4.713-1.642-17.399-4.472-18.655-9.427c-1.647-6.502,5.523-7.999,10.184-6.74C147.658,286.528,151.725,289.892,156.007,292.675z"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "leftArmThumb",
+ "shape": {
+ "type": "path",
+ "path": "M188.257,284.902c-1.932-1.391-3.313-4.206-3.506-6.494c-0.149-1.786,0.59-6.521,3.199-3.95c0.792,0.78,0.083,2.155,0.558,2.943 c0.885,1.47,1.071,0.493,2.748,1.002c1.406,0.426,3.827,2.05,4.251,3.499"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "rightArm",
+ "shape": {
+ "type": "path",
+ "path": "M57.05,283.307c-5.502,5.354-13.185,8.541-18.249,14.221c-4.303,4.827-7.721,11.575-11.138,17.112 c-6.752,10.938-10.794,26.076-19.912,35.185c-3.869,3.866-7.637,5.722-7.251,12.032c0.932,0.372,1.548,0.589,2.418,0.683 c0.605-2.745,2.569-4.198,5.362-3.799c-0.14,3.365-3.512,5.941-3.228,9.235c0.364,4.223,3.983,5.968,7.181,2.662 c2.61-2.699,0.192-7.849,3.338-10.18c5.535-4.103,2.889,2.998,4.13,5.515c5.19,10.519,8.634-1.859,7.35-7.996 c-2.336-11.159-3.003-15.126,3.267-24.416c6.358-9.419,12.194-18.708,19.399-27.588c1.116-1.375,2.08-2.729,3.333-4"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "shirt",
+ "children": [
+ {
+ "name": "tShirt",
+ "shape": {
+ "type": "path",
+ "path": "M96.509,268.265 c-2.301,0.323-4.69,0.205-6.945,0.72c-2.234,0.509-4.5,0.8-6.749,1.249c-4.369,0.872-8.206,3.265-12.3,5.024 c-3.259,1.4-6.644,2.57-9.763,4.26c-1.923,1.041-3.688,2.616-5.487,3.97c-1.543,1.16-3.495,2.11-4.854,3.563 c-2.205,2.354,0.896,7.407,1.854,9.873c0.92,2.367,2.149,4.819,2.749,7.29c0.228,0.937,0.235,2.058,0.875,2.872 c0.644,0.821,0.64,0.735,1.822,0.049c1.513-0.878,2.873-1.993,4.329-2.993c2.431-1.67,5.462-2.849,7.434-5.111 c-3.335,1.652-5.335,4.679-6.931,8.012c-1.398,2.921-4.482,35.854-5.389,38.947c-0.195,0.003-0.775,0.003-0.749,0.013 c20.561,0,41.123-0.069,61.684,0c2.1,0.008,3.607-0.496,5.529-1.252c0.715-0.28,2.257-0.355,2.807-0.744 c1.412-0.998-0.094-3.916-0.646-5.303c-1.425-3.579-2.111-37.767-4.726-40.543c1.842,0.058,4.127,1.312,5.938,1.95 c1.351,0.478,2.633,1.092,3.956,1.66c1.39,0.597,3.667,1.927,5.168,1.857c0.296-1.872,1.045-3.285,1.839-5.02 c0.942-2.061,1.155-4.214,1.528-6.415c0.351-2.07,0.897-3.787,1.938-5.635c0.531-0.942,1.356-1.73,1.693-2.769 c-0.443-0.401-1.043-0.906-1.604-1.125c-0.56-0.219-1.292-0.11-1.908-0.33c-1.236-0.438-2.439-1.089-3.668-1.575 c-3.773-1.499-7.519-2.983-11.319-4.467c-3.575-1.396-6.977-3.238-10.784-3.871c-1.735-0.289-3.467-0.529-5.073-0.906"
+ },
+ "fill": "#4459A5",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round"
+ }
+ },
+ {
+ "name": "shirtNeck",
+ "shape": {
+ "type": "path",
+ "path": "M99.759,268.89 c-0.984,0.151-1.746-0.549-2.75-0.5c-1.369,0.065-1.649,0.872-2.153,2c-1.037,2.325-2.442,4.974,0.064,6.945 c2.53,1.991,6.964,1.718,9.829,0.804c1.616-0.517,3.045-1.24,3.825-2.867c0.508-1.062,0.935-2.771,0.149-3.598 c-0.231-0.243-0.562-0.376-0.84-0.534"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round"
+ }
+ },
+ {
+ "name": "shirtLogo",
+ "children": [
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M104.864,296.921c-0.151-0.004,7.101,0.409,7.052,0.403c0.132,0.028-0.172,0.633-0.021,0.632 c-0.226,0.028-7.244-0.454-7.28-0.464C104.657,297.519,104.776,296.904,104.864,296.921z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M90.071,295.919c-0.199,0.005,6.792,0.431,6.79,0.446c0.153,0.005-0.031,0.663,0.012,0.665 c0.272,0.016-6.79-0.471-6.875-0.459C89.881,296.561,89.796,295.899,90.071,295.919z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M84.407,306.477c0.2-0.159,0.322-1.04,0.254,0.057c-0.542-0.355-2.02,2.083-4.215,2.001 c-1.887-1.706-4.559-3.384-4.302-7.092c0.652-2.599,3.082-4.084,5.213-3.942c1.889,0.378,2.899,0.717,4,1.318 c-0.497,0.957-0.175,0.866-0.459,0.703c0.456-2.398,0.598-5.75,0.312-7.855c0.594-0.554,0.714,0.125,1.249,0.941 c0.502-0.727,0.509-1.425,0.875-0.571c-0.207,1.328-0.809,7.187-0.711,10.174c-0.126,2.798-0.375,4.354-0.051,4.985 c-0.718,0.613-0.667,1.006-0.981,1.381c-0.72-1.33-1.056-0.132-1.339-0.157C84.632,308.442,84.493,305.791,84.407,306.477z M81.186,307.177c2.403,0.206,3.734-2.164,3.841-4.223c0.269-2.72-0.896-5.104-3.198-5.04c-1.972,0.438-3.46,2.188-3.331,4.639 C78.171,306.266,79.847,306.962,81.186,307.177z"
+ },
+ "stroke": {
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M93.321,297.767c2.592,0.147,5.688,2.314,5.696,5.627c-0.611,4.576-3.69,5.316-6.158,5.581 c-2.68-0.76-5.708-1.872-5.413-6.472C88.086,299.395,90.653,297.875,93.321,297.767z M92.939,307.46 c2.531,0.735,3.706-1.297,3.666-3.935c0.114-2.219-0.641-4.584-3.389-4.896c-2.29-0.553-3.366,2.188-3.661,4.688 C89.339,305.265,89.934,307.95,92.939,307.46z"
+ },
+ "stroke": {
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M99.688,303.916c0.03-1.511,0.055-4.73,0.022-4.646c0.481-1.355,0.658-0.556,1.034-1.297 c0.263,1.473,0.653,0.326,1.186,0.065c-0.386,2.518-0.513,3.348-0.574,4.949c-0.068-0.47-0.128,2.28-0.238,2.188 c-0.055,1.935-0.036,2.201-0.047,4.219c-0.079,0.914-0.28,2.412-1.126,3.831c-0.61,1.212-1.73,1.146-3.24,1.651 c0.073-0.945-0.065-1.242-0.096-1.822c0.098,0.138,0.213,0.604,0.225,0.397c1.892,0.229,2.209-1.896,2.362-3.365 c0.042,0.304,0.512-6.934,0.415-7.062C99.73,302.637,99.75,303.179,99.688,303.916z M100.978,295.564 c0.717,0.14,1.11,0.61,1.099,1.156c0.052,0.552-0.595,0.993-1.286,1.015c-0.541-0.074-1.025-0.548-1.022-1.054 C99.813,296.084,100.292,295.644,100.978,295.564z"
+ },
+ "stroke": {
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M108.115,298.791c3.028-0.066,5.283,1.359,5.256,5.758c-0.264,3.479-3.366,4.63-5.883,5.119 c-2.429-0.033-5.619-2.24-5.16-5.811C102.322,300.085,105.715,298.846,108.115,298.791z M107.351,309.232 c2.675-0.132,3.839-2.333,3.841-4.497c0.246-2.344-0.263-4.833-2.923-5.396c-2.844,0.299-3.974,1.917-4.053,4.479 C104.136,306.655,104.854,308.372,107.351,309.232z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "heads",
+ "children": [
+ {
+ "name": "head1",
+ "children": [
+ {
+ "name": "leftEart",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M201.557,195.475 c7.734-4.547,16.592-5.012,18.405,4.443c2.43,12.659-3.317,13.328-14.598,13.328"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M211.711,203.09 c0.523,0.004,0.946-0.208,1.271-0.635"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M211.076,197.377 c3.062,3.013,5.489,5.624,4.442,10.155"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ }
+ ]
+ },
+ {
+ "name": "bgHairTop",
+ "shape": {
+ "type": "path",
+ "path": "M54.384,199.307c-5.253-4.402-7.511-11.061-15.779-10.632c3.449-1.277,7.116-2.397,10.911-2.666 c-2.873-1.397-5.865-2.575-8.231-4.718c3.986-1.119,11.47-1.817,14.864,0.75c-5.183-2.758-8.397-7.816-13.062-10.598 c6.014-0.643,12.377,0.978,18.022,2.265c-2.547-4.486-6.682-10.83-10.523-14.297c5.033,1.052,10.647,4.518,15.062,7.177 c-1.614-4.176-5.634-8.406-7.859-12.513c10.312-1.125,12.522,4.919,19.7,9.932c-0.412-0.127-1.114-0.113-1.527,0.015 c0.875-7.261,3.058-12.8,8.258-18.566c6.771-7.507,17.813-9.131,24.095-15.381c-4.699,1.821-4.518,23.765-4.875,28.955"
+ },
+ "fill": "#FFF471",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "bgHairLeft",
+ "shape": {
+ "type": "path",
+ "path": "M92.384,243.973c-6.334,7.929-12.601,12.241-22.465,15.361c3.65-1.263,7.735-5.859,7.695-9.928 c-2.208,0.218-4.49,0.605-6.498,1.098c1.244-1.098,2.087-3.239,3.198-4.396c-5.77,0.001-12.131,1.133-18.396,1.23 c5.013-2.81,10.665-3.25,12.398-9.247c-3.59,0.313-7.233,1.606-11.033,1.097c1.731-2.022,3.953-3.995,5.049-6.447 c-3.781,0.056-6.665,3.098-10.547,2.465c0.962-2.863,3.187-5.208,4.531-7.766c-5.59-0.273-11.658,2.45-17.732,2.564 c5.494-2.857,8.967-7.819,12.3-12.718c5.233-7.693,10.625-9.96,20.349-9.981c11.059-0.024,15.558,6.714,20.984,16 c2.786,4.767,7.249,14.375,0.832,18"
+ },
+ "fill": "#FFF471",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "bgHair",
+ "shape": {
+ "type": "path",
+ "path": "M142.384,255.307c2.984,6.076,3.567,11.855,10.531,14.6c-0.134-3.114-0.094-6.664,1.619-9.033 c1.604,1.969,3.122,4.211,5.048,5.698c-0.29-1.769,0.412-4.023,0.233-5.828c3.444,0.261,4.979,3.965,8.468,4.479 c0.065-2.78,0.427-5.151,0.868-7.813c2.687,0.2,4.768,1.565,7.132,2.997c0.452-4.921-0.409-10.579-0.667-15.666 c-5.795-0.756-12.291,2.827-17.899,3.899c-4.414,0.844-14.136,0.523-15.333,6"
+ },
+ "fill": "#FFF471",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "neck",
+ "shape": {
+ "type": "path",
+ "path": "M106.989,254.499c-2.932,6.063-4.613,11.997-8.947,17.138c7.288,10.194,16.311-10.9,15.183-17.026 c-1.926-1.138-3.928-1.589-6.236-1.38"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "headShape",
+ "shape": {
+ "type": "path",
+ "path": "M210.941,207.666c-0.844,3.985-2.081,7.982-3.77,11.783c-3.374,7.604-8.543,14.427-16.052,18.899 c-2.94,2.13-5.983,4.167-9.109,6.085c-25.013,15.342-55.353,23.08-82.254,10.57c-3.433-1.558-6.785-3.432-10.053-5.66 c-1.821-1.185-3.592-2.46-5.308-3.832c-1.715-1.373-3.375-2.842-4.972-4.412c-2.352-2.148-4.576-4.425-6.631-6.814 c-6.168-7.169-10.823-15.358-12.87-24.185c-0.649-3.284-0.84-6.634-0.5-9.975c4.48-13.743,14.22-24.364,26.109-32.149 c2.973-1.946,6.079-3.715,9.271-5.309c30.581-15.027,69.581-10.027,95.852,12.209c2.563,2.254,4.987,4.651,7.244,7.178 c4.513,5.054,8.354,10.626,11.312,16.64C210.178,201.505,210.798,204.497,210.941,207.666z"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "rightEar",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M64.857,195.606 c-6.59-7.181-15.047-10.664-19.467,3.676c-1.235,4.007-1.87,14.468,1.29,17.786c4.223,4.435,13.591,0.529,19.055-0.015"
+ },
+ "fill": "#FFE8B0",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M52.407,196.744 c-1.702,3.613-1.257,7.505-1.27,11.424"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M51.772,209.438 c-3.39-4.661,0.922-5.769,5.078-6.347"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ }
+ ]
+ },
+ {
+ "name": "fgHair",
+ "shape": {
+ "type": "path",
+ "path": "M90.384,154.64c8.453-11.353,15.678-13.458,28.581-15.915c-1.382,3.376-3.89,7.352-5.179,11.16 c5.01-1.816,9.571-6.545,15.218-8.413c11.355-3.755,23.853-1.903,35.671-2.213c-3.004,3.712-4.912,7.88-2.025,11.447 c5.855-2.212,13.369-6.871,19.635-6.646c0.263,4.561-0.024,9.278,0.201,13.841c3.509-1.201,6.015-3.04,8.276-5.148 c2.263-2.108,3.761-4.049,4.942-5.2c1.063,2.408,2.134,5.334,2.24,8.494c-0.183,3.462-0.866,6.794-2.66,9.291 c3.663,0.65,6.098-2.021,8.35-4.479c-0.655,4.349-3.164,8.604-3.851,13.013c2.178-0.072,4.382,0.216,6.367-0.48 c-1.39,3.093-3.069,7.287-6.616,8.414c-4.476,1.423-4.354-0.992-7.315-4.332c-4.892-5.518-9.773-6.791-15.872-9.464 c-6.585-2.887-10.982-6.47-17.963-8.219c-8.994-2.255-19.864-3.867-28.093-5.196c2.466,1.967,1.138,5.594,0.659,8.625 c-2.729-0.646-4.41-3.813-6.301-5.158c0.953,3.195,0.983,6.953-2.134,8.491c-6.145-5.226-9.199-9.721-17.527-11.647 c1,1.83,1.728,4.208,1.396,6.402c-0.751,4.971-0.289,3.134-3.836,2.466c-5.192-0.977-9.953-3.677-15.815-4.496 c3.292,2.002,5.469,5.017,7.418,8.21c-2.651,0.404-6.238,0.257-8.382,1.671c2.456,0.38,3.44,2.166,3.197,4.714 c-7.45,0.386-13.623,0.731-19.915,5.434"
+ },
+ "fill": "#FFF471",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "eyes",
+ "children": [
+ {
+ "name": "eyes1",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M123.163,176.668 c-5.066,1.17-9.01,7.888-13.666,10.335c-4.238,2.227-8.648,6.636-7.009,12.332c1.971,6.848,12.042,3.991,16.261,1.165 c5.282-3.539,9.59-8.517,12.006-14.524c1.523-3.787,2.568-7.272-1.509-9.391c-2.905-1.51-8.174-1.386-11.417-0.583"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M182.545,179.865 c-3.533,0.169-4.854-1.166-8.408-0.001c-3,0.983-6.239,1.936-8.852,3.743c-3.938,2.725-7.46,5.555-4.73,13.592 c1.974,5.811,8.791,7.571,14.656,6.667c5.537-0.854,9.078-4.977,11.408-10.007c3.666-7.918,0.942-11.639-6.742-13.659"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M108.829,183.668c-1.308-1.03-4.557,0.011-5.6-1.733 c-1.056-1.765,1.735-5.409,2.984-6.192c5.684-3.562,15.946-0.39,19.95-6.742"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M163.877,167.198c2.369,1.282,6.539,0.307,9.408,0.815 c3.449,0.612,7.065,2.657,10.592,2.851"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M127.496,192.002c-4.917-2.12-9.188-1.708-8.608,4.942 c3.132,1.734,5.428-2.82,7.275-4.942"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M174.852,203.144c-0.293,0.12-0.307,0.577-0.942,0.282 c-1.605-3.188-0.404-6.507,2.676-8.192c2.15-1.176,5.67-1.759,7.471,0.359c0.199,0.234,0.412,0.521,0.515,0.813 c0.229,0.649-0.285,0.95-0.285,0.95s-3.988,6.009-3.285,1.934c0.438,1.743-5.537,5.743-2.287,1.653 c-1.955,2.583-2.524,1.977-3.859,2.868"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "eyes2",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M98.668,186.108c0.668-8.915,15.545-13.749,22.667-15"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M169.667,178.108c5.307,3.436,16.928,5.632,19.668,12.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M105.334,197.775c8.085-4.283,17.059-2.8,25-6.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M164.001,198.775c4.656-0.417,9.664,1.805,14.334,2.017 c3.951,0.18,5.773,0.189,9,2.316"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M124.001,188.108c3.039-0.258,4.594,2.571,5.301,4.983 c-1.096,1.242-2.065,2.646-2.968,4.017"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M168.335,194.108c-1.77,2.293-4.869,3.271-6.299,5.91 c1.377,0.991,3.02,2.122,3.965,3.424"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "beard",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M96.05,213.64 c-0.366,0.21-0.783,0.389-1.167,0.5"
+ },
+ "fill": "#AFA8A5",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M102.55,211.973 c0.314-0.01,0.554-0.198,0.667-0.5"
+ },
+ "fill": "#AFA8A5",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M105.717,208.806 c0.164-0.109,0.336-0.224,0.5-0.333"
+ },
+ "fill": "#AFA8A5",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M111.05,207.973 c-0.651-1.81,0.859-2.262,2.333-1.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M117.717,209.806 c1.738,0,3.653,0.369,5.333,0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M132.717,214.473 c0.104-0.21,0.162-0.435,0.167-0.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M139.551,216.973 c0.215-0.175,0.465-0.426,0.666-0.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M144.551,213.306 c0.277-0.056,0.557-0.111,0.833-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M147.884,216.64 c0.195,0.045,0.369-0.013,0.5-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M148.384,214.14 c0.112-0.168,0.223-0.332,0.333-0.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M98.217,219.306c1.697-1.772,4.233-2.109,5.967-4.046c1.519-1.696,3.812-3.001,4.2-5.454"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M152.717,216.14 c0.611,0,1.224,0,1.834,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M160.384,217.473 c0.333,0,0.667,0,1,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M163.217,215.973 c0.321-0.042,0.658-0.175,0.834-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M164.217,218.806 c0.167,0,0.333,0,0.5,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M168.384,217.973 c0.057-0.056,0.111-0.111,0.167-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M169.884,225.806 c0.491-0.397,0.882-0.926,1.167-1.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M172.717,221.973 c0.057,0,0.111,0,0.167,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M171.717,229.806 c0.334,0.075,0.659,0.025,0.834-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M190.051,227.806 c0.163-0.242,0.398-0.423,0.666-0.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M197.384,221.473 c0.258-0.007,0.485-0.125,0.667-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M199.384,214.973 c-0.04-0.333,0.075-0.609,0.333-0.833"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M117.884,257.306 c0.056,0,0.111,0,0.167,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M142.717,252.473 c0.358,0.068,0.71,0.016,1-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M137.884,256.473 c0.277,0,0.557,0,0.833,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M160.884,252.973 c0.366-0.139,0.766-0.402,1-0.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M171.384,250.14 c0.235-0.264,0.476-0.562,0.667-0.834"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M89.384,243.973 c0.537,0.378,1.329,0.876,1.833,1.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M79.05,225.473 c0.087,0.272,0.143,0.55,0.167,0.833"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M73.884,222.64 c0,0.167,0,0.333,0,0.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#AAAAAA",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M72.55,219.806c0.466-0.325,0.875-0.797,1.167-1.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M71.717,211.973c0.422-0.553,0.776-1.305,1-2"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M78.55,214.473c0-0.111,0-0.222,0-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M79.384,218.806c-0.001-0.137,0.055-0.248,0.167-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M80.217,221.14c0.111,0,0.222,0,0.333,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M75.55,226.473c0.103-0.5,0.156-0.977,0.167-1.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M78.55,230.14c0.111,0,0.222,0,0.333,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M83.384,227.64c0.118-0.059,0.215-0.107,0.333-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M81.55,237.14c0.056,0,0.111,0,0.167,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M86.217,233.806c0.056,0,0.111,0,0.167,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M87.884,230.473c0.595-0.181,1.219-0.527,1.833-0.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M88.717,222.14 c-0.929,2.359-1.615,4.865-2.667,7.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M89.05,216.14 c0.784-0.736,1.709-1.565,2.833-1.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M94.217,210.14 c1.599-0.089,3.199-0.167,4.833-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M94.884,224.64 c0.052-0.588-0.004-1.155-0.167-1.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M92.384,228.306 c0.585-0.062,1.244-0.132,1.667-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M88.717,240.14 c0.111,0,0.222,0,0.333,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M95.884,243.306 c0.526,0.1,1.017-0.016,1.333-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M98.55,248.306 c0.069-0.24,0.265-0.926,0.333-1.166"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M96.55,249.806 c0.125,0.014,0.18-0.042,0.167-0.166"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M104.55,250.14 c0.01-0.238,0.126-0.428,0.333-0.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M106.884,251.973 c0.195,0.045,0.37-0.014,0.5-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M113.884,254.806 c0.758-0.586,1.595-1.171,2.382-1.774c0.072,0.376,0.418,0.686,0.48,1.079c0.833,0.265,1.624-0.021,1.638-0.971"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M122.217,254.64 c0.063-0.165,0.179-0.288,0.333-0.334"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M125.884,255.806 c1.13-0.745,2.783-0.962,3.667-2"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M132.217,255.973 c0.638-0.492,1.104-1.173,1.141-1.976c-1.11,0.063-1.449-0.888-1.475-1.857"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M129.717,249.306 c-0.045,0.153-0.168,0.271-0.333,0.334"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M136.551,252.306 c0.223,0,0.444,0,0.666,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M110.217,251.306 c0.056-0.057,0.111-0.11,0.167-0.166"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M140.717,251.806 c0.111,0,0.224,0,0.334,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M150.051,249.473 c0.111,0,0.223,0,0.333,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M143.217,255.473 c1.022-0.313,1.725-1.175,2.646-1.654c0.203,0.321,0.439,0.626,0.521,0.987"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M152.217,253.473 c0.165-0.063,0.288-0.179,0.334-0.333"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M155.051,254.64 c0.223,0,0.444,0,0.666,0"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M157.717,256.473 c0.326-0.027,0.546-0.073,0.834-0.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M163.217,252.64 c0.552-0.892,2.082-1.512,2.341-2.334c0.37-1.178-1.155-3.069-1.007-4.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M167.384,235.973 c0.118-0.54,0.354-1.064,0.667-1.5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M170.717,242.806 c0-0.333,0-0.667,0-1"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M170.217,236.973 c0-0.333,0-0.667,0-1"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M179.051,235.806 c0.378-0.101,0.738-0.35,1-0.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M185.051,232.806 c0.379-0.319,0.656-0.702,0.833-1.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M188.051,231.14 c0.063-0.39,0.178-0.792,0.333-1.167"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M197.884,223.306 c-0.166,0.277-0.334,0.556-0.5,0.833"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ }
+ ]
+ },
+ {
+ "name": "mouths",
+ "children": [
+ {
+ "name": "mouth1",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M177.122,216.821c-0.515,2.282-5.213,3.21-7.434,3.854 c-3.254,0.945-6.596,1.345-9.895,1.851c-3.26,0.5-6.665,0.671-10.107,0.671c-3.596,0-6.645,0.559-10.106,0.671 c-3.105,0.1-6.898-0.474-9.694-1.3c-3.527-1.043-6.672-1.666-10.096-3.062c-2.823-1.152-5.746-1.876-8.462-3.143 c-2.594-1.209-6.084-1.994-8.221-3.552c-1.068,1.834-5.867,3.748-8.1,4.546c-2.444,0.874-8.881,2.725-7.817,5.512 c0.457,1.195,1.948,2.273,2.63,3.385c0.774,1.261,1.139,2.601,2.057,3.859c1.83,2.5,4.506,4.773,6,7.34 c1.308,2.249,2.096,4.74,4.01,6.669c2.214,2.233,5.792,2.635,9.231,2.399c7.028-0.479,13.982-2.129,20.481-3.983 c3.295-0.941,6.699-1.536,10.086-2.686c3.272-1.111,6.642-3,9.402-4.777c5.248-3.377,10.278-6.409,14.283-10.705 c1.479-1.587,3.429-2.503,5.149-3.859"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M135.25,241.319 c0.723-4.757-10.487-8.47-14.898-9.526c-3.09-0.74-6.68-1.17-9.858-1.712c-2.758-0.47-6.865-0.836-9.437,0.369 c-1.385,0.649-2.843,1.724-4.141,2.513c2.156,3.964,4.728,8.861,9.468,11.506c3.229,1.801,5.511,0.776,8.859,0.373 c3.045-0.369,6.046-0.703,9.029-1.721c3.479-1.186,7.228-2.385,10.978-2.475"
+ },
+ "fill": "#FFC0C0",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M148.656,225.547c1.267,0.697,1.301,2.838,0.671,3.9 c-0.702,1.182-2.063,1.4-3.307,2.01c-2.271,1.116-4.58,2.624-7.481,2.638c-4.619,0.023-2.144-4.067-0.253-5.869 c2.405-2.292,5.057-2.72,8.72-2.512c0.588,0.034,1.095,0.041,1.65,0.168"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M130.299,223.365 c2.687,0.437,5.619,4.384,3.727,6.422c-1.234,1.33-7.94,1.391-9.915,1.296c-4.896-0.233-2.502-2.445-0.613-4.525 c1.604-1.767,5.088-3.249,7.833-3.36"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M113.178,217.157 c2.56,0.958,4.922,5.057,5.352,7.215c0.377,1.885-0.324,2.106-2.526,2.643c-1.366,0.333-3.636,0.723-5.105,0.385 c-2.506-0.577-5.883-5.051-4.909-7.223c1.03-2.298,5.944-2.923,8.427-2.852"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M99.359,217.662 c2.038,0.432,4.015,4.279,2.468,5.625c-1.083,0.943-5.221,1.795-6.799,1.589c-4.032-0.526-2.265-4.102-0.866-5.872 c0.706-0.894,1.049-1.976,2.514-2.186c1.627-0.233,2.501,0.99,3.921,1.346"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M181.815,222.896c-3.102-2.75-4.765-8.777-9.282-10.403"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "mouth2",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M87.57,221.951c5.563-1.759,11.066-1.32,16.694-1.782c2.93-0.24,5.228-1.14,8.309-0.927c3.142,0.217,6.085-0.235,9.289,0.176 c7.136,0.914,13.96,0.598,21.112,1.506c3.654,0.464,7.219,0.609,10.811,0.869c4.017,0.291,7.646,1.582,11.433,2.623 c2.948,0.812,6.347,1.618,9.011,2.99c2.521,1.298,6.354,2.856,8.301,4.72c-2.775,0.027-5.602,2.603-8.021,3.769 c-2.93,1.412-5.741,2.949-8.656,4.432c-5.599,2.849-11.885,5.468-18.104,6.53c-6.793,1.161-13.195,2.107-20.067,2.197 c-7.699,0.102-14.313-4.705-20.735-8.396c-2.071-1.19-4.69-2.182-6.504-3.666c-1.792-1.466-3.469-3.386-5.154-4.984 c-2.703-2.564-7.519-5.649-8.13-9.438"
+ },
+ "stroke": {
+ "color": "#000000",
+ "width": "3",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M87.785,228.193 c-5.907-3.235-0.344-9.531,3.971-11.424"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M184.679,227.229c-1.534,2.583-2.548,5.334-4.024,7.889"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "width": "2",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M106.862,219.528 c-3.071-0.74-5.608,2.166-6.318,4.738c-0.379,1.375-0.494,2.55,0.748,3.337c1.519,0.962,2.905-0.052,4.418-0.332 c2.518-0.467,7.293,0.053,6.461-4.248c-0.568-2.938-3.743-3.682-6.338-3.335c-0.451,0.06-0.758,0.212-1.205,0.229"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M119.764,218.479 c-2.648,1.243-4.657,3.518-5.346,6.377c-0.866,3.594,3.9,3.711,6.356,2.865c2.64-0.91,4.77-3.351,3.299-6.133 c-1.01-1.91-3.979-2.548-6.026-2.823"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M130.388,219.492 c-1.753,1.382-4.069,4.525-4.835,6.61c-1.159,3.156,2.296,3.371,4.868,3.348c3.061-0.028,6.6-1.148,5.022-4.78 c-1.168-2.691-2.552-4.85-5.551-5.241"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M142.954,221.087 c-1.502,0.337-5.418,3.249-5.638,4.997c-0.292,2.311,4.855,4.536,6.854,4.234c2.503-0.377,4.384-3.175,3.167-5.65 c-0.92-1.873-3.36-2.252-4.508-3.932"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M155.354,222.664 c-2.038,0.426-4.212,2.287-4.766,4.444c-0.723,2.821,3.226,3.383,5.458,3.331c2.541-0.059,5.126-1.752,3.249-4.32 c-1.394-1.908-3.707-3.189-5.304-4.636"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M168.367,237.924 c-1.554-1.217-3.302-2.557-5.203-2.976c-2.973-0.654-3.537,2.131-3.377,4.406c0.205,2.913,1.032,3.883,3.901,2.344 c1.987-1.066,4.271-1.997,4.599-4.456"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M151.524,246.202 c-1.912-0.166-4.004-4.491-2.91-6.25c0.771-1.239,5.456-1.688,6.857-1.292c0.271,0.917,0.979,1.841,0.829,2.771 c-0.088,0.54-0.994,1.645-1.296,2.188c-1.08,1.951-2.133,1.866-3.998,2.685"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M145.911,241.458 c-0.209,1.649-0.215,2.702-1.528,3.801c-0.885,0.738-1.772,1.189-2.54,2.1c-0.786,0.933-1.226,2.38-2.792,1.813 c-1.042-0.377-1.959-2.318-2.138-3.312c-0.299-1.676-1.003-5.228,0.783-6.158c1.154-0.603,7.066-0.18,7.43,1.32"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M133.12,238.991 c-1.495-0.087-2.253-1.33-3.918-0.964c-1.42,0.311-2.489,1.354-2.54,2.836c-0.052,1.527,0.99,5.581,1.852,6.956 c2.363,3.771,4.329-1.535,5.516-3.159c1.117-1.525,2.643-2.053,2.271-3.958c-0.318-1.632-1.118-2.047-2.766-2.329 c-0.382-0.065-0.773-0.095-1.158-0.147"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M116.853,237.43 c-1.049,2.211-0.173,5.147,0.047,7.565c0.357,3.93,3.827,2.028,5.831,0.067c1.575-1.541,4.599-4.86,2.209-6.484 c-1.881-1.279-5.727-2.458-7.756-1.107"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M107.455,233.38 c-0.813,2.487-1.704,5.049,0.073,7.364c1.91,2.486,4.009,1.229,5.537-0.939c1.056-1.5,3.316-4.481,1.563-6.017 c-1.347-1.179-6.468-1.518-7.854-0.325"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "mouth3",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M99.05,218.973c1.691-0.875,3.313-2.39,4.833-3.537c1.231-0.928,2.782-1.671,3.5-3.072c1.846,3.486,7.661,4.669,11.003,6.067 c3.553,1.486,7.174,3.066,10.784,4.166c4.271,1.301,9.277,1.67,13.721,2.343c4.155,0.629,9.979,1.365,14.162,0.496 c1.182-0.245,2.343-1.024,3.462-1.446c0.162,1.905-3.637,3.023-4.933,3.487c-2.435,0.871-4.18,2.541-6.362,3.871 c-1.623,0.989-2.974,1.669-4.755,2.117c-1.77,0.445-3.353,0.806-4.825,1.878c-5.915,4.311-15.264,3.247-22.424,3.13 c-5.384-0.088-6.719-5.372-9.337-9c-1.437-1.991-2.843-3.854-3.796-6.138c-0.871-2.086-1.119-4.582-2.033-6.528"
+ },
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M107.217,227.973c1.182-2.033,4.375-2.176,6.5-1.963c2.879,0.289,4.124,1.217,6.168,3.167c1.834,1.749,5.906,5.509,5.64,8.271 c-2.808,0.89-7.847,0.402-10.346-1.104c-1.334-0.804-1.151-2.256-2.246-3.588c-0.712-0.866-1.836-2.673-2.855-3.311 c-0.209-0.94-2.106-1.499-3.028-1.805"
+ },
+ "fill": "#F4BDBD",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "personalProps",
+ "children": [
+ {
+ "name": "hat",
+ "children": [
+ {
+ "children": [
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M88.374,173.145c0.474-0.074,16.606,2.725,18.01,5.879 c1.145,2.572,28.184,4.568,28.184,4.568l35.971-5.618l5.024,1.132l7.212,0.315l9.295,0.851l10.188,3.248l5.75,2.935 l1.615-1.832l-0.264-5.27l-3.968-7.087c0,0-22.045-13.031-23.272-13.703c-1.229-0.669-4.941-2.294-6.484-4.542 c-8.584-12.528-8.403-18.05-3.371-6.461c0,0,2.662-7.592,2.521-8.575c-0.144-0.982,0.354-5.031,0.354-5.031l2.396-6.832 c0,0-1.379-5.341-2.738-7.19c-1.356-1.844-15.793-4.078-18.162-4.011c-24.933,0.706-3.783,0.071-25.567,0.724 c-24.317,0.728-0.882-2.591-24.068,3.551c-24.228,6.418-5.35-1.298-23.187,6.142c-18.301,7.633-16.67,7.186-16.704,10.685 c-0.034,3.499-3.057-4.884-0.034,3.499c3.023,8.381,3.037-3.871,3.023,8.381c-0.015,12.252,6.696,4.557,1.678,12.373 c-5.017,7.813-3.831,7.91-0.179,8.543c17.017,2.953,4.157,4.378,17.427,3.175"
+ },
+ "fill": "#FF0000",
+ "stroke": {
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M156.604,114.92l-13.936,0.381l-11.633,0.343c-10.646,0.319-11.973-0.155-12.021-0.175l-0.599-0.238 l-0.577,0.514l0.049-0.047c-0.118,0.09-1.43,0.957-11.145,3.53c-9.989,2.646-12.812,2.931-13.421,2.704 c-0.822-0.306-0.821-0.306-7.791,2.604l-2.104,0.878c-16.037,6.689-17.342,7.324-17.342,10.316c0,0.019,0.001,0.041,0.001,0.06 c-0.224-0.108-0.459-0.199-0.787-0.04c-0.357,0.173-0.565,0.275-0.565,0.672c0,0.557,0.411,1.697,1.399,4.438 c0.924,2.561,1.71,3.671,2.714,3.833c0.083,0.014,0.164,0.02,0.241,0.02c0.007,0.584,0.01,1.339,0.01,2.313 c0,0.561-0.001,1.902-0.001,1.916c0,6.908,2.176,8.105,3.347,8.749c0,0,0.075,0.045,0.151,0.09 c-0.095,0.332-0.47,1.1-1.661,2.955c-2.509,3.908-3.516,5.931-3.516,7.303c0,0.358,0.068,0.671,0.196,0.962 c0.544,1.237,1.926,1.477,3.677,1.78l0.135,0.023c8.138,1.412,9.14,2.422,9.568,2.854c0.923,0.931,1.511,0.928,7.224,0.413 c0.06,0.014,0.102,0.068,0.165,0.071c2.167,0.105,16.131,3.138,17.087,5.288c1.147,2.578,16.416,4.228,29.023,5.159 l0.115,0.009c0,0,35.523-5.548,35.896-5.606c0.345,0.078,4.927,1.11,4.927,1.11l7.301,0.319c0,0,8.927,0.818,9.139,0.837 c0.202,0.064,9.854,3.142,10.006,3.19c0.143,0.073,6.368,3.251,6.368,3.251l2.397-2.719l-0.296-5.911l-4.213-7.526 l-0.231-0.137c-0.9-0.532-22.073-13.047-23.304-13.72c-0.001,0-0.734-0.38-0.734-0.38c-1.48-0.752-4.238-2.151-5.404-3.85 c-1.357-1.982-2.451-3.729-3.354-5.268c0.021-0.064,0.104-0.296,0.104-0.296c1.193-3.402,2.576-7.619,2.576-8.885 c0-0.063-0.004-0.118-0.011-0.165c-0.013-0.083-0.018-0.204-0.018-0.356c0-0.909,0.194-2.911,0.363-4.307 c0.072-0.205,2.46-7.013,2.46-7.013l-0.076-0.294c-0.146-0.566-1.468-5.584-2.9-7.532 C173.721,116.784,158.242,114.875,156.604,114.92z M131.097,117.644l11.614-0.342l13.951-0.382 c2.575-0.073,16.104,2.238,17.336,3.614c0.956,1.3,2.058,4.938,2.49,6.549c-0.188,0.536-2.33,6.642-2.33,6.642l-0.014,0.107 c-0.072,0.592-0.387,3.224-0.387,4.658c0,0.258,0.011,0.477,0.034,0.639c-0.006,0.493-0.768,3.026-1.659,5.709 c-2.14-4.566-2.792-4.606-3.242-4.629l-0.62-0.031l-0.354,0.571c-0.069,0.124-0.102,0.29-0.102,0.492 c0,2.273,4.134,9.172,6.992,13.346c1.456,2.12,4.51,3.669,6.149,4.501l0.682,0.353c1.139,0.622,20.813,12.25,23.012,13.549 c0.238,0.427,3.513,6.275,3.721,6.647c0.02,0.393,0.199,3.971,0.23,4.629c-0.229,0.262-0.472,0.535-0.832,0.944 c-1.069-0.546-5.132-2.619-5.132-2.619l-10.369-3.306l-9.403-0.86c0,0-6.995-0.307-7.169-0.315 c-0.168-0.038-5.124-1.155-5.124-1.155s-35.814,5.594-36.044,5.63c-12.419-0.922-25.993-2.687-27.285-4.058 c-1.366-3.097-13.245-5.574-17.517-6.211c-0.203-0.212-0.479-0.346-0.793-0.318c-3.083,0.28-5.996,0.544-6.4,0.369 c0-0.003-0.12-0.117-0.12-0.117c-0.703-0.708-1.879-1.895-10.646-3.416l-0.135-0.023c-0.827-0.143-2.075-0.359-2.188-0.614 c-0.021-0.048-0.033-0.111-0.033-0.193c0-0.592,0.632-2.179,3.205-6.187c1.488-2.318,2.024-3.388,2.024-4.188 c0-0.15-0.019-0.291-0.054-0.428c-0.181-0.712-0.758-1.03-1.179-1.261c-0.865-0.476-2.311-1.271-2.311-6.993 c0-0.014,0.001-1.098,0.001-1.56c0-4.969-0.065-4.992-0.833-5.258c-0.424-0.146-0.816,0.001-1.178,0.377 c-0.208-0.289-0.558-0.898-1.073-2.324c-0.205-0.568-0.385-1.068-0.542-1.506c0.587-0.423,0.632-1.277,0.636-1.644 l-0.014-0.825c-0.004-0.119-0.007-0.231-0.007-0.338c0-1.702,0.899-2.264,16.109-8.608l2.105-0.878 c4.165-1.739,5.948-2.482,6.375-2.562c0.817,0.296,2.292,0.597,14.579-2.658c8.169-2.164,10.697-3.187,11.58-3.704 C120.451,117.773,124.529,117.84,131.097,117.644z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M155.146,147.93c4.88-9.398-5.344-20.199-12.649-21.176 c-12.05-1.61-13.404,10.426-13.684,21.258c3.73,2.016,8.915,3.425,11.721,6.534"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M133.446,127.979c-4.599,3.921-5.426,11.933-5.635,20.006l-0.017,0.654l4.415,2.067 c2.849,1.244,5.793,2.529,7.581,4.509c0.371,0.41,1.004,0.442,1.412,0.072c0.219-0.197,0.33-0.469,0.33-0.743 c0-0.239-0.084-0.479-0.258-0.67c-2.076-2.299-5.223-3.673-8.267-5.001c0,0-2.377-1.112-3.174-1.486 c0.223-7.385,1.021-14.572,4.909-17.887c1.892-1.614,4.386-2.189,7.621-1.757c4.143,0.554,9.086,4.472,11.5,9.113 c1.348,2.591,2.51,6.535,0.395,10.611c-0.254,0.49-0.063,1.093,0.426,1.348c0.49,0.254,1.095,0.063,1.351-0.427 c1.959-3.775,1.817-8.199-0.396-12.456c-2.731-5.251-8.203-9.53-13.012-10.172C138.853,125.257,135.763,126,133.446,127.979z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M154.077,146.278c-2.156,1.18-4.24,2.619-6.256,4.01c-3.636,2.509-7.068,4.878-10.941,5.924 c-2.991,0.808-6.055,1.058-9.3,1.324c-3.222,0.263-6.553,0.536-9.783,1.406c-2.027,0.546-4.117,1.397-6.137,2.221 c-3.491,1.423-7.102,2.895-10.528,2.866c-0.552-0.005-1.004,0.439-1.009,0.991c-0.005,0.552,0.439,1.004,0.991,1.009 c3.828,0.033,7.627-1.516,11.301-3.014c2.054-0.837,3.994-1.628,5.902-2.142c3.054-0.823,6.292-1.088,9.425-1.344 c3.191-0.261,6.492-0.531,9.659-1.386c4.205-1.135,7.94-3.714,11.557-6.208c1.973-1.362,4.014-2.771,6.08-3.901 c0.484-0.265,0.662-0.873,0.396-1.357C155.168,146.193,154.562,146.014,154.077,146.278z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M156.458,153.549c-2.619,0.064-5.709,0.812-8.98,1.604c-4.278,1.035-8.7,2.104-11.901,1.536 c-0.543-0.096-1.063,0.267-1.159,0.81c-0.097,0.544,0.267,1.063,0.81,1.16c3.613,0.641,8.24-0.481,12.72-1.562 c3.166-0.766,6.153-1.489,8.561-1.548c5.664-0.141,7.961,0.698,13.508,2.724c0.519,0.189,1.095-0.077,1.281-0.596 c0.189-0.519-0.076-1.091-0.596-1.282C165.069,154.337,162.501,153.399,156.458,153.549z"
+ },
+ "stroke": {
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "textSurface",
+ "children": [
+ {
+ "name": "spokenBubble",
+ "children": [
+ {
+ "name": "textContainer",
+ "shape": {
+ "type": "path",
+ "path": "M225.719,45.307 c0-6.627,5.373-12,12-12h181.333c6.627,0,12,5.373,12,12v105.334c0,6.627-5.373,12-12,12H237.719c-6.627,0-12-5.373-12-12 V45.307z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "textArrowBelow",
+ "shape": {
+ "type": "path",
+ "path": "M249.052,160.64 c-0.774,14.251-1.676,18.525-9.1,30.565c9.705-0.79,21.952-21.605,25.1-30.045"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "thoughtBubble",
+ "children": [
+ {
+ "name": "textContainer_1_",
+ "shape": {
+ "type": "path",
+ "path": "M202.698,21.089 c19.686-26.45,59.686-24.45,79.747-0.084c2.696,1.349,5.57,1.709,7.472,0.781c15.28-13.888,33.271-14.043,49.893-7.839 c2.771,1.034,5.479,2.219,8.031,3.421C376.384-4.36,423.384,6.64,431.007,45.026c0,0-1.324,3.889,1.165,6.603 c18.212,11.011,26.212,32.011,22.212,53.011c-1,5.333-3.223,9.667-6.037,13.52c-2.813,3.854-1.381,0-2.612-0.591 c-1.351-0.929-3.351-0.929-4.351-1.929c16,7,27,22,30,39c2,21-8,41-27,50c-16,7.5-32.5,5.5-45.745-2.556 c-2.531-1.384-4.229-1.856-5.336-1.551c-1.919,0.107-3.919,2.107-5.919,2.107c4-1,6-5,10-6c-15,11-35,12-52,3c-13-7-20-20-24-34 c1,5,3,9,3.299,13.505c-0.396,0.708-3.423,2.219-6.654,3.466c-22.627,8.729-49.423,1.729-65.241-19.971 c-3.453,0-6.263,0.589-8.723,0.879c-17.301,3.2-32.382-7.709-40.771-22.689c-1.678-2.996-3.089-6.153-4.195-9.396 c-15.714-7.795-29.714-18.795-33.714-37.795c-5-25,11-45,29.842-57.667c0.72-2.335,1.697-4.636,3.007-6.896 C201.159,23.307,202.698,21.089,202.698,21.089z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M269.719,186.307c0,4.602-4.179,8.333-9.333,8.333s-9.334-3.731-9.334-8.333 c0-4.603,4.18-8.333,9.334-8.333S269.719,181.705,269.719,186.307z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ }
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M269.719,186.307c0,4.602-4.179,8.333-9.333,8.333s-9.334-3.731-9.334-8.333 c0-4.603,4.18-8.333,9.334-8.333S269.719,181.705,269.719,186.307z"
+ },
+ "fill": "none",
+ "stroke": {
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M268.225,186.166c-0.563,8.736-13.981,9.286-15.633,0.853 c-1.785-9.125,15.018-10.254,15.649-0.451c0.125,1.929,3.078,1.388,2.955-0.521c-0.814-12.597-20.828-12.412-21.64,0.119 c-0.827,12.813,20.831,13.028,21.655,0.283C271.337,184.519,268.35,184.235,268.225,186.166z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M260.386,188.307c0,3.498-2.984,6.333-6.667,6.333 c-3.682,0-6.667-2.835-6.667-6.333s2.985-6.333,6.667-6.333C257.401,181.974,260.386,184.809,260.386,188.307z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M238.386,196.974c0,1.289-1.045,2.333-2.334,2.333 c-1.288,0-2.333-1.045-2.333-2.333c0-1.288,1.045-2.333,2.333-2.333C237.341,194.64,238.386,195.685,238.386,196.974z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M285.719,179.974c0,4.602-4.253,8.333-9.5,8.333 s-9.5-3.731-9.5-8.333c0-4.603,4.253-8.333,9.5-8.333S285.719,175.372,285.719,179.974z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "yellBubble",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M251.156,176.051l40.228-15.992"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M280.932,149.385l-40.667,36.42"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000",
+ "cap": "round",
+ "join": "bevel"
+ }
+ },
+ {
+ "name": "textContainer_2_",
+ "shape": {
+ "type": "path",
+ "path": "M217.778,34.644 c8.608,6.684,9.951,3.684,7.986-5.785c6.309,5.125,9.309,3.782,10.188-4.309c2.433,8.091,5.266,8.091,9.12-1.703 c6.063,9.793,13.146,9.793,24.043,3.878c6.103,5.915,16.02,5.915,20.094-4.64c17.178,10.555,28.511,10.555,45.233-5.505 c5.94,16.06,17.272,16.06,18.835,1.458c19.688,14.603,29.604,14.603,46.749-17.802c-0.145,32.405,6.938,32.405,29.26,16.182 c-12.403,16.223-9.57,16.223,4.813,6.576c-11.069,9.646-8.069,10.99,4.333,9.089c-8.061,6.244-6.717,9.244,2.533,11.068 c-9.25,1.489-9.25,5.703-0.314,13.07c-8.936,6.115-8.936,15.385,7.513,10.932c-16.447,24.677-16.447,35.631,14.938,36.553 c-31.385,19.303-31.385,28.571-4.39,40.526c-26.995,1.528-26.995,5.741-5.942,17.857c-21.053-8.801-22.396-5.802-9.525,11.916 c-17.213-13.374-20.213-12.03-12.048,8.029c-11.479-20.06-14.313-20.06-10.554,3.532c-13.676-23.591-20.759-23.591-29.813-2.664 c-7.944-20.927-17.861-20.927-27.072,12.467c-12.039-33.395-23.373-33.395-23.147-1.581 c-22.891-31.814-34.225-31.814-61.518-8.479c6.042-23.335-3.874-23.335-11.899-9.703c-8.976-13.632-16.059-13.632-23.927,4.361 c-2.049-17.993-4.882-17.993-10.51-1.486c2.314-16.508-0.686-17.851-12.385-5.019c7.355-17.175,6.013-20.176-10.271-7.879 c16.283-15.61,16.283-19.824-9.255-12.972c25.538-20.334,25.538-29.603,1.919-46.578c23.619-3.249,23.619-14.204-0.313-25.522 c23.933-8.905,23.933-18.175,7.798-37.429C226.385,48.854,226.385,44.641,217.778,34.644z"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+] \ No newline at end of file
diff --git a/includes/js/dojox/gfx/demos/data/LarsDreaming.svg b/includes/js/dojox/gfx/demos/data/LarsDreaming.svg
new file mode 100644
index 0000000..3f4b903
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/LarsDreaming.svg
@@ -0,0 +1,536 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/">
+ <g id="torso" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F008000FFFF">
+ <path id="leftArm" i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M156.007,292.675c2.737,1.778,5.563,3.321,8.752,3.946c7.099,1.391,19.25-5.666,23.136-11.698
+ c1.572-2.441,8.077-21.031,11.178-14.271c1.224,2.67-1.59,4-1.399,6.462c3.108-1.425,5.48-5.242,8.918-2.182
+ c0.672,4.019-4.472,4.343-3.918,7.669c1.376,0.218,5.395-1.595,6.285-0.535c1.707,2.027-2.933,3.561-4.072,4.018
+ c-1.852,0.741-4.294,1.233-5.988,2.369c-2.636,1.769-4.766,5.144-7.033,7.4c-11.657,11.604-26.184,10.553-40.646,5.515
+ c-4.713-1.642-17.399-4.472-18.655-9.427c-1.647-6.502,5.523-7.999,10.184-6.74C147.658,286.528,151.725,289.892,156.007,292.675z
+ "/>
+ <path id="leftArmThumb" i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M188.257,284.902c-1.932-1.391-3.313-4.206-3.506-6.494c-0.149-1.786,0.59-6.521,3.199-3.95c0.792,0.78,0.083,2.155,0.558,2.943
+ c0.885,1.47,1.071,0.493,2.748,1.002c1.406,0.426,3.827,2.05,4.251,3.499"/>
+ <path id="rightArm" i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M57.05,283.307c-5.502,5.354-13.185,8.541-18.249,14.221c-4.303,4.827-7.721,11.575-11.138,17.112
+ c-6.752,10.938-10.794,26.076-19.912,35.185c-3.869,3.866-7.637,5.722-7.251,12.032c0.932,0.372,1.548,0.589,2.418,0.683
+ c0.605-2.745,2.569-4.198,5.362-3.799c-0.14,3.365-3.512,5.941-3.228,9.235c0.364,4.223,3.983,5.968,7.181,2.662
+ c2.61-2.699,0.192-7.849,3.338-10.18c5.535-4.103,2.889,2.998,4.13,5.515c5.19,10.519,8.634-1.859,7.35-7.996
+ c-2.336-11.159-3.003-15.126,3.267-24.416c6.358-9.419,12.194-18.708,19.399-27.588c1.116-1.375,2.08-2.729,3.333-4"/>
+ <g id="shirt" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFF4F00">
+ <path id="tShirt" i:knockout="Off" fill="#4459A5" stroke="#000000" stroke-linecap="round" d="M96.509,268.265
+ c-2.301,0.323-4.69,0.205-6.945,0.72c-2.234,0.509-4.5,0.8-6.749,1.249c-4.369,0.872-8.206,3.265-12.3,5.024
+ c-3.259,1.4-6.644,2.57-9.763,4.26c-1.923,1.041-3.688,2.616-5.487,3.97c-1.543,1.16-3.495,2.11-4.854,3.563
+ c-2.205,2.354,0.896,7.407,1.854,9.873c0.92,2.367,2.149,4.819,2.749,7.29c0.228,0.937,0.235,2.058,0.875,2.872
+ c0.644,0.821,0.64,0.735,1.822,0.049c1.513-0.878,2.873-1.993,4.329-2.993c2.431-1.67,5.462-2.849,7.434-5.111
+ c-3.335,1.652-5.335,4.679-6.931,8.012c-1.398,2.921-4.482,35.854-5.389,38.947c-0.195,0.003-0.775,0.003-0.749,0.013
+ c20.561,0,41.123-0.069,61.684,0c2.1,0.008,3.607-0.496,5.529-1.252c0.715-0.28,2.257-0.355,2.807-0.744
+ c1.412-0.998-0.094-3.916-0.646-5.303c-1.425-3.579-2.111-37.767-4.726-40.543c1.842,0.058,4.127,1.312,5.938,1.95
+ c1.351,0.478,2.633,1.092,3.956,1.66c1.39,0.597,3.667,1.927,5.168,1.857c0.296-1.872,1.045-3.285,1.839-5.02
+ c0.942-2.061,1.155-4.214,1.528-6.415c0.351-2.07,0.897-3.787,1.938-5.635c0.531-0.942,1.356-1.73,1.693-2.769
+ c-0.443-0.401-1.043-0.906-1.604-1.125c-0.56-0.219-1.292-0.11-1.908-0.33c-1.236-0.438-2.439-1.089-3.668-1.575
+ c-3.773-1.499-7.519-2.983-11.319-4.467c-3.575-1.396-6.977-3.238-10.784-3.871c-1.735-0.289-3.467-0.529-5.073-0.906"/>
+ <path id="shirtNeck" i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" d="M99.759,268.89
+ c-0.984,0.151-1.746-0.549-2.75-0.5c-1.369,0.065-1.649,0.872-2.153,2c-1.037,2.325-2.442,4.974,0.064,6.945
+ c2.53,1.991,6.964,1.718,9.829,0.804c1.616-0.517,3.045-1.24,3.825-2.867c0.508-1.062,0.935-2.771,0.149-3.598
+ c-0.231-0.243-0.562-0.376-0.84-0.534"/>
+ <g id="shirtLogo" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F004F00FFFF">
+ <g i:knockout="Off">
+ <path i:knockout="Off" d="M104.864,296.921c-0.151-0.004,7.101,0.409,7.052,0.403c0.132,0.028-0.172,0.633-0.021,0.632
+ c-0.226,0.028-7.244-0.454-7.28-0.464C104.657,297.519,104.776,296.904,104.864,296.921z"/>
+ </g>
+ <g i:knockout="Off">
+ <path i:knockout="Off" d="M90.071,295.919c-0.199,0.005,6.792,0.431,6.79,0.446c0.153,0.005-0.031,0.663,0.012,0.665
+ c0.272,0.016-6.79-0.471-6.875-0.459C89.881,296.561,89.796,295.899,90.071,295.919z"/>
+ </g>
+ <path i:knockout="Off" d="M84.407,306.477c0.2-0.159,0.322-1.04,0.254,0.057c-0.542-0.355-2.02,2.083-4.215,2.001
+ c-1.887-1.706-4.559-3.384-4.302-7.092c0.652-2.599,3.082-4.084,5.213-3.942c1.889,0.378,2.899,0.717,4,1.318
+ c-0.497,0.957-0.175,0.866-0.459,0.703c0.456-2.398,0.598-5.75,0.312-7.855c0.594-0.554,0.714,0.125,1.249,0.941
+ c0.502-0.727,0.509-1.425,0.875-0.571c-0.207,1.328-0.809,7.187-0.711,10.174c-0.126,2.798-0.375,4.354-0.051,4.985
+ c-0.718,0.613-0.667,1.006-0.981,1.381c-0.72-1.33-1.056-0.132-1.339-0.157C84.632,308.442,84.493,305.791,84.407,306.477z
+ M81.186,307.177c2.403,0.206,3.734-2.164,3.841-4.223c0.269-2.72-0.896-5.104-3.198-5.04c-1.972,0.438-3.46,2.188-3.331,4.639
+ C78.171,306.266,79.847,306.962,81.186,307.177z"/>
+ <path i:knockout="Off" d="M93.321,297.767c2.592,0.147,5.688,2.314,5.696,5.627c-0.611,4.576-3.69,5.316-6.158,5.581
+ c-2.68-0.76-5.708-1.872-5.413-6.472C88.086,299.395,90.653,297.875,93.321,297.767z M92.939,307.46
+ c2.531,0.735,3.706-1.297,3.666-3.935c0.114-2.219-0.641-4.584-3.389-4.896c-2.29-0.553-3.366,2.188-3.661,4.688
+ C89.339,305.265,89.934,307.95,92.939,307.46z"/>
+ <path i:knockout="Off" d="M99.688,303.916c0.03-1.511,0.055-4.73,0.022-4.646c0.481-1.355,0.658-0.556,1.034-1.297
+ c0.263,1.473,0.653,0.326,1.186,0.065c-0.386,2.518-0.513,3.348-0.574,4.949c-0.068-0.47-0.128,2.28-0.238,2.188
+ c-0.055,1.935-0.036,2.201-0.047,4.219c-0.079,0.914-0.28,2.412-1.126,3.831c-0.61,1.212-1.73,1.146-3.24,1.651
+ c0.073-0.945-0.065-1.242-0.096-1.822c0.098,0.138,0.213,0.604,0.225,0.397c1.892,0.229,2.209-1.896,2.362-3.365
+ c0.042,0.304,0.512-6.934,0.415-7.062C99.73,302.637,99.75,303.179,99.688,303.916z M100.978,295.564
+ c0.717,0.14,1.11,0.61,1.099,1.156c0.052,0.552-0.595,0.993-1.286,1.015c-0.541-0.074-1.025-0.548-1.022-1.054
+ C99.813,296.084,100.292,295.644,100.978,295.564z"/>
+ <path i:knockout="Off" d="M108.115,298.791c3.028-0.066,5.283,1.359,5.256,5.758c-0.264,3.479-3.366,4.63-5.883,5.119
+ c-2.429-0.033-5.619-2.24-5.16-5.811C102.322,300.085,105.715,298.846,108.115,298.791z M107.351,309.232
+ c2.675-0.132,3.839-2.333,3.841-4.497c0.246-2.344-0.263-4.833-2.923-5.396c-2.844,0.299-3.974,1.917-4.053,4.479
+ C104.136,306.655,104.854,308.372,107.351,309.232z"/>
+ </g>
+ </g>
+ </g>
+ <g id="heads" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFFFFFF4F00">
+ <g id="head1" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFF4F00FFFF">
+ <g id="leftEart" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFFFFFF">
+ <path i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M201.557,195.475
+ c7.734-4.547,16.592-5.012,18.405,4.443c2.43,12.659-3.317,13.328-14.598,13.328"/>
+ <path i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M211.711,203.09
+ c0.523,0.004,0.946-0.208,1.271-0.635"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M211.076,197.377
+ c3.062,3.013,5.489,5.624,4.442,10.155"/>
+ </g>
+ <path id="bgHairTop" i:knockout="Off" fill="#FFF471" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M54.384,199.307c-5.253-4.402-7.511-11.061-15.779-10.632c3.449-1.277,7.116-2.397,10.911-2.666
+ c-2.873-1.397-5.865-2.575-8.231-4.718c3.986-1.119,11.47-1.817,14.864,0.75c-5.183-2.758-8.397-7.816-13.062-10.598
+ c6.014-0.643,12.377,0.978,18.022,2.265c-2.547-4.486-6.682-10.83-10.523-14.297c5.033,1.052,10.647,4.518,15.062,7.177
+ c-1.614-4.176-5.634-8.406-7.859-12.513c10.312-1.125,12.522,4.919,19.7,9.932c-0.412-0.127-1.114-0.113-1.527,0.015
+ c0.875-7.261,3.058-12.8,8.258-18.566c6.771-7.507,17.813-9.131,24.095-15.381c-4.699,1.821-4.518,23.765-4.875,28.955"/>
+ <path id="bgHairLeft" i:knockout="Off" fill="#FFF471" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M92.384,243.973c-6.334,7.929-12.601,12.241-22.465,15.361c3.65-1.263,7.735-5.859,7.695-9.928
+ c-2.208,0.218-4.49,0.605-6.498,1.098c1.244-1.098,2.087-3.239,3.198-4.396c-5.77,0.001-12.131,1.133-18.396,1.23
+ c5.013-2.81,10.665-3.25,12.398-9.247c-3.59,0.313-7.233,1.606-11.033,1.097c1.731-2.022,3.953-3.995,5.049-6.447
+ c-3.781,0.056-6.665,3.098-10.547,2.465c0.962-2.863,3.187-5.208,4.531-7.766c-5.59-0.273-11.658,2.45-17.732,2.564
+ c5.494-2.857,8.967-7.819,12.3-12.718c5.233-7.693,10.625-9.96,20.349-9.981c11.059-0.024,15.558,6.714,20.984,16
+ c2.786,4.767,7.249,14.375,0.832,18"/>
+ <path id="bgHair" i:knockout="Off" fill="#FFF471" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M142.384,255.307c2.984,6.076,3.567,11.855,10.531,14.6c-0.134-3.114-0.094-6.664,1.619-9.033
+ c1.604,1.969,3.122,4.211,5.048,5.698c-0.29-1.769,0.412-4.023,0.233-5.828c3.444,0.261,4.979,3.965,8.468,4.479
+ c0.065-2.78,0.427-5.151,0.868-7.813c2.687,0.2,4.768,1.565,7.132,2.997c0.452-4.921-0.409-10.579-0.667-15.666
+ c-5.795-0.756-12.291,2.827-17.899,3.899c-4.414,0.844-14.136,0.523-15.333,6"/>
+ <path id="neck" i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M106.989,254.499c-2.932,6.063-4.613,11.997-8.947,17.138c7.288,10.194,16.311-10.9,15.183-17.026
+ c-1.926-1.138-3.928-1.589-6.236-1.38"/>
+ <path id="headShape" i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M210.941,207.666c-0.844,3.985-2.081,7.982-3.77,11.783c-3.374,7.604-8.543,14.427-16.052,18.899
+ c-2.94,2.13-5.983,4.167-9.109,6.085c-25.013,15.342-55.353,23.08-82.254,10.57c-3.433-1.558-6.785-3.432-10.053-5.66
+ c-1.821-1.185-3.592-2.46-5.308-3.832c-1.715-1.373-3.375-2.842-4.972-4.412c-2.352-2.148-4.576-4.425-6.631-6.814
+ c-6.168-7.169-10.823-15.358-12.87-24.185c-0.649-3.284-0.84-6.634-0.5-9.975c4.48-13.743,14.22-24.364,26.109-32.149
+ c2.973-1.946,6.079-3.715,9.271-5.309c30.581-15.027,69.581-10.027,95.852,12.209c2.563,2.254,4.987,4.651,7.244,7.178
+ c4.513,5.054,8.354,10.626,11.312,16.64C210.178,201.505,210.798,204.497,210.941,207.666z"/>
+ <g id="rightEar" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#800080008000">
+ <path i:knockout="Off" fill="#FFE8B0" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M64.857,195.606
+ c-6.59-7.181-15.047-10.664-19.467,3.676c-1.235,4.007-1.87,14.468,1.29,17.786c4.223,4.435,13.591,0.529,19.055-0.015"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M52.407,196.744
+ c-1.702,3.613-1.257,7.505-1.27,11.424"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M51.772,209.438
+ c-3.39-4.661,0.922-5.769,5.078-6.347"/>
+ </g>
+ <path id="fgHair" i:knockout="Off" fill="#FFF471" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M90.384,154.64c8.453-11.353,15.678-13.458,28.581-15.915c-1.382,3.376-3.89,7.352-5.179,11.16
+ c5.01-1.816,9.571-6.545,15.218-8.413c11.355-3.755,23.853-1.903,35.671-2.213c-3.004,3.712-4.912,7.88-2.025,11.447
+ c5.855-2.212,13.369-6.871,19.635-6.646c0.263,4.561-0.024,9.278,0.201,13.841c3.509-1.201,6.015-3.04,8.276-5.148
+ c2.263-2.108,3.761-4.049,4.942-5.2c1.063,2.408,2.134,5.334,2.24,8.494c-0.183,3.462-0.866,6.794-2.66,9.291
+ c3.663,0.65,6.098-2.021,8.35-4.479c-0.655,4.349-3.164,8.604-3.851,13.013c2.178-0.072,4.382,0.216,6.367-0.48
+ c-1.39,3.093-3.069,7.287-6.616,8.414c-4.476,1.423-4.354-0.992-7.315-4.332c-4.892-5.518-9.773-6.791-15.872-9.464
+ c-6.585-2.887-10.982-6.47-17.963-8.219c-8.994-2.255-19.864-3.867-28.093-5.196c2.466,1.967,1.138,5.594,0.659,8.625
+ c-2.729-0.646-4.41-3.813-6.301-5.158c0.953,3.195,0.983,6.953-2.134,8.491c-6.145-5.226-9.199-9.721-17.527-11.647
+ c1,1.83,1.728,4.208,1.396,6.402c-0.751,4.971-0.289,3.134-3.836,2.466c-5.192-0.977-9.953-3.677-15.815-4.496
+ c3.292,2.002,5.469,5.017,7.418,8.21c-2.651,0.404-6.238,0.257-8.382,1.671c2.456,0.38,3.44,2.166,3.197,4.714
+ c-7.45,0.386-13.623,0.731-19.915,5.434"/>
+ </g>
+ </g>
+ <g id="eyes" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#000000000000">
+ <g id="eyes1" i:knockout="Off" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#4F008000FFFF" display="none">
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M123.163,176.668
+ c-5.066,1.17-9.01,7.888-13.666,10.335c-4.238,2.227-8.648,6.636-7.009,12.332c1.971,6.848,12.042,3.991,16.261,1.165
+ c5.282-3.539,9.59-8.517,12.006-14.524c1.523-3.787,2.568-7.272-1.509-9.391c-2.905-1.51-8.174-1.386-11.417-0.583"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" stroke-linecap="round" d="M182.545,179.865
+ c-3.533,0.169-4.854-1.166-8.408-0.001c-3,0.983-6.239,1.936-8.852,3.743c-3.938,2.725-7.46,5.555-4.73,13.592
+ c1.974,5.811,8.791,7.571,14.656,6.667c5.537-0.854,9.078-4.977,11.408-10.007c3.666-7.918,0.942-11.639-6.742-13.659"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M108.829,183.668c-1.308-1.03-4.557,0.011-5.6-1.733
+ c-1.056-1.765,1.735-5.409,2.984-6.192c5.684-3.562,15.946-0.39,19.95-6.742"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M163.877,167.198c2.369,1.282,6.539,0.307,9.408,0.815
+ c3.449,0.612,7.065,2.657,10.592,2.851"/>
+ <path i:knockout="Off" display="inline" stroke="#000000" d="M127.496,192.002c-4.917-2.12-9.188-1.708-8.608,4.942
+ c3.132,1.734,5.428-2.82,7.275-4.942"/>
+ <path i:knockout="Off" display="inline" stroke="#000000" d="M174.852,203.144c-0.293,0.12-0.307,0.577-0.942,0.282
+ c-1.605-3.188-0.404-6.507,2.676-8.192c2.15-1.176,5.67-1.759,7.471,0.359c0.199,0.234,0.412,0.521,0.515,0.813
+ c0.229,0.649-0.285,0.95-0.285,0.95s-3.988,6.009-3.285,1.934c0.438,1.743-5.537,5.743-2.287,1.653
+ c-1.955,2.583-2.524,1.977-3.859,2.868"/>
+ </g>
+ <g id="eyes2" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFF4F004F00">
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M98.668,186.108c0.668-8.915,15.545-13.749,22.667-15"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M169.667,178.108c5.307,3.436,16.928,5.632,19.668,12.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M105.334,197.775c8.085-4.283,17.059-2.8,25-6.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M164.001,198.775c4.656-0.417,9.664,1.805,14.334,2.017
+ c3.951,0.18,5.773,0.189,9,2.316"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M124.001,188.108c3.039-0.258,4.594,2.571,5.301,4.983
+ c-1.096,1.242-2.065,2.646-2.968,4.017"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M168.335,194.108c-1.77,2.293-4.869,3.271-6.299,5.91
+ c1.377,0.991,3.02,2.122,3.965,3.424"/>
+ </g>
+ </g>
+ <g id="beard" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFF4F00">
+ <path i:knockout="Off" fill="#AFA8A5" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M96.05,213.64
+ c-0.366,0.21-0.783,0.389-1.167,0.5"/>
+ <path i:knockout="Off" fill="#AFA8A5" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M102.55,211.973
+ c0.314-0.01,0.554-0.198,0.667-0.5"/>
+ <path i:knockout="Off" fill="#AFA8A5" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M105.717,208.806
+ c0.164-0.109,0.336-0.224,0.5-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M111.05,207.973
+ c-0.651-1.81,0.859-2.262,2.333-1.5"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M117.717,209.806
+ c1.738,0,3.653,0.369,5.333,0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M132.717,214.473
+ c0.104-0.21,0.162-0.435,0.167-0.667"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M139.551,216.973
+ c0.215-0.175,0.465-0.426,0.666-0.667"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M144.551,213.306
+ c0.277-0.056,0.557-0.111,0.833-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M147.884,216.64
+ c0.195,0.045,0.369-0.013,0.5-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M148.384,214.14
+ c0.112-0.168,0.223-0.332,0.333-0.5"/>
+ <path i:knockout="Off" display="none" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M98.217,219.306c1.697-1.772,4.233-2.109,5.967-4.046c1.519-1.696,3.812-3.001,4.2-5.454"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M152.717,216.14
+ c0.611,0,1.224,0,1.834,0"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M160.384,217.473
+ c0.333,0,0.667,0,1,0"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M163.217,215.973
+ c0.321-0.042,0.658-0.175,0.834-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M164.217,218.806
+ c0.167,0,0.333,0,0.5,0"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M168.384,217.973
+ c0.057-0.056,0.111-0.111,0.167-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M169.884,225.806
+ c0.491-0.397,0.882-0.926,1.167-1.5"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M172.717,221.973
+ c0.057,0,0.111,0,0.167,0"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M171.717,229.806
+ c0.334,0.075,0.659,0.025,0.834-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M190.051,227.806
+ c0.163-0.242,0.398-0.423,0.666-0.5"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M197.384,221.473
+ c0.258-0.007,0.485-0.125,0.667-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M199.384,214.973
+ c-0.04-0.333,0.075-0.609,0.333-0.833"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M117.884,257.306
+ c0.056,0,0.111,0,0.167,0"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M142.717,252.473
+ c0.358,0.068,0.71,0.016,1-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M137.884,256.473
+ c0.277,0,0.557,0,0.833,0"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M160.884,252.973
+ c0.366-0.139,0.766-0.402,1-0.667"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M171.384,250.14
+ c0.235-0.264,0.476-0.562,0.667-0.834"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M89.384,243.973
+ c0.537,0.378,1.329,0.876,1.833,1.333"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M79.05,225.473
+ c0.087,0.272,0.143,0.55,0.167,0.833"/>
+ <path i:knockout="Off" fill="none" stroke="#AAAAAA" stroke-linecap="round" stroke-linejoin="bevel" d="M73.884,222.64
+ c0,0.167,0,0.333,0,0.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M72.55,219.806c0.466-0.325,0.875-0.797,1.167-1.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M71.717,211.973c0.422-0.553,0.776-1.305,1-2"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M78.55,214.473c0-0.111,0-0.222,0-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M79.384,218.806c-0.001-0.137,0.055-0.248,0.167-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M80.217,221.14c0.111,0,0.222,0,0.333,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M75.55,226.473c0.103-0.5,0.156-0.977,0.167-1.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M78.55,230.14c0.111,0,0.222,0,0.333,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M83.384,227.64c0.118-0.059,0.215-0.107,0.333-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M81.55,237.14c0.056,0,0.111,0,0.167,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M86.217,233.806c0.056,0,0.111,0,0.167,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M87.884,230.473c0.595-0.181,1.219-0.527,1.833-0.667"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M88.717,222.14
+ c-0.929,2.359-1.615,4.865-2.667,7.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M89.05,216.14
+ c0.784-0.736,1.709-1.565,2.833-1.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M94.217,210.14
+ c1.599-0.089,3.199-0.167,4.833-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M94.884,224.64
+ c0.052-0.588-0.004-1.155-0.167-1.667"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M92.384,228.306
+ c0.585-0.062,1.244-0.132,1.667-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M88.717,240.14
+ c0.111,0,0.222,0,0.333,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M95.884,243.306
+ c0.526,0.1,1.017-0.016,1.333-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M98.55,248.306
+ c0.069-0.24,0.265-0.926,0.333-1.166"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M96.55,249.806
+ c0.125,0.014,0.18-0.042,0.167-0.166"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M104.55,250.14
+ c0.01-0.238,0.126-0.428,0.333-0.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M106.884,251.973
+ c0.195,0.045,0.37-0.014,0.5-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M113.884,254.806
+ c0.758-0.586,1.595-1.171,2.382-1.774c0.072,0.376,0.418,0.686,0.48,1.079c0.833,0.265,1.624-0.021,1.638-0.971"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M122.217,254.64
+ c0.063-0.165,0.179-0.288,0.333-0.334"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M125.884,255.806
+ c1.13-0.745,2.783-0.962,3.667-2"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M132.217,255.973
+ c0.638-0.492,1.104-1.173,1.141-1.976c-1.11,0.063-1.449-0.888-1.475-1.857"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M129.717,249.306
+ c-0.045,0.153-0.168,0.271-0.333,0.334"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M136.551,252.306
+ c0.223,0,0.444,0,0.666,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M110.217,251.306
+ c0.056-0.057,0.111-0.11,0.167-0.166"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M140.717,251.806
+ c0.111,0,0.224,0,0.334,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M150.051,249.473
+ c0.111,0,0.223,0,0.333,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M143.217,255.473
+ c1.022-0.313,1.725-1.175,2.646-1.654c0.203,0.321,0.439,0.626,0.521,0.987"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M152.217,253.473
+ c0.165-0.063,0.288-0.179,0.334-0.333"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M155.051,254.64
+ c0.223,0,0.444,0,0.666,0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M157.717,256.473
+ c0.326-0.027,0.546-0.073,0.834-0.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M163.217,252.64
+ c0.552-0.892,2.082-1.512,2.341-2.334c0.37-1.178-1.155-3.069-1.007-4.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M167.384,235.973
+ c0.118-0.54,0.354-1.064,0.667-1.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M170.717,242.806
+ c0-0.333,0-0.667,0-1"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M170.217,236.973
+ c0-0.333,0-0.667,0-1"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M179.051,235.806
+ c0.378-0.101,0.738-0.35,1-0.667"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M185.051,232.806
+ c0.379-0.319,0.656-0.702,0.833-1.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M188.051,231.14
+ c0.063-0.39,0.178-0.792,0.333-1.167"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="M197.884,223.306
+ c-0.166,0.277-0.334,0.556-0.5,0.833"/>
+ </g>
+
+ <g id="mouths" i:isolated="yes" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F004F00FFFF" enable-background="new ">
+ <g id="mouth1" i:knockout="Off" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#FFFFFFFF4F00" display="none">
+ <path i:knockout="Off" display="inline" stroke="#000000" d="M177.122,216.821c-0.515,2.282-5.213,3.21-7.434,3.854
+ c-3.254,0.945-6.596,1.345-9.895,1.851c-3.26,0.5-6.665,0.671-10.107,0.671c-3.596,0-6.645,0.559-10.106,0.671
+ c-3.105,0.1-6.898-0.474-9.694-1.3c-3.527-1.043-6.672-1.666-10.096-3.062c-2.823-1.152-5.746-1.876-8.462-3.143
+ c-2.594-1.209-6.084-1.994-8.221-3.552c-1.068,1.834-5.867,3.748-8.1,4.546c-2.444,0.874-8.881,2.725-7.817,5.512
+ c0.457,1.195,1.948,2.273,2.63,3.385c0.774,1.261,1.139,2.601,2.057,3.859c1.83,2.5,4.506,4.773,6,7.34
+ c1.308,2.249,2.096,4.74,4.01,6.669c2.214,2.233,5.792,2.635,9.231,2.399c7.028-0.479,13.982-2.129,20.481-3.983
+ c3.295-0.941,6.699-1.536,10.086-2.686c3.272-1.111,6.642-3,9.402-4.777c5.248-3.377,10.278-6.409,14.283-10.705
+ c1.479-1.587,3.429-2.503,5.149-3.859"/>
+ <path i:knockout="Off" display="inline" fill="#FFC0C0" stroke="#000000" d="M135.25,241.319
+ c0.723-4.757-10.487-8.47-14.898-9.526c-3.09-0.74-6.68-1.17-9.858-1.712c-2.758-0.47-6.865-0.836-9.437,0.369
+ c-1.385,0.649-2.843,1.724-4.141,2.513c2.156,3.964,4.728,8.861,9.468,11.506c3.229,1.801,5.511,0.776,8.859,0.373
+ c3.045-0.369,6.046-0.703,9.029-1.721c3.479-1.186,7.228-2.385,10.978-2.475"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M148.656,225.547c1.267,0.697,1.301,2.838,0.671,3.9
+ c-0.702,1.182-2.063,1.4-3.307,2.01c-2.271,1.116-4.58,2.624-7.481,2.638c-4.619,0.023-2.144-4.067-0.253-5.869
+ c2.405-2.292,5.057-2.72,8.72-2.512c0.588,0.034,1.095,0.041,1.65,0.168"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M130.299,223.365
+ c2.687,0.437,5.619,4.384,3.727,6.422c-1.234,1.33-7.94,1.391-9.915,1.296c-4.896-0.233-2.502-2.445-0.613-4.525
+ c1.604-1.767,5.088-3.249,7.833-3.36"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M113.178,217.157
+ c2.56,0.958,4.922,5.057,5.352,7.215c0.377,1.885-0.324,2.106-2.526,2.643c-1.366,0.333-3.636,0.723-5.105,0.385
+ c-2.506-0.577-5.883-5.051-4.909-7.223c1.03-2.298,5.944-2.923,8.427-2.852"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M99.359,217.662
+ c2.038,0.432,4.015,4.279,2.468,5.625c-1.083,0.943-5.221,1.795-6.799,1.589c-4.032-0.526-2.265-4.102-0.866-5.872
+ c0.706-0.894,1.049-1.976,2.514-2.186c1.627-0.233,2.501,0.99,3.921,1.346"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M181.815,222.896c-3.102-2.75-4.765-8.777-9.282-10.403
+ "/>
+ </g>
+ <g id="mouth2" i:knockout="Off" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#FFFF4F00FFFF" display="none">
+ <path i:knockout="Off" display="inline" stroke="#000000" stroke-width="3" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M87.57,221.951c5.563-1.759,11.066-1.32,16.694-1.782c2.93-0.24,5.228-1.14,8.309-0.927c3.142,0.217,6.085-0.235,9.289,0.176
+ c7.136,0.914,13.96,0.598,21.112,1.506c3.654,0.464,7.219,0.609,10.811,0.869c4.017,0.291,7.646,1.582,11.433,2.623
+ c2.948,0.812,6.347,1.618,9.011,2.99c2.521,1.298,6.354,2.856,8.301,4.72c-2.775,0.027-5.602,2.603-8.021,3.769
+ c-2.93,1.412-5.741,2.949-8.656,4.432c-5.599,2.849-11.885,5.468-18.104,6.53c-6.793,1.161-13.195,2.107-20.067,2.197
+ c-7.699,0.102-14.313-4.705-20.735-8.396c-2.071-1.19-4.69-2.182-6.504-3.666c-1.792-1.466-3.469-3.386-5.154-4.984
+ c-2.703-2.564-7.519-5.649-8.13-9.438"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" stroke-width="2" d="M87.785,228.193
+ c-5.907-3.235-0.344-9.531,3.971-11.424"/>
+
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M184.679,227.229c-1.534,2.583-2.548,5.334-4.024,7.889"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M106.862,219.528
+ c-3.071-0.74-5.608,2.166-6.318,4.738c-0.379,1.375-0.494,2.55,0.748,3.337c1.519,0.962,2.905-0.052,4.418-0.332
+ c2.518-0.467,7.293,0.053,6.461-4.248c-0.568-2.938-3.743-3.682-6.338-3.335c-0.451,0.06-0.758,0.212-1.205,0.229"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M119.764,218.479
+ c-2.648,1.243-4.657,3.518-5.346,6.377c-0.866,3.594,3.9,3.711,6.356,2.865c2.64-0.91,4.77-3.351,3.299-6.133
+ c-1.01-1.91-3.979-2.548-6.026-2.823"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M130.388,219.492
+ c-1.753,1.382-4.069,4.525-4.835,6.61c-1.159,3.156,2.296,3.371,4.868,3.348c3.061-0.028,6.6-1.148,5.022-4.78
+ c-1.168-2.691-2.552-4.85-5.551-5.241"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M142.954,221.087
+ c-1.502,0.337-5.418,3.249-5.638,4.997c-0.292,2.311,4.855,4.536,6.854,4.234c2.503-0.377,4.384-3.175,3.167-5.65
+ c-0.92-1.873-3.36-2.252-4.508-3.932"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M155.354,222.664
+ c-2.038,0.426-4.212,2.287-4.766,4.444c-0.723,2.821,3.226,3.383,5.458,3.331c2.541-0.059,5.126-1.752,3.249-4.32
+ c-1.394-1.908-3.707-3.189-5.304-4.636"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M168.367,237.924
+ c-1.554-1.217-3.302-2.557-5.203-2.976c-2.973-0.654-3.537,2.131-3.377,4.406c0.205,2.913,1.032,3.883,3.901,2.344
+ c1.987-1.066,4.271-1.997,4.599-4.456"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M151.524,246.202
+ c-1.912-0.166-4.004-4.491-2.91-6.25c0.771-1.239,5.456-1.688,6.857-1.292c0.271,0.917,0.979,1.841,0.829,2.771
+ c-0.088,0.54-0.994,1.645-1.296,2.188c-1.08,1.951-2.133,1.866-3.998,2.685"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M145.911,241.458
+ c-0.209,1.649-0.215,2.702-1.528,3.801c-0.885,0.738-1.772,1.189-2.54,2.1c-0.786,0.933-1.226,2.38-2.792,1.813
+ c-1.042-0.377-1.959-2.318-2.138-3.312c-0.299-1.676-1.003-5.228,0.783-6.158c1.154-0.603,7.066-0.18,7.43,1.32"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M133.12,238.991
+ c-1.495-0.087-2.253-1.33-3.918-0.964c-1.42,0.311-2.489,1.354-2.54,2.836c-0.052,1.527,0.99,5.581,1.852,6.956
+ c2.363,3.771,4.329-1.535,5.516-3.159c1.117-1.525,2.643-2.053,2.271-3.958c-0.318-1.632-1.118-2.047-2.766-2.329
+ c-0.382-0.065-0.773-0.095-1.158-0.147"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M116.853,237.43
+ c-1.049,2.211-0.173,5.147,0.047,7.565c0.357,3.93,3.827,2.028,5.831,0.067c1.575-1.541,4.599-4.86,2.209-6.484
+ c-1.881-1.279-5.727-2.458-7.756-1.107"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M107.455,233.38
+ c-0.813,2.487-1.704,5.049,0.073,7.364c1.91,2.486,4.009,1.229,5.537-0.939c1.056-1.5,3.316-4.481,1.563-6.017
+ c-1.347-1.179-6.468-1.518-7.854-0.325"/>
+ </g>
+
+ <g id="mouth3" i:isolated="yes" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFFFFFF" enable-background="new ">
+
+ <path i:isolated="yes" i:knockout="Off" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" enable-background="new " d="
+ M99.05,218.973c1.691-0.875,3.313-2.39,4.833-3.537c1.231-0.928,2.782-1.671,3.5-3.072c1.846,3.486,7.661,4.669,11.003,6.067
+ c3.553,1.486,7.174,3.066,10.784,4.166c4.271,1.301,9.277,1.67,13.721,2.343c4.155,0.629,9.979,1.365,14.162,0.496
+ c1.182-0.245,2.343-1.024,3.462-1.446c0.162,1.905-3.637,3.023-4.933,3.487c-2.435,0.871-4.18,2.541-6.362,3.871
+ c-1.623,0.989-2.974,1.669-4.755,2.117c-1.77,0.445-3.353,0.806-4.825,1.878c-5.915,4.311-15.264,3.247-22.424,3.13
+ c-5.384-0.088-6.719-5.372-9.337-9c-1.437-1.991-2.843-3.854-3.796-6.138c-0.871-2.086-1.119-4.582-2.033-6.528"/>
+
+ <path i:isolated="yes" i:knockout="Off" fill="#F4BDBD" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" enable-background="new " d="
+ M107.217,227.973c1.182-2.033,4.375-2.176,6.5-1.963c2.879,0.289,4.124,1.217,6.168,3.167c1.834,1.749,5.906,5.509,5.64,8.271
+ c-2.808,0.89-7.847,0.402-10.346-1.104c-1.334-0.804-1.151-2.256-2.246-3.588c-0.712-0.866-1.836-2.673-2.855-3.311
+ c-0.209-0.94-2.106-1.499-3.028-1.805"/>
+ </g>
+ </g>
+ <g id="personalProps" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#800080008000">
+ <g id="hat" i:knockout="Off" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#000000000000" display="none">
+ <g i:knockout="Off" display="inline">
+ <g i:knockout="Off">
+ <path i:knockout="Off" fill="#FF0000" d="M88.374,173.145c0.474-0.074,16.606,2.725,18.01,5.879
+ c1.145,2.572,28.184,4.568,28.184,4.568l35.971-5.618l5.024,1.132l7.212,0.315l9.295,0.851l10.188,3.248l5.75,2.935
+ l1.615-1.832l-0.264-5.27l-3.968-7.087c0,0-22.045-13.031-23.272-13.703c-1.229-0.669-4.941-2.294-6.484-4.542
+ c-8.584-12.528-8.403-18.05-3.371-6.461c0,0,2.662-7.592,2.521-8.575c-0.144-0.982,0.354-5.031,0.354-5.031l2.396-6.832
+ c0,0-1.379-5.341-2.738-7.19c-1.356-1.844-15.793-4.078-18.162-4.011c-24.933,0.706-3.783,0.071-25.567,0.724
+ c-24.317,0.728-0.882-2.591-24.068,3.551c-24.228,6.418-5.35-1.298-23.187,6.142c-18.301,7.633-16.67,7.186-16.704,10.685
+ c-0.034,3.499-3.057-4.884-0.034,3.499c3.023,8.381,3.037-3.871,3.023,8.381c-0.015,12.252,6.696,4.557,1.678,12.373
+ c-5.017,7.813-3.831,7.91-0.179,8.543c17.017,2.953,4.157,4.378,17.427,3.175"/>
+ <path i:knockout="Off" d="M156.604,114.92l-13.936,0.381l-11.633,0.343c-10.646,0.319-11.973-0.155-12.021-0.175l-0.599-0.238
+ l-0.577,0.514l0.049-0.047c-0.118,0.09-1.43,0.957-11.145,3.53c-9.989,2.646-12.812,2.931-13.421,2.704
+ c-0.822-0.306-0.821-0.306-7.791,2.604l-2.104,0.878c-16.037,6.689-17.342,7.324-17.342,10.316c0,0.019,0.001,0.041,0.001,0.06
+ c-0.224-0.108-0.459-0.199-0.787-0.04c-0.357,0.173-0.565,0.275-0.565,0.672c0,0.557,0.411,1.697,1.399,4.438
+ c0.924,2.561,1.71,3.671,2.714,3.833c0.083,0.014,0.164,0.02,0.241,0.02c0.007,0.584,0.01,1.339,0.01,2.313
+ c0,0.561-0.001,1.902-0.001,1.916c0,6.908,2.176,8.105,3.347,8.749c0,0,0.075,0.045,0.151,0.09
+ c-0.095,0.332-0.47,1.1-1.661,2.955c-2.509,3.908-3.516,5.931-3.516,7.303c0,0.358,0.068,0.671,0.196,0.962
+ c0.544,1.237,1.926,1.477,3.677,1.78l0.135,0.023c8.138,1.412,9.14,2.422,9.568,2.854c0.923,0.931,1.511,0.928,7.224,0.413
+ c0.06,0.014,0.102,0.068,0.165,0.071c2.167,0.105,16.131,3.138,17.087,5.288c1.147,2.578,16.416,4.228,29.023,5.159
+ l0.115,0.009c0,0,35.523-5.548,35.896-5.606c0.345,0.078,4.927,1.11,4.927,1.11l7.301,0.319c0,0,8.927,0.818,9.139,0.837
+ c0.202,0.064,9.854,3.142,10.006,3.19c0.143,0.073,6.368,3.251,6.368,3.251l2.397-2.719l-0.296-5.911l-4.213-7.526
+ l-0.231-0.137c-0.9-0.532-22.073-13.047-23.304-13.72c-0.001,0-0.734-0.38-0.734-0.38c-1.48-0.752-4.238-2.151-5.404-3.85
+ c-1.357-1.982-2.451-3.729-3.354-5.268c0.021-0.064,0.104-0.296,0.104-0.296c1.193-3.402,2.576-7.619,2.576-8.885
+ c0-0.063-0.004-0.118-0.011-0.165c-0.013-0.083-0.018-0.204-0.018-0.356c0-0.909,0.194-2.911,0.363-4.307
+ c0.072-0.205,2.46-7.013,2.46-7.013l-0.076-0.294c-0.146-0.566-1.468-5.584-2.9-7.532
+ C173.721,116.784,158.242,114.875,156.604,114.92z M131.097,117.644l11.614-0.342l13.951-0.382
+ c2.575-0.073,16.104,2.238,17.336,3.614c0.956,1.3,2.058,4.938,2.49,6.549c-0.188,0.536-2.33,6.642-2.33,6.642l-0.014,0.107
+ c-0.072,0.592-0.387,3.224-0.387,4.658c0,0.258,0.011,0.477,0.034,0.639c-0.006,0.493-0.768,3.026-1.659,5.709
+ c-2.14-4.566-2.792-4.606-3.242-4.629l-0.62-0.031l-0.354,0.571c-0.069,0.124-0.102,0.29-0.102,0.492
+ c0,2.273,4.134,9.172,6.992,13.346c1.456,2.12,4.51,3.669,6.149,4.501l0.682,0.353c1.139,0.622,20.813,12.25,23.012,13.549
+ c0.238,0.427,3.513,6.275,3.721,6.647c0.02,0.393,0.199,3.971,0.23,4.629c-0.229,0.262-0.472,0.535-0.832,0.944
+ c-1.069-0.546-5.132-2.619-5.132-2.619l-10.369-3.306l-9.403-0.86c0,0-6.995-0.307-7.169-0.315
+ c-0.168-0.038-5.124-1.155-5.124-1.155s-35.814,5.594-36.044,5.63c-12.419-0.922-25.993-2.687-27.285-4.058
+ c-1.366-3.097-13.245-5.574-17.517-6.211c-0.203-0.212-0.479-0.346-0.793-0.318c-3.083,0.28-5.996,0.544-6.4,0.369
+ c0-0.003-0.12-0.117-0.12-0.117c-0.703-0.708-1.879-1.895-10.646-3.416l-0.135-0.023c-0.827-0.143-2.075-0.359-2.188-0.614
+ c-0.021-0.048-0.033-0.111-0.033-0.193c0-0.592,0.632-2.179,3.205-6.187c1.488-2.318,2.024-3.388,2.024-4.188
+ c0-0.15-0.019-0.291-0.054-0.428c-0.181-0.712-0.758-1.03-1.179-1.261c-0.865-0.476-2.311-1.271-2.311-6.993
+ c0-0.014,0.001-1.098,0.001-1.56c0-4.969-0.065-4.992-0.833-5.258c-0.424-0.146-0.816,0.001-1.178,0.377
+ c-0.208-0.289-0.558-0.898-1.073-2.324c-0.205-0.568-0.385-1.068-0.542-1.506c0.587-0.423,0.632-1.277,0.636-1.644
+ l-0.014-0.825c-0.004-0.119-0.007-0.231-0.007-0.338c0-1.702,0.899-2.264,16.109-8.608l2.105-0.878
+ c4.165-1.739,5.948-2.482,6.375-2.562c0.817,0.296,2.292,0.597,14.579-2.658c8.169-2.164,10.697-3.187,11.58-3.704
+ C120.451,117.773,124.529,117.84,131.097,117.644z"/>
+ </g>
+ <g i:knockout="Off">
+ <path i:knockout="Off" fill="#FFFFFF" d="M155.146,147.93c4.88-9.398-5.344-20.199-12.649-21.176
+ c-12.05-1.61-13.404,10.426-13.684,21.258c3.73,2.016,8.915,3.425,11.721,6.534"/>
+ <path i:knockout="Off" d="M133.446,127.979c-4.599,3.921-5.426,11.933-5.635,20.006l-0.017,0.654l4.415,2.067
+ c2.849,1.244,5.793,2.529,7.581,4.509c0.371,0.41,1.004,0.442,1.412,0.072c0.219-0.197,0.33-0.469,0.33-0.743
+ c0-0.239-0.084-0.479-0.258-0.67c-2.076-2.299-5.223-3.673-8.267-5.001c0,0-2.377-1.112-3.174-1.486
+ c0.223-7.385,1.021-14.572,4.909-17.887c1.892-1.614,4.386-2.189,7.621-1.757c4.143,0.554,9.086,4.472,11.5,9.113
+ c1.348,2.591,2.51,6.535,0.395,10.611c-0.254,0.49-0.063,1.093,0.426,1.348c0.49,0.254,1.095,0.063,1.351-0.427
+ c1.959-3.775,1.817-8.199-0.396-12.456c-2.731-5.251-8.203-9.53-13.012-10.172C138.853,125.257,135.763,126,133.446,127.979z"
+ />
+ </g>
+ <g i:knockout="Off">
+ <path i:knockout="Off" d="M154.077,146.278c-2.156,1.18-4.24,2.619-6.256,4.01c-3.636,2.509-7.068,4.878-10.941,5.924
+ c-2.991,0.808-6.055,1.058-9.3,1.324c-3.222,0.263-6.553,0.536-9.783,1.406c-2.027,0.546-4.117,1.397-6.137,2.221
+ c-3.491,1.423-7.102,2.895-10.528,2.866c-0.552-0.005-1.004,0.439-1.009,0.991c-0.005,0.552,0.439,1.004,0.991,1.009
+ c3.828,0.033,7.627-1.516,11.301-3.014c2.054-0.837,3.994-1.628,5.902-2.142c3.054-0.823,6.292-1.088,9.425-1.344
+ c3.191-0.261,6.492-0.531,9.659-1.386c4.205-1.135,7.94-3.714,11.557-6.208c1.973-1.362,4.014-2.771,6.08-3.901
+ c0.484-0.265,0.662-0.873,0.396-1.357C155.168,146.193,154.562,146.014,154.077,146.278z"/>
+ </g>
+ <g i:knockout="Off">
+ <path i:knockout="Off" d="M156.458,153.549c-2.619,0.064-5.709,0.812-8.98,1.604c-4.278,1.035-8.7,2.104-11.901,1.536
+ c-0.543-0.096-1.063,0.267-1.159,0.81c-0.097,0.544,0.267,1.063,0.81,1.16c3.613,0.641,8.24-0.481,12.72-1.562
+ c3.166-0.766,6.153-1.489,8.561-1.548c5.664-0.141,7.961,0.698,13.508,2.724c0.519,0.189,1.095-0.077,1.281-0.596
+ c0.189-0.519-0.076-1.091-0.596-1.282C165.069,154.337,162.501,153.399,156.458,153.549z"/>
+ </g>
+ </g>
+ </g>
+ <g id="textSurface" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F008000FFFF">
+
+ <g id="spokenBubble" i:knockout="Off" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#FFFF4F004F00" display="none">
+ <path id="textContainer" i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M225.719,45.307
+ c0-6.627,5.373-12,12-12h181.333c6.627,0,12,5.373,12,12v105.334c0,6.627-5.373,12-12,12H237.719c-6.627,0-12-5.373-12-12
+ V45.307z"/>
+ <path id="textArrowBelow" i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M249.052,160.64
+ c-0.774,14.251-1.676,18.525-9.1,30.565c9.705-0.79,21.952-21.605,25.1-30.045"/>
+ </g>
+ <g id="thoughtBubble" i:knockout="Off" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFF4F00">
+ <path id="textContainer_1_" i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M202.698,21.089
+ c19.686-26.45,59.686-24.45,79.747-0.084c2.696,1.349,5.57,1.709,7.472,0.781c15.28-13.888,33.271-14.043,49.893-7.839
+ c2.771,1.034,5.479,2.219,8.031,3.421C376.384-4.36,423.384,6.64,431.007,45.026c0,0-1.324,3.889,1.165,6.603
+ c18.212,11.011,26.212,32.011,22.212,53.011c-1,5.333-3.223,9.667-6.037,13.52c-2.813,3.854-1.381,0-2.612-0.591
+ c-1.351-0.929-3.351-0.929-4.351-1.929c16,7,27,22,30,39c2,21-8,41-27,50c-16,7.5-32.5,5.5-45.745-2.556
+ c-2.531-1.384-4.229-1.856-5.336-1.551c-1.919,0.107-3.919,2.107-5.919,2.107c4-1,6-5,10-6c-15,11-35,12-52,3c-13-7-20-20-24-34
+ c1,5,3,9,3.299,13.505c-0.396,0.708-3.423,2.219-6.654,3.466c-22.627,8.729-49.423,1.729-65.241-19.971
+ c-3.453,0-6.263,0.589-8.723,0.879c-17.301,3.2-32.382-7.709-40.771-22.689c-1.678-2.996-3.089-6.153-4.195-9.396
+ c-15.714-7.795-29.714-18.795-33.714-37.795c-5-25,11-45,29.842-57.667c0.72-2.335,1.697-4.636,3.007-6.896
+ C201.159,23.307,202.698,21.089,202.698,21.089z"/>
+ <g i:knockout="Off">
+ <path i:knockout="Off" fill="#FFFFFF" d="M269.719,186.307c0,4.602-4.179,8.333-9.333,8.333s-9.334-3.731-9.334-8.333
+ c0-4.603,4.18-8.333,9.334-8.333S269.719,181.705,269.719,186.307z"/>
+ <g i:knockout="Off">
+ <path i:knockout="Off" fill="none" d="M269.719,186.307c0,4.602-4.179,8.333-9.333,8.333s-9.334-3.731-9.334-8.333
+ c0-4.603,4.18-8.333,9.334-8.333S269.719,181.705,269.719,186.307z"/>
+ <path i:knockout="Off" fill="#FFFFFF" d="M268.225,186.166c-0.563,8.736-13.981,9.286-15.633,0.853
+ c-1.785-9.125,15.018-10.254,15.649-0.451c0.125,1.929,3.078,1.388,2.955-0.521c-0.814-12.597-20.828-12.412-21.64,0.119
+ c-0.827,12.813,20.831,13.028,21.655,0.283C271.337,184.519,268.35,184.235,268.225,186.166z"/>
+ </g>
+ </g>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M260.386,188.307c0,3.498-2.984,6.333-6.667,6.333
+ c-3.682,0-6.667-2.835-6.667-6.333s2.985-6.333,6.667-6.333C257.401,181.974,260.386,184.809,260.386,188.307z"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M238.386,196.974c0,1.289-1.045,2.333-2.334,2.333
+ c-1.288,0-2.333-1.045-2.333-2.333c0-1.288,1.045-2.333,2.333-2.333C237.341,194.64,238.386,195.685,238.386,196.974z"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M285.719,179.974c0,4.602-4.253,8.333-9.5,8.333
+ s-9.5-3.731-9.5-8.333c0-4.603,4.253-8.333,9.5-8.333S285.719,175.372,285.719,179.974z"/>
+ </g>
+
+ <g id="yellBubble" i:knockout="Off" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#4F004F00FFFF" display="none">
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M251.156,176.051l40.228-15.992"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="bevel" d="
+ M280.932,149.385l-40.667,36.42"/>
+ <path id="textContainer_2_" i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M217.778,34.644
+ c8.608,6.684,9.951,3.684,7.986-5.785c6.309,5.125,9.309,3.782,10.188-4.309c2.433,8.091,5.266,8.091,9.12-1.703
+ c6.063,9.793,13.146,9.793,24.043,3.878c6.103,5.915,16.02,5.915,20.094-4.64c17.178,10.555,28.511,10.555,45.233-5.505
+ c5.94,16.06,17.272,16.06,18.835,1.458c19.688,14.603,29.604,14.603,46.749-17.802c-0.145,32.405,6.938,32.405,29.26,16.182
+ c-12.403,16.223-9.57,16.223,4.813,6.576c-11.069,9.646-8.069,10.99,4.333,9.089c-8.061,6.244-6.717,9.244,2.533,11.068
+ c-9.25,1.489-9.25,5.703-0.314,13.07c-8.936,6.115-8.936,15.385,7.513,10.932c-16.447,24.677-16.447,35.631,14.938,36.553
+ c-31.385,19.303-31.385,28.571-4.39,40.526c-26.995,1.528-26.995,5.741-5.942,17.857c-21.053-8.801-22.396-5.802-9.525,11.916
+ c-17.213-13.374-20.213-12.03-12.048,8.029c-11.479-20.06-14.313-20.06-10.554,3.532c-13.676-23.591-20.759-23.591-29.813-2.664
+ c-7.944-20.927-17.861-20.927-27.072,12.467c-12.039-33.395-23.373-33.395-23.147-1.581
+ c-22.891-31.814-34.225-31.814-61.518-8.479c6.042-23.335-3.874-23.335-11.899-9.703c-8.976-13.632-16.059-13.632-23.927,4.361
+ c-2.049-17.993-4.882-17.993-10.51-1.486c2.314-16.508-0.686-17.851-12.385-5.019c7.355-17.175,6.013-20.176-10.271-7.879
+ c16.283-15.61,16.283-19.824-9.255-12.972c25.538-20.334,25.538-29.603,1.919-46.578c23.619-3.249,23.619-14.204-0.313-25.522
+ c23.933-8.905,23.933-18.175,7.798-37.429C226.385,48.854,226.385,44.641,217.778,34.644z"/>
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/includes/js/dojox/gfx/demos/data/Nils.json b/includes/js/dojox/gfx/demos/data/Nils.json
new file mode 100644
index 0000000..59e40cb
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/Nils.json
@@ -0,0 +1,717 @@
+[
+ {
+ "name": "nils_1_",
+ "children": [
+ {
+ "name": "lowerBody",
+ "children": [
+ {
+ "name": "leftShoe",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M44.787,442.042c13.536-0.097,28.515-2.647,40.667-8.815 c13.064-6.631,3.188-24.604,0.553-34.404c-5.771-1.73-10.549-4.837-16.568-0.148c-4.371,3.405-6.025,11.462-2.07,15.501 c-3.212,7.339-17.804,1.912-23.732,6.7c-5.825,4.706-7.32,17.966,0.484,21.167"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M133.453,425.375c0.901-2.979,2.793-5.781,4.667-8"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M56.787,426.708c-2.551-2.07-3.97-5.252-5.333-8"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "rightShoe",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M111.453,402.042c-2.005-0.426-3.947-0.363-5.899-0.566 c-0.104,2.376,0.438,5.478,0.048,7.751c-0.4,2.327-1.597,4.06-2.146,6.817c-0.975,4.9,0.412,10.561,3.813,13.517 c3.718,3.23,8.442,2.56,12.87,3.797c4.256,1.189,7.959,3.502,12.5,4.849c9.169,2.717,20.433,7.657,25.649-4.685 c2.797-6.618-0.894-5.624-6.331-7.982c-4.049-1.757-6.774-4.353-10.32-7.014c-4.123-3.095-8.203-5.957-13.415-6.584 c-0.11-3.353,1.616-5.692,1.132-9.117c-5.299-2.318-13.883-3.984-19.233-0.116"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M62.787,424.708c-1.417-2.271-3.012-5.388-2.667-8.666"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M141.453,428.042c2.076-1.991,4.274-3.745,6-6"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "leftLeft",
+ "shape": {
+ "type": "path",
+ "path": "M111.687,360.891c0.036,4.747,1.844,9.223,1.56,14.078 c-0.24,4.099-1.372,8.075-1.553,12.199c-0.2,4.558-1.141,9.069-1.142,13.648c0,3.48-0.275,5.533,3.084,7.379 c2.301,1.264,4.909,1.163,7.094-0.113c2.993-1.748,2.841-3.747,2.868-6.904c0.025-2.952,0.712-5.943,1.162-8.841 c0.446-2.868,0.401-5.667,0.398-8.578c-0.004-3.788,0.138-7.556,0.003-11.357c-0.118-3.318-1.49-6.782-1.279-10.093"
+ },
+ "fill": "#FFF0A9",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "rightLeg",
+ "shape": {
+ "type": "path",
+ "path": "M74.107,353.8c-0.57,1.485-0.055,3.729-0.142,5.357 c-0.076,1.44-0.315,2.774-0.571,4.184c-0.786,4.316-1,8.786-1.732,13.181c-1.158,6.942-0.906,14.193-1.777,21.167 c-0.456,3.648,0.862,8.169,5.499,7.139c2.579-0.572,4.859-3.016,5.846-5.361c2.937-6.981-0.974-13.832-0.457-21.057 c0.331-4.619,2.141-8.637,3.402-13.056c0.769-2.694,1.709-5.131,1.703-7.972c-0.004-1.809,0-3.616,0-5.425"
+ },
+ "fill": "#FFF0A9",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "pants",
+ "children": [
+ {
+ "name": "pants_1_",
+ "shape": {
+ "type": "path",
+ "path": "M72.453,299.375 c1.947,19.47-1.848,38.143-0.849,57.849c3.905,0.681,11.166,0.417,14.849-0.849c7.135-2.453,6.497-2.631,7-11 c0.81-13.479-2.849-20.278,12.845-17.853c-1.125,13.305-9.43,25.115-3.42,38.649c8.404-0.38,20.265,0.661,28.427-1.944 c0.505-10.198-1.523-17.622-2.853-26.853c-1.398-9.708,3.313-18.866-1.174-27.826c-9.218,0.693-18.358,2.747-27.722,0.798 c-9.863-2.054-18.89-8.623-29.104-8.972"
+ },
+ "fill": "#ADA274",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "leftArm_1_",
+ "children": [
+ {
+ "name": "leftArm",
+ "shape": {
+ "type": "path",
+ "path": "M161.453,199.375c-6.73,0.606-12.711,7.192-9.248,13.248 c3.358,5.87,13.618,5.538,19.021,6.979c4,1.066,16.837,3.192,19.52,5.703c3.974,3.72,5.243,15.844,5.854,20.924 c13.641,4.354,26.949-0.671,33.102-13.826c5.331-11.398-5.783-19.505-17.098-22.174c1.771-8.465,14.167-32.061-0.128-36.899 c-4.761-1.611-15.726,3.346-17.801,7.272c-3.095,5.855-0.055,15.902-0.374,22.623c-13.399,0.68-27.351-3.555-39.849-1.849"
+ },
+ "fill": "#FFF0A9",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M221.453,220.375c-4.604-1.889-17.369-6.456-21.801-1.801 c-4.797,5.039,1.256,14.077,6.027,16.578c4.118,2.159,20.628,4.348,24.575,1c4.999-4.241,2.906-14.993-2.801-17.777"
+ },
+ "fill": "#FFF0A9",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M214.453,253.375c-1.006,3.482-0.767,9-3.174,12.826 c-15.878,0.834-16.244-5.43-25.674-14.571c10.53-5.253,19.583,4.754,29.849,2.745"
+ },
+ "fill": "#FFF0A9",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M226.453,239.375c0.54,16.962-8.377,15.391-21.023,12.023 c-17.34-4.617-11.577-7.176,3.023-13.023"
+ },
+ "fill": "#FFF0A9",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M208.453,188.375c-4.474,0.83-8.972-0.434-11-4"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M203.453,221.375c6.112-0.45,18.967,6.649,8,10"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M195.453,258.375c3.441-0.666,5.408-2.2,4-5"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "rightArm",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M39.453,187.375c-3.104,7.216-3.137,14.998-7.278,21.997 c-5.137,8.684-9.794,6.9-17.5,12.281c-8.803,6.146-12.141,29.697-14.095,40.548c20.2,3.536,18.779-23.776,21.649-34.524 c0.975,13.012-0.289,26.468,0.374,39.546c2.257,0.582,6.44,0.582,8.697,0c2.04-10.494-3.53-22.034-0.852-33.546 c0.009,7.58-2.598,32.2,10.852,28.546c0.514-10.124-1.899-18.938-4.868-25.972c2.181,8.766,4.798,18.48,15.845,15.949 c6.407-12.781-3.909-15.105-8.048-25.604c-2.531-6.422,0.527-25.44,6.223-31.223"
+ },
+ "fill": "#FFF0A9",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M6.453,248.042c2.111,0,6.324-0.997,6.667,1.666"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M22.453,255.375c2.85-0.37,4.155,0.539,4.999,3.001 c1.085,3.168-0.233,4.173-2.999,5.332"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M31.787,255.042c3.675-0.503,7.077,4.971,3,6"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M48.453,235.708c-5.387-0.935-3.676,10.551,3.667,8.667"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M207.453,241.375c2.63,1.686,2.368,4.909,1.884,7.884 c-0.744,0.175-1.23,0.456-1.884,0.783"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "shirt",
+ "children": [
+ {
+ "name": "mainShirt",
+ "shape": {
+ "type": "path",
+ "path": "M39.453,189.375 c0.777-3.467,1.211-7.217,1.151-10.849c14.871-1.403,32.372-7.656,46.875-11.125c9.423-2.254,31.959-20.14,39.244-11.079 c3.778,4.7,2.066,16.102,5.456,22.08c2.827,4.986,9.093,12.445,13.003,16.217c5.193,5.009,15.695-3.271,18.271,2.754 c3.024,7.075-0.511,20.739-10.02,18.016c-5.084-1.456-12.238-5.093-15.228-9.769c-4.055-6.341-8.831-13.012-10.53-19.167 c-0.713,10.697,1.173,22.369,2.726,32.92c1.637,11.128,1.886,22.261,3.052,34c2.02,20.336,6.915,42.053,10.845,61.855 c-14.599,4.091-47.868-3.832-47.868-3.832s-14.457-3.595-21.2-5.801c-8.131-2.661-21.777-11.223-13.777-11.223 s-3.063-9.756,2.468-40.878s14.003-39.61,19.806-56.122c1.387-3.946,2.399-8.004,4.375-11.845 c-17.565,1.273-26.117,7.964-40.475,16.742c-2.413-9.11-9.707-14.336-17.174-18.897"
+ },
+ "fill": "#4867FF",
+ "stroke": {
+ "color": "#000000",
+ "width": "2"
+ }
+ },
+ {
+ "name": "highlight",
+ "shape": {
+ "type": "path",
+ "path": "M99.453,179.375 c-5.364,2.937-10.603,8.065-17,8"
+ },
+ "fill": "#4867FF",
+ "stroke": {
+ "color": "#000000",
+ "width": "2"
+ }
+ },
+ {
+ "name": "logo",
+ "children": [
+ ]
+ }
+ ]
+ },
+ {
+ "name": "heads",
+ "children": [
+ {
+ "name": "head1",
+ "children": [
+ {
+ "name": "hair_1_",
+ "shape": {
+ "type": "path",
+ "path": "M60.453,97.375c-3.965-0.012-7.98,0.045-11.897-0.147 c2.645-5.735,10.791-8.417,14.794-13.65c-2.384,0.19-5.083-0.61-7.543-0.154c2.395-1.359,4.008-3.487,6.347-4.846 c-2.993-0.207-6.326-0.467-9.399-0.18c2.893-0.874,5.243-2.063,7.821-3.05c-0.92-0.166-4.625-2.732-6.772-4.221 c5.187-4.255,12.317-5.834,17.573-8.534c-2.844-0.13-5.037-1.713-7.75-2.393c-0.424-7.244-1.302-14.461-1.223-21.475 c2.166,2.761,3.541,5.976,4.849,8.546c-0.996-11.489,4.773-13.594,13.025-18.797c0.403,1.91,1.943,3.845,2.229,5.546 c1.27-13.312,22.924-28.644,34.016-33.272c0.039,6.247-2.955,11.957-5.365,17.475c-0.365,0.375-0.375,0.366-0.028-0.028 c5.849-6.92,14-8.882,22.143-10.721c-1.215,5.635-5.28,10.684-6.698,16.602c6.258-10.069,20.421-4.135,27.949-11.351 c-1.011,3.251-2.028,6.254-3.143,9.276c7.035-8.774,15.902-11.37,25.894-14.499c-0.668,7.995-10.243,18.061-0.822,20.872 c8.889,2.653,17.435-7.31,26.698-6.075c-2.976,1.954-5.822,4.12-8.614,6.345c7.596,2.01,18.243,0.852,26.614,0.658 c-4.125,3.304-9.116,7.352-9.593,12.943c3.896-0.826,8.6-1.318,12.741-0.725c-1.013,1.726-1.479,5.845-2.718,7.678 c3.136-0.265,6.17,1.053,8.519,1.452c-3.019,0.804-5.247,3.16-7.566,4.52c3.765,0.755,7.282,2.001,10.844,3.398 c-3.322,1.78-5.724,5.475-4.776,9.657c0.798,0.374,2.536,0.977,2.995,1.147c-6.481,3.645-21.331-1.522-28.945-2.752 c-13.967-2.257-27.844-4.641-41.913-6.244c-17.039-1.941-37.716-3.446-54.359,1.025C83.983,67.42,68.871,76.651,58.453,98.375"
+ },
+ "fill": "#605542",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "neck",
+ "shape": {
+ "type": "path",
+ "path": "M108.453,132.375c0.902,8.412-0.835,20.235-3.849,27.797 c4.164,2.769,15.721,4.339,19.868,0c3.538-3.701,1.964-17.522,1.98-22.797"
+ },
+ "fill": "#FFF0A9",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "leftEar_1_",
+ "children": [
+ {
+ "name": "leftEar",
+ "shape": {
+ "type": "path",
+ "path": "M232.453,76.375c10.186-6.915,21.465,6.994,19.052,17 c-2.781,11.53-20.253,15.518-27.052,5"
+ },
+ "fill": "#FFF0A9",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M245.453,91.375c-0.398-2.267-1.99-4.77-3.171-6.829 c-2.738-0.936-5.713-1.545-8.829-1.171"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M238.453,90.375c1.863-0.367,3.589-1.433,5-3"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "headShape",
+ "shape": {
+ "type": "path",
+ "path": "M116.453,35.375 c-13.417,2.219-31.83,24.639-39.777,35.055c-8.128,10.652-24.737,25.747-20.219,39.945 c5.161,16.221,22.089,14.526,34.025,19.972c15.448,7.047,30.645,11.875,46.749,14.251c18.146,2.676,27.633,0.161,44.223-7.972 c15.701-7.697,29.862-9.589,41.801-24.303c8.182-10.084,15.033-28.733,8.174-38.923c-6.159-9.151-21.79-19.289-31.201-25.75 c-12.144-8.339-26.876-10.032-41-11.274c-15.007-1.32-33.207-3.056-47.774,1"
+ },
+ "fill": "#FFF0A9",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "rightEar_1_",
+ "children": [
+ {
+ "name": "rightEar",
+ "shape": {
+ "type": "path",
+ "path": "M66.453,94.375 c-10.188-4.124-23.701-5.729-27.774,7.226c-4.779,15.198,14.506,23.077,25.774,15.774"
+ },
+ "fill": "#FFF0A9",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M42.453,106.375c4.149-4.954,11.06-7.737,16-10"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M48.453,100.375c1.337,3.541,2.787,6.955,5,10"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "adamsApple",
+ "shape": {
+ "type": "path",
+ "path": "M113.453,152.375c-0.526-2.327,1.546-3.837,5-4"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "expressions",
+ "children": [
+ {
+ "name": "confused",
+ "children": [
+ {
+ "name": "mouth_1_",
+ "children": [
+ {
+ "name": "mouth",
+ "shape": {
+ "type": "path",
+ "path": "M102.148,120.014c13.398-6.9,33.568-7.688,49-10.026 c12.555-1.903,36.519-2.575,44,9.026"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "tooth_1_",
+ "shape": {
+ "type": "path",
+ "path": "M178.148,109.014 c-0.563-2.655-0.017-6.196,0.151-8.849c4.788-0.944,9.637,0.768,13.675,3.022c0.664,3.187,0.065,6.267-1.826,8.826"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "tooth",
+ "shape": {
+ "type": "path",
+ "path": "M168.148,108.014c-2.021-7.958,5.04-7.752,10.826-6.826 c1.286,2.446,1.752,5.863,1.022,8.675c-3.801,0.292-8.049,0.308-10.849-0.849"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "eyes",
+ "children": [
+ {
+ "name": "rightEye",
+ "shape": {
+ "type": "path",
+ "path": "M121.148,52.014 c-6.562,8.145-20.057,16.28-21.023,26.977c-1.104,12.227,10.759,15.164,21.02,11.798c18.8-6.168,24.482-40.499,0.004-39.774"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "pupilRight",
+ "shape": {
+ "type": "path",
+ "path": "M112.148,61.014c-7.625,3.067-4.047,12.428,3.826,10.826 C118.354,67.432,118.046,61.261,112.148,61.014"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "leftEye",
+ "shape": {
+ "type": "path",
+ "path": "M184.148,55.014c-13.391-8.758-17.664,28.504,5,25.996 c10.862-1.201,14.124-12.581,8.004-19.996c-6.121-7.415-14.988-4.947-22.004-8"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "pupilLeft",
+ "shape": {
+ "type": "path",
+ "path": "M176.148,54.014c-2.04,2.896-2.657,6.347-1.849,9.849 C184.707,66.621,182.108,56.322,176.148,54.014"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "confused2",
+ "children": [
+ {
+ "name": "rightEye_1_",
+ "shape": {
+ "type": "path",
+ "path": "M121.148,52.014 c-6.562,8.145-20.057,16.28-21.023,26.977c-1.104,12.227,10.759,15.164,21.02,11.798c18.8-6.168,24.482-40.499,0.004-39.774"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "pupilRight_1_",
+ "shape": {
+ "type": "path",
+ "path": "M112.148,61.014 c-7.625,3.067-4.047,12.428,3.826,10.826C118.354,67.432,118.046,61.261,112.148,61.014"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "leftEye_1_",
+ "shape": {
+ "type": "path",
+ "path": "M184.148,55.014 c-13.391-8.758-17.664,28.504,5,25.996c10.862-1.201,14.124-12.581,8.004-19.996c-6.121-7.415-14.988-4.947-22.004-8"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "name": "pupilLeft_1_",
+ "shape": {
+ "type": "path",
+ "path": "M176.148,54.014 c-2.04,2.896-2.657,6.347-1.849,9.849C184.707,66.621,182.108,56.322,176.148,54.014"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M114.934,118.74 c18.933-4.896,31.704-2.456,49.826,1.171c6.734,1.348,17.654,7.566,23.408,0.323c5.436-6.841-0.011-16.179-7.237-17.994"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "talking",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M150.536,116.479c0.413,18.115,48.746,18.222,37.276-7.278 c-10.396-1.757-28.836,2.451-38.776,5.778"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M103.453,104.875c-2.277,2.169-1.729,7.324-4.849,8 c8.889,3.074,18.975,7.877,28.849,6.998c6.759-0.602,18.439-1.511,23.5-5.998"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M104.453,64.875 c-6.218-0.224-17.093,9.247-13.875,15.887c2.822,5.825,15.087,4.174,20.375,3.113c4.505-0.904,7.783-1.37,9.889-6.123 c1.107-2.499,2.855-9.088,1.623-11.889c-2.859-6.496-15.374-3.248-19.512,0.012"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M176.953,59.875 c-4.742,8.403,0.46,13.596,6.486,18.376c4.779,3.791,15.903,8.529,19.512,0.622c8.012-17.554-22.026-19.554-32.498-17.887 c-0.345,0.055-1.151,0.291-1.5,0.389"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M98.953,66.875c-6.969-2.545-10.165,5.418-3.002,8.05 c2.178-2.129,5.596-6.88,2.502-9.05"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M178.453,60.875c-5.534,0.708-5.259,9.173,0.5,7.387 c6.145-1.906,5.217-9.047-1.5-8.387"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ },
+ {
+ "name": "talking2",
+ "children": [
+ {
+ "shape": {
+ "type": "path",
+ "path": "M102.87,94.503c-2.279,15.037-5.934,27.828,15.027,23.027 c15.334-3.512,25.379-13.239,28.973-28.027"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M92.87,104.503 c4.248-16.004,34.717-10.765,47.052-11.948c8.414-0.807,15.879-1.97,24.948-1.055c8.295,0.837,19.3,2.941,27-0.997"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M84.87,73.503c2.341-8.752,12.467-12.772,19-18"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M181.87,59.503c8.968-3.27,16.681,2.245,25,3"
+ },
+ "fill": "none",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M98.87,68.503 c-7.218,11.165,3.031,17.234,13.003,17.997c13.201,1.009,21.125-8.677,18.845-21.842c-11.637-0.604-21.219,1.818-31.849,2.845"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M178.87,67.503 c-9.045,2.007-6.264,11.616-1.249,15.249c3.778,2.737,13.479,4.477,18.249,2.528C210.946,79.123,185.327,71.038,178.87,67.503"
+ },
+ "fill": "#FFFFFF",
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M115.87,85.503c2.365-1.63,3.646-3.553,2.826-6.826 c-16.491-8.159-17.436,11.182-1.826,8.826"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M174.87,80.503c-0.492-1.165-0.677-2.687-0.872-3.826 c3.483-0.285,7.207-0.292,10.698-0.023c3.568,7.301-6.079,7.593-10.826,5.849"
+ },
+ "stroke": {
+ "color": "#000000"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+] \ No newline at end of file
diff --git a/includes/js/dojox/gfx/demos/data/Nils.svg b/includes/js/dojox/gfx/demos/data/Nils.svg
new file mode 100644
index 0000000..48908a2
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/Nils.svg
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/">
+ <g id="nils_1_" i:isolated="yes" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFF4F004F00" enable-background="new ">
+ <g id="lowerBody" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFFFFFF4F00">
+ <g id="leftShoe" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFF4F00FFFF">
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M44.787,442.042c13.536-0.097,28.515-2.647,40.667-8.815
+ c13.064-6.631,3.188-24.604,0.553-34.404c-5.771-1.73-10.549-4.837-16.568-0.148c-4.371,3.405-6.025,11.462-2.07,15.501
+ c-3.212,7.339-17.804,1.912-23.732,6.7c-5.825,4.706-7.32,17.966,0.484,21.167"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M133.453,425.375c0.901-2.979,2.793-5.781,4.667-8"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M56.787,426.708c-2.551-2.07-3.97-5.252-5.333-8"/>
+ </g>
+ <g id="rightShoe" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFFFFFF">
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M111.453,402.042c-2.005-0.426-3.947-0.363-5.899-0.566
+ c-0.104,2.376,0.438,5.478,0.048,7.751c-0.4,2.327-1.597,4.06-2.146,6.817c-0.975,4.9,0.412,10.561,3.813,13.517
+ c3.718,3.23,8.442,2.56,12.87,3.797c4.256,1.189,7.959,3.502,12.5,4.849c9.169,2.717,20.433,7.657,25.649-4.685
+ c2.797-6.618-0.894-5.624-6.331-7.982c-4.049-1.757-6.774-4.353-10.32-7.014c-4.123-3.095-8.203-5.957-13.415-6.584
+ c-0.11-3.353,1.616-5.692,1.132-9.117c-5.299-2.318-13.883-3.984-19.233-0.116"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M62.787,424.708c-1.417-2.271-3.012-5.388-2.667-8.666"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M141.453,428.042c2.076-1.991,4.274-3.745,6-6"/>
+ </g>
+ <path id="leftLeft" i:knockout="Off" fill="#FFF0A9" stroke="#000000" d="M111.687,360.891c0.036,4.747,1.844,9.223,1.56,14.078
+ c-0.24,4.099-1.372,8.075-1.553,12.199c-0.2,4.558-1.141,9.069-1.142,13.648c0,3.48-0.275,5.533,3.084,7.379
+ c2.301,1.264,4.909,1.163,7.094-0.113c2.993-1.748,2.841-3.747,2.868-6.904c0.025-2.952,0.712-5.943,1.162-8.841
+ c0.446-2.868,0.401-5.667,0.398-8.578c-0.004-3.788,0.138-7.556,0.003-11.357c-0.118-3.318-1.49-6.782-1.279-10.093"/>
+ <path id="rightLeg" i:knockout="Off" fill="#FFF0A9" stroke="#000000" d="M74.107,353.8c-0.57,1.485-0.055,3.729-0.142,5.357
+ c-0.076,1.44-0.315,2.774-0.571,4.184c-0.786,4.316-1,8.786-1.732,13.181c-1.158,6.942-0.906,14.193-1.777,21.167
+ c-0.456,3.648,0.862,8.169,5.499,7.139c2.579-0.572,4.859-3.016,5.846-5.361c2.937-6.981-0.974-13.832-0.457-21.057
+ c0.331-4.619,2.141-8.637,3.402-13.056c0.769-2.694,1.709-5.131,1.703-7.972c-0.004-1.809,0-3.616,0-5.425"/>
+ <g id="pants" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFF4F00">
+ <path id="pants_1_" i:knockout="Off" fill="#ADA274" stroke="#000000" d="M72.453,299.375
+ c1.947,19.47-1.848,38.143-0.849,57.849c3.905,0.681,11.166,0.417,14.849-0.849c7.135-2.453,6.497-2.631,7-11
+ c0.81-13.479-2.849-20.278,12.845-17.853c-1.125,13.305-9.43,25.115-3.42,38.649c8.404-0.38,20.265,0.661,28.427-1.944
+ c0.505-10.198-1.523-17.622-2.853-26.853c-1.398-9.708,3.313-18.866-1.174-27.826c-9.218,0.693-18.358,2.747-27.722,0.798
+ c-9.863-2.054-18.89-8.623-29.104-8.972"/>
+ </g>
+ </g>
+ <g id="leftArm_1_" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFFFFFF">
+ <path id="leftArm" i:knockout="Off" fill="#FFF0A9" stroke="#000000" d="M161.453,199.375c-6.73,0.606-12.711,7.192-9.248,13.248
+ c3.358,5.87,13.618,5.538,19.021,6.979c4,1.066,16.837,3.192,19.52,5.703c3.974,3.72,5.243,15.844,5.854,20.924
+ c13.641,4.354,26.949-0.671,33.102-13.826c5.331-11.398-5.783-19.505-17.098-22.174c1.771-8.465,14.167-32.061-0.128-36.899
+ c-4.761-1.611-15.726,3.346-17.801,7.272c-3.095,5.855-0.055,15.902-0.374,22.623c-13.399,0.68-27.351-3.555-39.849-1.849"/>
+ <path i:knockout="Off" fill="#FFF0A9" stroke="#000000" d="M221.453,220.375c-4.604-1.889-17.369-6.456-21.801-1.801
+ c-4.797,5.039,1.256,14.077,6.027,16.578c4.118,2.159,20.628,4.348,24.575,1c4.999-4.241,2.906-14.993-2.801-17.777"/>
+ <path i:knockout="Off" fill="#FFF0A9" stroke="#000000" d="M214.453,253.375c-1.006,3.482-0.767,9-3.174,12.826
+ c-15.878,0.834-16.244-5.43-25.674-14.571c10.53-5.253,19.583,4.754,29.849,2.745"/>
+ <path i:knockout="Off" fill="#FFF0A9" stroke="#000000" d="M226.453,239.375c0.54,16.962-8.377,15.391-21.023,12.023
+ c-17.34-4.617-11.577-7.176,3.023-13.023"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M208.453,188.375c-4.474,0.83-8.972-0.434-11-4"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M203.453,221.375c6.112-0.45,18.967,6.649,8,10"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M195.453,258.375c3.441-0.666,5.408-2.2,4-5"/>
+ </g>
+ <g id="rightArm" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFF4F00">
+ <path i:knockout="Off" fill="#FFF0A9" stroke="#000000" d="M39.453,187.375c-3.104,7.216-3.137,14.998-7.278,21.997
+ c-5.137,8.684-9.794,6.9-17.5,12.281c-8.803,6.146-12.141,29.697-14.095,40.548c20.2,3.536,18.779-23.776,21.649-34.524
+ c0.975,13.012-0.289,26.468,0.374,39.546c2.257,0.582,6.44,0.582,8.697,0c2.04-10.494-3.53-22.034-0.852-33.546
+ c0.009,7.58-2.598,32.2,10.852,28.546c0.514-10.124-1.899-18.938-4.868-25.972c2.181,8.766,4.798,18.48,15.845,15.949
+ c6.407-12.781-3.909-15.105-8.048-25.604c-2.531-6.422,0.527-25.44,6.223-31.223"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M6.453,248.042c2.111,0,6.324-0.997,6.667,1.666"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M22.453,255.375c2.85-0.37,4.155,0.539,4.999,3.001
+ c1.085,3.168-0.233,4.173-2.999,5.332"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M31.787,255.042c3.675-0.503,7.077,4.971,3,6"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M48.453,235.708c-5.387-0.935-3.676,10.551,3.667,8.667"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M207.453,241.375c2.63,1.686,2.368,4.909,1.884,7.884
+ c-0.744,0.175-1.23,0.456-1.884,0.783"/>
+ </g>
+ <g id="shirt" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFFFFFF4F00">
+ <path id="mainShirt" i:knockout="Off" fill="#4867FF" stroke="#000000" stroke-width="2" d="M39.453,189.375
+ c0.777-3.467,1.211-7.217,1.151-10.849c14.871-1.403,32.372-7.656,46.875-11.125c9.423-2.254,31.959-20.14,39.244-11.079
+ c3.778,4.7,2.066,16.102,5.456,22.08c2.827,4.986,9.093,12.445,13.003,16.217c5.193,5.009,15.695-3.271,18.271,2.754
+ c3.024,7.075-0.511,20.739-10.02,18.016c-5.084-1.456-12.238-5.093-15.228-9.769c-4.055-6.341-8.831-13.012-10.53-19.167
+ c-0.713,10.697,1.173,22.369,2.726,32.92c1.637,11.128,1.886,22.261,3.052,34c2.02,20.336,6.915,42.053,10.845,61.855
+ c-14.599,4.091-47.868-3.832-47.868-3.832s-14.457-3.595-21.2-5.801c-8.131-2.661-21.777-11.223-13.777-11.223
+ s-3.063-9.756,2.468-40.878s14.003-39.61,19.806-56.122c1.387-3.946,2.399-8.004,4.375-11.845
+ c-17.565,1.273-26.117,7.964-40.475,16.742c-2.413-9.11-9.707-14.336-17.174-18.897"/>
+ <path id="highlight" i:knockout="Off" fill="#4867FF" stroke="#000000" stroke-width="2" d="M99.453,179.375
+ c-5.364,2.937-10.603,8.065-17,8"/>
+ <g id="logo" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFF4F00FFFF">
+ </g>
+ </g>
+ <g id="heads" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFF4F004F00">
+ <g id="head1" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFF4F00">
+ <path id="hair_1_" i:knockout="Off" fill="#605542" stroke="#000000" d="M60.453,97.375c-3.965-0.012-7.98,0.045-11.897-0.147
+ c2.645-5.735,10.791-8.417,14.794-13.65c-2.384,0.19-5.083-0.61-7.543-0.154c2.395-1.359,4.008-3.487,6.347-4.846
+ c-2.993-0.207-6.326-0.467-9.399-0.18c2.893-0.874,5.243-2.063,7.821-3.05c-0.92-0.166-4.625-2.732-6.772-4.221
+ c5.187-4.255,12.317-5.834,17.573-8.534c-2.844-0.13-5.037-1.713-7.75-2.393c-0.424-7.244-1.302-14.461-1.223-21.475
+ c2.166,2.761,3.541,5.976,4.849,8.546c-0.996-11.489,4.773-13.594,13.025-18.797c0.403,1.91,1.943,3.845,2.229,5.546
+ c1.27-13.312,22.924-28.644,34.016-33.272c0.039,6.247-2.955,11.957-5.365,17.475c-0.365,0.375-0.375,0.366-0.028-0.028
+ c5.849-6.92,14-8.882,22.143-10.721c-1.215,5.635-5.28,10.684-6.698,16.602c6.258-10.069,20.421-4.135,27.949-11.351
+ c-1.011,3.251-2.028,6.254-3.143,9.276c7.035-8.774,15.902-11.37,25.894-14.499c-0.668,7.995-10.243,18.061-0.822,20.872
+ c8.889,2.653,17.435-7.31,26.698-6.075c-2.976,1.954-5.822,4.12-8.614,6.345c7.596,2.01,18.243,0.852,26.614,0.658
+ c-4.125,3.304-9.116,7.352-9.593,12.943c3.896-0.826,8.6-1.318,12.741-0.725c-1.013,1.726-1.479,5.845-2.718,7.678
+ c3.136-0.265,6.17,1.053,8.519,1.452c-3.019,0.804-5.247,3.16-7.566,4.52c3.765,0.755,7.282,2.001,10.844,3.398
+ c-3.322,1.78-5.724,5.475-4.776,9.657c0.798,0.374,2.536,0.977,2.995,1.147c-6.481,3.645-21.331-1.522-28.945-2.752
+ c-13.967-2.257-27.844-4.641-41.913-6.244c-17.039-1.941-37.716-3.446-54.359,1.025C83.983,67.42,68.871,76.651,58.453,98.375"
+ />
+ <path id="neck" i:knockout="Off" fill="#FFF0A9" stroke="#000000" d="M108.453,132.375c0.902,8.412-0.835,20.235-3.849,27.797
+ c4.164,2.769,15.721,4.339,19.868,0c3.538-3.701,1.964-17.522,1.98-22.797"/>
+ <g id="leftEar_1_" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFFFFFF">
+ <path id="leftEar" i:knockout="Off" fill="#FFF0A9" stroke="#000000" d="M232.453,76.375c10.186-6.915,21.465,6.994,19.052,17
+ c-2.781,11.53-20.253,15.518-27.052,5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M245.453,91.375c-0.398-2.267-1.99-4.77-3.171-6.829
+ c-2.738-0.936-5.713-1.545-8.829-1.171"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M238.453,90.375c1.863-0.367,3.589-1.433,5-3"/>
+ </g>
+ <path id="headShape" i:knockout="Off" fill="#FFF0A9" stroke="#000000" d="M116.453,35.375
+ c-13.417,2.219-31.83,24.639-39.777,35.055c-8.128,10.652-24.737,25.747-20.219,39.945
+ c5.161,16.221,22.089,14.526,34.025,19.972c15.448,7.047,30.645,11.875,46.749,14.251c18.146,2.676,27.633,0.161,44.223-7.972
+ c15.701-7.697,29.862-9.589,41.801-24.303c8.182-10.084,15.033-28.733,8.174-38.923c-6.159-9.151-21.79-19.289-31.201-25.75
+ c-12.144-8.339-26.876-10.032-41-11.274c-15.007-1.32-33.207-3.056-47.774,1"/>
+ <g id="rightEar_1_" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFF4F00FFFF">
+ <path id="rightEar" i:knockout="Off" fill="#FFF0A9" stroke="#000000" d="M66.453,94.375
+ c-10.188-4.124-23.701-5.729-27.774,7.226c-4.779,15.198,14.506,23.077,25.774,15.774"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M42.453,106.375c4.149-4.954,11.06-7.737,16-10"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" d="M48.453,100.375c1.337,3.541,2.787,6.955,5,10"/>
+ </g>
+ <path id="adamsApple" i:knockout="Off" fill="none" stroke="#000000" d="M113.453,152.375c-0.526-2.327,1.546-3.837,5-4"/>
+ </g>
+ </g>
+ <g id="expressions" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#800080008000">
+ <g id="confused" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#000000000000">
+ <g id="mouth_1_" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F008000FFFF">
+ <path id="mouth" i:knockout="Off" fill="none" stroke="#000000" d="M102.148,120.014c13.398-6.9,33.568-7.688,49-10.026
+ c12.555-1.903,36.519-2.575,44,9.026"/>
+ <path id="tooth_1_" i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M178.148,109.014
+ c-0.563-2.655-0.017-6.196,0.151-8.849c4.788-0.944,9.637,0.768,13.675,3.022c0.664,3.187,0.065,6.267-1.826,8.826"/>
+ <path id="tooth" i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M168.148,108.014c-2.021-7.958,5.04-7.752,10.826-6.826
+ c1.286,2.446,1.752,5.863,1.022,8.675c-3.801,0.292-8.049,0.308-10.849-0.849"/>
+ </g>
+ <g id="eyes" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F008000FFFF">
+ <path id="rightEye" i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M121.148,52.014
+ c-6.562,8.145-20.057,16.28-21.023,26.977c-1.104,12.227,10.759,15.164,21.02,11.798c18.8-6.168,24.482-40.499,0.004-39.774"/>
+ <path id="pupilRight" i:knockout="Off" stroke="#000000" d="M112.148,61.014c-7.625,3.067-4.047,12.428,3.826,10.826
+ C118.354,67.432,118.046,61.261,112.148,61.014"/>
+ <path id="leftEye" i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M184.148,55.014c-13.391-8.758-17.664,28.504,5,25.996
+ c10.862-1.201,14.124-12.581,8.004-19.996c-6.121-7.415-14.988-4.947-22.004-8"/>
+ <path id="pupilLeft" i:knockout="Off" stroke="#000000" d="M176.148,54.014c-2.04,2.896-2.657,6.347-1.849,9.849
+ C184.707,66.621,182.108,56.322,176.148,54.014"/>
+ </g>
+ </g>
+ <g id="confused2" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#000000000000" display="none">
+ <path id="rightEye_1_" i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M121.148,52.014
+ c-6.562,8.145-20.057,16.28-21.023,26.977c-1.104,12.227,10.759,15.164,21.02,11.798c18.8-6.168,24.482-40.499,0.004-39.774"/>
+ <path id="pupilRight_1_" i:knockout="Off" display="inline" stroke="#000000" d="M112.148,61.014
+ c-7.625,3.067-4.047,12.428,3.826,10.826C118.354,67.432,118.046,61.261,112.148,61.014"/>
+ <path id="leftEye_1_" i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M184.148,55.014
+ c-13.391-8.758-17.664,28.504,5,25.996c10.862-1.201,14.124-12.581,8.004-19.996c-6.121-7.415-14.988-4.947-22.004-8"/>
+ <path id="pupilLeft_1_" i:knockout="Off" display="inline" stroke="#000000" d="M176.148,54.014
+ c-2.04,2.896-2.657,6.347-1.849,9.849C184.707,66.621,182.108,56.322,176.148,54.014"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M114.934,118.74
+ c18.933-4.896,31.704-2.456,49.826,1.171c6.734,1.348,17.654,7.566,23.408,0.323c5.436-6.841-0.011-16.179-7.237-17.994"/>
+ </g>
+ <g id="talking" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#000000000000" display="none">
+ <path i:knockout="Off" display="inline" stroke="#000000" d="M150.536,116.479c0.413,18.115,48.746,18.222,37.276-7.278
+ c-10.396-1.757-28.836,2.451-38.776,5.778"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M103.453,104.875c-2.277,2.169-1.729,7.324-4.849,8
+ c8.889,3.074,18.975,7.877,28.849,6.998c6.759-0.602,18.439-1.511,23.5-5.998"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M104.453,64.875
+ c-6.218-0.224-17.093,9.247-13.875,15.887c2.822,5.825,15.087,4.174,20.375,3.113c4.505-0.904,7.783-1.37,9.889-6.123
+ c1.107-2.499,2.855-9.088,1.623-11.889c-2.859-6.496-15.374-3.248-19.512,0.012"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M176.953,59.875
+ c-4.742,8.403,0.46,13.596,6.486,18.376c4.779,3.791,15.903,8.529,19.512,0.622c8.012-17.554-22.026-19.554-32.498-17.887
+ c-0.345,0.055-1.151,0.291-1.5,0.389"/>
+ <path i:knockout="Off" display="inline" stroke="#000000" d="M98.953,66.875c-6.969-2.545-10.165,5.418-3.002,8.05
+ c2.178-2.129,5.596-6.88,2.502-9.05"/>
+ <path i:knockout="Off" display="inline" stroke="#000000" d="M178.453,60.875c-5.534,0.708-5.259,9.173,0.5,7.387
+ c6.145-1.906,5.217-9.047-1.5-8.387"/>
+ </g>
+ <g id="talking2" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#000000000000" display="none">
+ <path i:knockout="Off" display="inline" stroke="#000000" d="M102.87,94.503c-2.279,15.037-5.934,27.828,15.027,23.027
+ c15.334-3.512,25.379-13.239,28.973-28.027"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M92.87,104.503
+ c4.248-16.004,34.717-10.765,47.052-11.948c8.414-0.807,15.879-1.97,24.948-1.055c8.295,0.837,19.3,2.941,27-0.997"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M84.87,73.503c2.341-8.752,12.467-12.772,19-18"/>
+ <path i:knockout="Off" display="inline" fill="none" stroke="#000000" d="M181.87,59.503c8.968-3.27,16.681,2.245,25,3"/>
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M98.87,68.503
+ c-7.218,11.165,3.031,17.234,13.003,17.997c13.201,1.009,21.125-8.677,18.845-21.842c-11.637-0.604-21.219,1.818-31.849,2.845"
+ />
+ <path i:knockout="Off" display="inline" fill="#FFFFFF" stroke="#000000" d="M178.87,67.503
+ c-9.045,2.007-6.264,11.616-1.249,15.249c3.778,2.737,13.479,4.477,18.249,2.528C210.946,79.123,185.327,71.038,178.87,67.503"
+ />
+ <path i:knockout="Off" display="inline" stroke="#000000" d="M115.87,85.503c2.365-1.63,3.646-3.553,2.826-6.826
+ c-16.491-8.159-17.436,11.182-1.826,8.826"/>
+ <path i:knockout="Off" display="inline" stroke="#000000" d="M174.87,80.503c-0.492-1.165-0.677-2.687-0.872-3.826
+ c3.483-0.285,7.207-0.292,10.698-0.023c3.568,7.301-6.079,7.593-10.826,5.849"/>
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/includes/js/dojox/gfx/demos/data/buratino-bg.png b/includes/js/dojox/gfx/demos/data/buratino-bg.png
new file mode 100644
index 0000000..ee50a15
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/buratino-bg.png
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/data/buratino-head.png b/includes/js/dojox/gfx/demos/data/buratino-head.png
new file mode 100644
index 0000000..d576873
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/buratino-head.png
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/data/buratino-left-arm.png b/includes/js/dojox/gfx/demos/data/buratino-left-arm.png
new file mode 100644
index 0000000..1e620f3
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/buratino-left-arm.png
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/data/buratino-left-leg.png b/includes/js/dojox/gfx/demos/data/buratino-left-leg.png
new file mode 100644
index 0000000..1ae5600
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/buratino-left-leg.png
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/data/buratino-lollipop.png b/includes/js/dojox/gfx/demos/data/buratino-lollipop.png
new file mode 100644
index 0000000..9a52c1e
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/buratino-lollipop.png
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/data/buratino-nose-large.png b/includes/js/dojox/gfx/demos/data/buratino-nose-large.png
new file mode 100644
index 0000000..a0e38fd
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/buratino-nose-large.png
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/data/buratino-nose-medium.png b/includes/js/dojox/gfx/demos/data/buratino-nose-medium.png
new file mode 100644
index 0000000..f38e205
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/buratino-nose-medium.png
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/data/buratino-right-arm.png b/includes/js/dojox/gfx/demos/data/buratino-right-arm.png
new file mode 100644
index 0000000..206bdb1
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/buratino-right-arm.png
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/data/buratino-right-leg.png b/includes/js/dojox/gfx/demos/data/buratino-right-leg.png
new file mode 100644
index 0000000..cd0e172
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/buratino-right-leg.png
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/data/buratino-torso.png b/includes/js/dojox/gfx/demos/data/buratino-torso.png
new file mode 100644
index 0000000..64c2336
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/buratino-torso.png
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/data/buratino.jpg b/includes/js/dojox/gfx/demos/data/buratino.jpg
new file mode 100644
index 0000000..95aaf05
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/buratino.jpg
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/data/buratino.json b/includes/js/dojox/gfx/demos/data/buratino.json
new file mode 100644
index 0000000..45ed668
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/buratino.json
@@ -0,0 +1,12 @@
+[
+ {name: "bg", shape: {type: "image", width: 321, height: 355, src: "data/buratino-bg.png"}},
+ {name: "left-arm", shape: {type: "image", width: 111, height: 40, src: "data/buratino-left-arm.png"}},
+ {name: "right-arm", shape: {type: "image", width: 59, height: 130, src: "data/buratino-right-arm.png"}},
+ {name: "left-leg", shape: {type: "image", width: 152, height: 99, src: "data/buratino-left-leg.png"}},
+ {name: "right-leg", shape: {type: "image", width: 104, height: 158, src: "data/buratino-right-leg.png"}},
+ {name: "torso", shape: {type: "image", width: 90, height: 130, src: "data/buratino-torso.png"}},
+ {name: "head", shape: {type: "image", width: 116, height: 139, src: "data/buratino-head.png"}},
+ {name: "nose-medium", shape: {type: "image", width: 50, height: 43, src: "data/buratino-nose-medium.png"}},
+ {name: "nose-large", shape: {type: "image", width: 70, height: 66, src: "data/buratino-nose-large.png"}},
+ {name: "lollipop", shape: {type: "image", width: 82, height: 144, src: "data/buratino-lollipop.png"}}
+]
diff --git a/includes/js/dojox/gfx/demos/data/svg2gfx.xsl b/includes/js/dojox/gfx/demos/data/svg2gfx.xsl
new file mode 100644
index 0000000..90a463f
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/svg2gfx.xsl
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Super simple XSLT to convert Nils.svg and Lars.svg to our format -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <xsl:output method="text" version="1.0" encoding="UTF-8"/>
+ <xsl:template name="fill">
+ <xsl:param name="node"/>
+ <xsl:if test="count($node/@fill) &gt; 0">
+ <xsl:text>fill: "</xsl:text>
+ <xsl:value-of select="$node/@fill"/>
+ <xsl:text>",</xsl:text>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="stroke">
+ <xsl:param name="node"/>
+ <xsl:text>stroke: {</xsl:text>
+ <xsl:if test="count($node/@stroke) &gt; 0">
+ <xsl:text>color: "</xsl:text>
+ <xsl:value-of select="$node/@stroke"/>
+ <xsl:text>",</xsl:text>
+ </xsl:if>
+ <xsl:if test="count($node/@stroke-width) &gt; 0">
+ <xsl:text>width: "</xsl:text>
+ <xsl:value-of select="$node/@stroke-width"/>
+ <xsl:text>",</xsl:text>
+ </xsl:if>
+ <xsl:if test="count($node/@stroke-linecap) &gt; 0">
+ <xsl:text>cap: "</xsl:text>
+ <xsl:value-of select="$node/@stroke-linecap"/>
+ <xsl:text>",</xsl:text>
+ </xsl:if>
+ <xsl:if test="count($node/@stroke-linejoin) &gt; 0">
+ <xsl:text>join: "</xsl:text>
+ <xsl:value-of select="$node/@stroke-linejoin"/>
+ <xsl:text>",</xsl:text>
+ </xsl:if>
+ <xsl:text>},</xsl:text>
+ </xsl:template>
+ <xsl:template match="g">
+ <xsl:text>{</xsl:text>
+ <xsl:if test="count(@id) &gt; 0">
+ <xsl:text>name: "</xsl:text>
+ <xsl:value-of select="@id"/>
+ <xsl:text>",</xsl:text>
+ </xsl:if>
+ <xsl:text>children: [</xsl:text>
+ <xsl:apply-templates select="g|path"/>
+ <xsl:text>]},</xsl:text>
+ </xsl:template>
+ <xsl:template match="path">
+ <xsl:text>{</xsl:text>
+ <xsl:if test="count(@id) &gt; 0">
+ <xsl:text>name: "</xsl:text>
+ <xsl:value-of select="@id"/>
+ <xsl:text>",</xsl:text>
+ </xsl:if>
+ <xsl:text>shape: {type: "path", path: "</xsl:text>
+ <xsl:value-of select="@d"/>
+ <xsl:text>"},</xsl:text>
+ <xsl:call-template name="fill">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ <xsl:call-template name="stroke">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ <xsl:text>},</xsl:text>
+ </xsl:template>
+ <xsl:template match="svg">
+ <xsl:text>[</xsl:text>
+ <xsl:apply-templates select="g|path"/>
+ <xsl:text>]</xsl:text>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/includes/js/dojox/gfx/demos/data/transform.json b/includes/js/dojox/gfx/demos/data/transform.json
new file mode 100644
index 0000000..60bd466
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/data/transform.json
@@ -0,0 +1,1567 @@
+[
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "line",
+ "x1": 0,
+ "y1": 0,
+ "x2": 500,
+ "y2": 0
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 0,
+ "y1": 0,
+ "x2": 0,
+ "y2": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 0,
+ "y1": 50,
+ "x2": 500,
+ "y2": 50
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 50,
+ "y1": 0,
+ "x2": 50,
+ "y2": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 0,
+ "y1": 100,
+ "x2": 500,
+ "y2": 100
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 100,
+ "y1": 0,
+ "x2": 100,
+ "y2": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 0,
+ "y1": 150,
+ "x2": 500,
+ "y2": 150
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 150,
+ "y1": 0,
+ "x2": 150,
+ "y2": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 0,
+ "y1": 200,
+ "x2": 500,
+ "y2": 200
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 200,
+ "y1": 0,
+ "x2": 200,
+ "y2": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 0,
+ "y1": 250,
+ "x2": 500,
+ "y2": 250
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 250,
+ "y1": 0,
+ "x2": 250,
+ "y2": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 0,
+ "y1": 300,
+ "x2": 500,
+ "y2": 300
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 300,
+ "y1": 0,
+ "x2": 300,
+ "y2": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 0,
+ "y1": 350,
+ "x2": 500,
+ "y2": 350
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 350,
+ "y1": 0,
+ "x2": 350,
+ "y2": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 0,
+ "y1": 400,
+ "x2": 500,
+ "y2": 400
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 400,
+ "y1": 0,
+ "x2": 400,
+ "y2": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 0,
+ "y1": 450,
+ "x2": 500,
+ "y2": 450
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 450,
+ "y1": 0,
+ "x2": 450,
+ "y2": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 0,
+ "y1": 500,
+ "x2": 500,
+ "y2": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ },
+ {
+ "shape": {
+ "type": "line",
+ "x1": 500,
+ "y1": 0,
+ "x2": 500,
+ "y2": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ }
+ }
+ ],
+ "name": "grid"
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "rect",
+ "x": 0,
+ "y": 0,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 0,
+ "y": 100,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 0,
+ "y": 200,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 0,
+ "y": 300,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 0,
+ "y": 400,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 50,
+ "y": 50,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 50,
+ "y": 150,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 50,
+ "y": 250,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 50,
+ "y": 350,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 50,
+ "y": 450,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 100,
+ "y": 0,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 100,
+ "y": 100,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 100,
+ "y": 200,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 100,
+ "y": 300,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 100,
+ "y": 400,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 150,
+ "y": 50,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 150,
+ "y": 150,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 150,
+ "y": 250,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 150,
+ "y": 350,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 150,
+ "y": 450,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 200,
+ "y": 0,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 200,
+ "y": 100,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 200,
+ "y": 200,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 200,
+ "y": 300,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 200,
+ "y": 400,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 250,
+ "y": 50,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 250,
+ "y": 150,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 250,
+ "y": 250,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 250,
+ "y": 350,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 250,
+ "y": 450,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 300,
+ "y": 0,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 300,
+ "y": 100,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 300,
+ "y": 200,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 300,
+ "y": 300,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 300,
+ "y": 400,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 350,
+ "y": 50,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 350,
+ "y": 150,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 350,
+ "y": 250,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 350,
+ "y": 350,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 350,
+ "y": 450,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 400,
+ "y": 0,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 400,
+ "y": 100,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 400,
+ "y": 200,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 400,
+ "y": 300,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 400,
+ "y": 400,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 450,
+ "y": 50,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 450,
+ "y": 150,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 450,
+ "y": 250,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 450,
+ "y": 350,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 450,
+ "y": 450,
+ "width": 50,
+ "height": 50,
+ "r": 0
+ },
+ "fill": {
+ "g": 0,
+ "b": 0,
+ "a": 0.1,
+ "r": 255
+ }
+ }
+ ],
+ "name": "checkerboard"
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 0,
+ "y": 0,
+ "width": 100,
+ "height": 100,
+ "r": 0
+ },
+ "transform": {
+ "dx": 100,
+ "dy": 100,
+ "xx": 1,
+ "xy": 0,
+ "yx": 0,
+ "yy": 1
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ },
+ "fill": {
+ "type": "linear",
+ "x1": 0,
+ "y1": 0,
+ "x2": 100,
+ "y2": 100,
+ "colors": [
+ {
+ "offset": 0,
+ "color": {
+ "r": 0,
+ "g": 128,
+ "b": 0,
+ "a": 1
+ }
+ },
+ {
+ "offset": 0.5,
+ "color": {
+ "g": 0,
+ "b": 0,
+ "r": 255,
+ "a": 1
+ }
+ },
+ {
+ "offset": 1,
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 255,
+ "a": 1
+ }
+ }
+ ]
+ },
+ "name": "rect with color gradient"
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 0,
+ "y": 0,
+ "width": 100,
+ "height": 100,
+ "r": 0
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ },
+ "fill": {
+ "type": "linear",
+ "x1": 0,
+ "y1": 0,
+ "x2": 100,
+ "y2": 100,
+ "colors": [
+ {
+ "offset": 0,
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ }
+ },
+ {
+ "offset": 1,
+ "color": {
+ "r": 255,
+ "g": 255,
+ "b": 255,
+ "a": 1
+ }
+ }
+ ]
+ },
+ "name": "rect with gray gradient"
+ },
+ {
+ "children": [
+ {
+ "shape": {
+ "type": "rect",
+ "x": 200,
+ "y": 200,
+ "width": 100,
+ "height": 100,
+ "r": 0
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ },
+ "fill": {
+ "r": 0,
+ "g": 128,
+ "b": 0,
+ "a": 1
+ },
+ name: "green rect"
+ },
+ {
+ "shape": {
+ "type": "rect",
+ "x": 0,
+ "y": 0,
+ "width": 100,
+ "height": 100,
+ "r": 0
+ },
+ "transform": {
+ "xx": 0.8660254037844387,
+ "xy": 0.49999999999999994,
+ "yx": -0.49999999999999994,
+ "yy": 0.8660254037844387,
+ "dx": 281.69872981077805,
+ "dy": 231.69872981077808
+ },
+ "fill": {
+ "r": 0,
+ "g": 0,
+ "b": 255,
+ "a": 1
+ },
+ name: "blue rect"
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M 300 100L 400 200L 400 300L 300 400C 400 300 400 200 300 100"
+ },
+ "transform": {
+ "xx": 1,
+ "xy": 0,
+ "yx": 0,
+ "yy": 1,
+ "dx": 0,
+ "dy": 0
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 0,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 1,
+ "cap": "butt",
+ "join": 4
+ },
+ name: "black path"
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M 300 100L 400 200L 400 300L 300 400C 400 300 400 200 300 100"
+ },
+ "transform": {
+ "dx": 100,
+ "xx": 1,
+ "xy": 0,
+ "yx": 0,
+ "yy": 1,
+ "dy": 0
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "g": 0,
+ "b": 0,
+ "r": 255,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 2,
+ "cap": "butt",
+ "join": 4
+ },
+ name: "red path"
+ },
+ {
+ "shape": {
+ "type": "path",
+ "path": "M 300 100l 100 100l 0 100l-100 100c 100-100 100-200 0-300"
+ },
+ "transform": {
+ "xx": -1,
+ "xy": -1.2246063538223773e-16,
+ "yx": 1.2246063538223773e-16,
+ "yy": -1,
+ "dx": 500,
+ "dy": 500
+ },
+ "stroke": {
+ "type": "stroke",
+ "color": {
+ "r": 0,
+ "g": 0,
+ "b": 255,
+ "a": 1
+ },
+ "style": "solid",
+ "width": 2,
+ "cap": "butt",
+ "join": 4
+ },
+ name: "blue path"
+ }
+ ],
+ "transform": {
+ "xx": 0.9659258262890683,
+ "xy": 0.25881904510252074,
+ "yx": -0.25881904510252074,
+ "yy": 0.9659258262890683,
+ "dx": -56.1862178478973,
+ "dy": 73.22330470336311
+ },
+ "name": "rotated group"
+ }
+]
diff --git a/includes/js/dojox/gfx/demos/images/clock_face.jpg b/includes/js/dojox/gfx/demos/images/clock_face.jpg
new file mode 100644
index 0000000..12f1903
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/images/clock_face.jpg
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/images/clock_face_black.jpg b/includes/js/dojox/gfx/demos/images/clock_face_black.jpg
new file mode 100644
index 0000000..dbef7cd
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/images/clock_face_black.jpg
Binary files differ
diff --git a/includes/js/dojox/gfx/demos/inspector.html b/includes/js/dojox/gfx/demos/inspector.html
new file mode 100644
index 0000000..034fa3b
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/inspector.html
@@ -0,0 +1,165 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Inspect DojoX GFX JSON</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+ td.cell { padding: 1em 1em 0em 0em; }
+ td.note { font-size: 80%; }
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.move");
+dojo.require("dojox.gfx.utils");
+
+surface = null;
+container_pos = null;
+mover = null;
+
+init = function(){
+ // initialize graphics
+ var container = dojo.byId("gfx");
+ surface = dojox.gfx.createSurface(container, 500, 500);
+ container_pos = dojo.coords(container, true);
+ // wire UI
+ dojo.connect(dojo.byId("load"), "onclick", onLoad);
+ dojo.connect(dojo.byId("add"), "onclick", onAdd);
+ // handle moves
+ dojo.subscribe("/gfx/move/start", function(m){ mover = m; });
+ dojo.subscribe("/gfx/move/stop", function(){ mover = null; });
+ // handle shape operations
+ dojo.connect(document, "onkeydown", onKeyDown);
+ // cancel text selection and text dragging
+ dojo.connect(container, "ondragstart", dojo, "stopEvent");
+ dojo.connect(container, "onselectstart", dojo, "stopEvent");
+};
+
+onLoad = function(){
+ var s = dojo.byId("source");
+ if(!s.value){
+ alert("Name of the file is required.");
+ return;
+ }
+ dojo.xhrGet({
+ url: s.value,
+ preventCache: true,
+ handleAs: "json",
+ load: loadObjects,
+ error: function(r){ alert("Error: " + r); }
+ });
+};
+
+mainObject = null;
+names = [];
+
+loadObjects = function(r){
+ if(!r){
+ alert("Wrong JSON object. Did you type the file name correctly?");
+ return;
+ }
+ mainObject = r;
+ // clear old object names
+ names = [];
+ var s = dojo.byId("names"), ni = dojo.byId("names_info");
+ ni.innerHTML = "";
+ while(s.childNodes.length){ s.removeChild(s.lastChild); }
+ // find new names
+ findNames(s, dojo.byId("named").checked, "", mainObject);
+ ni.innerHTML = " (" + names.length + ")";
+};
+
+findNames = function(selector, named_only, prefix, o){
+ if(o instanceof Array){
+ for(var i = 0; i < o.length; ++i){
+ findNames(selector, named_only, prefix, o[i]);
+ }
+ return;
+ }
+ if(named_only && !("name" in o)) return;
+ var name = ("name" in o) ? o.name : "*",
+ full = prefix ? prefix + "/" + name : name,
+ opt = document.createElement("option");
+ opt.value = names.length;
+ opt.innerHTML = full;
+ names.push(o);
+ selector.appendChild(opt);
+ if("children" in o){
+ findNames(selector, named_only, full, o.children);
+ }
+};
+
+onAdd = function(){
+ var s = dojo.byId("names");
+ for(var i = 0; i < s.options.length; ++i){
+ var opt = s.options[i];
+ if(!opt.selected) continue;
+ var object = names[Number(opt.value)];
+ var group = surface.createGroup();
+ dojox.gfx.utils.deserialize(group, object);
+ new dojox.gfx.Moveable(group); // make it moveable as whole
+ }
+};
+
+// event handling
+
+onKeyDown = function(e){
+ if(!mover) return;
+ switch(e.keyCode){
+ case "f".charCodeAt(0): case "F".charCodeAt(0):
+ mover.shape.moveToFront();
+ break;
+ case "b".charCodeAt(0): case "B".charCodeAt(0):
+ mover.shape.moveToBack();
+ break;
+ case "q".charCodeAt(0): case "Q".charCodeAt(0):
+ mover.shape.applyLeftTransform(dojox.gfx.matrix.rotategAt(-15, mover.lastX - container_pos.x, mover.lastY - container_pos.y));
+ break;
+ case "w".charCodeAt(0): case "W".charCodeAt(0):
+ mover.shape.applyLeftTransform(dojox.gfx.matrix.rotategAt(15, mover.lastX - container_pos.x, mover.lastY - container_pos.y));
+ break;
+ case "d".charCodeAt(0): case "D".charCodeAt(0):
+ mover.shape.parent.remove(mover.shape);
+ mover.shape.rawNode = null;
+ mover.destroy();
+ break;
+ }
+ dojo.stopEvent(e);
+};
+
+dojo.addOnLoad(init);
+</script>
+</head>
+<body>
+ <h1>Inspect DojoX GFX JSON</h1>
+ <p>Help: load a file, select an object, and add it, move it around, or apply operations to selected items:<br />
+ F &mdash; bring to front, B &mdash; bring to back, Q &mdash; rotate CCW, W &mdash; rotate CW, D &mdash; delete.<br />
+ (all operations work on currently dragged item).</p>
+ <p><strong>VML note:</strong> VML doesn't process PNG images with opacity correctly.</p>
+ <table><tr>
+ <td align="left" valign="top" class="cell"><div id="gfx" style="width: 500px; height: 500px; border: solid 1px black;"></div></td>
+ <td align="left" valign="top" class="cell"><table>
+ <tr><td>Source:</td></tr>
+ <tr><td><input type="text" id="source" value="data/Lars.json" size="30" />&nbsp;<button id="load">Load</button><br />
+ <input type="checkbox" id="named" checked="checked" />&nbsp;<label for="named">Load only named objects</label></td></tr>
+ <tr><td class="note"><em>Available sources:</em></td></tr>
+ <tr><td class="note"><em>data/Lars.json &mdash; vectors from SVG</em></td></tr>
+ <tr><td class="note"><em>data/Nils.json &mdash; vectors from SVG</em></td></tr>
+ <tr><td class="note"><em>data/LarsDreaming.json &mdash; vectors from SVG</em></td></tr>
+ <tr><td class="note"><em>data/buratino.json &mdash; images</em></td></tr>
+ <tr><td class="note"><em>data/transform.json &mdash; from dojox.gfx</em></td></tr>
+ <tr><td>&nbsp;</td></tr>
+ <tr><td>Objects<span id="names_info"></span>:</td></tr>
+ <tr><td><select id="names" multiple="multiple" size="10" style="width: 300px;"></select></td></tr>
+ <tr><td><button id="add">Add Selected</button></td></tr>
+ <tr><td class="note"><div style="width: 300px;">Object names are hierarchical and separated by "/". Adding a selected object creates a group for this object.
+ A higher-level object (a group) always includes lower-level objects as children.</div></td></tr>
+ </table></td>
+ </tr></table>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/demos/lion.html b/includes/js/dojox/gfx/demos/lion.html
new file mode 100644
index 0000000..445945c
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/lion.html
@@ -0,0 +1,235 @@
+<html>
+<head>
+<title>dojox.gfx: Lion</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/themes/tundra/tundra.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<!--
+<script type="text/javascript" src="../_base.js"></script>
+<script type="text/javascript" src="../shape.js"></script>
+<script type="text/javascript" src="../path.js"></script>
+<script type="text/javascript" src="../arc.js"></script>
+-->
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../canvas.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+
+dojo.require("dijit.form.Slider");
+dojo.require("dojo.parser"); // scan page for widgets
+
+dojo.require("dojox.gfx");
+
+var rotation = 0, scaling = 1;
+var surface, g, m = dojox.gfx.matrix;
+var initial_matrix = m.normalize([m.rotateg(10), m.translate(300, 100)]);
+
+var updateMatrix = function(){
+ if(g){ g.setTransform([m.rotategAt(rotation, 350, 350), m.scaleAt(scaling, 350, 350), initial_matrix]); }
+};
+
+var rotatingEvent = function(value){
+ rotation = value;
+ dojo.byId("rotationValue").innerHTML = rotation;
+ updateMatrix();
+};
+
+var scalingEvent = function(value){
+ scaling = Math.exp(Math.LN10 * (value - 1));
+ dojo.byId("scaleValue").innerHTML = scaling.toFixed(3);
+ updateMatrix();
+};
+
+makeShapes = function(){
+ surface = dojox.gfx.createSurface(dojo.byId("gfx_holder"), 700, 700);
+ surface.createRect({x: 0, y: 0, width: 700, height: 700}).setFill("#eee");
+ g = surface.createGroup().setTransform(initial_matrix);
+ g.createPolyline([69,18,82,8,99,3,118,5,135,12,149,21,156,13,165,9,177,13,183,28,180,50,164,91,155,107,154,114,151,121,141,127,139,136,155,206,157,251,126,342,133,357,128,376,83,376,75,368,67,350,61,350,53,369,4,369,2,361,5,354,12,342,16,321,4,257,4,244,7,218,9,179,26,127,43,93,32,77,30,70,24,67,16,49,17,35,18,23,30,12,40,7,53,7,62,12]).setFill("#f2cc99");
+ g.createPolyline([142,79,136,74,138,82,133,78,133,84,127,78,128,85,124,80,125,87,119,82,119,90,125,99,125,96,128,100,128,94,131,98,132,93,135,97,136,93,138,97,139,94,141,98,143,94,144,85]).setFill("#e5b27f");
+ g.createPolyline([127,101,132,100,137,99,144,101,143,105,135,110]).setFill("#eb8080");
+ g.createPolyline([178,229,157,248,139,296,126,349,137,356,158,357,183,342,212,332,235,288,235,261,228,252,212,250,188,251]).setFill("#f2cc99");
+ var c = new dojo.Color("#9c826b");
+ g.createPolyline([56,229,48,241,48,250,57,281,63,325,71,338,81,315,76,321,79,311,83,301,75,308,80,298,73,303,76,296,71,298,74,292,69,293,74,284,78,278,71,278,74,274,68,273,70,268,66,267,68,261,60,266,62,259,65,253,57,258,59,251,55,254,55,248,60,237,54,240,58,234,54,236]).setFill(c);
+ g.createPolyline([74,363,79,368,81,368,85,362,89,363,92,370,96,373,101,372,108,361,110,371,113,373,116,371,120,358,122,363,123,371,126,371,129,367,132,357,135,361,130,376,127,377,94,378,84,376,76,371]).setFill(c);
+ g.createPolyline([212,250,219,251,228,258,236,270,235,287,225,304,205,332,177,343,171,352,158,357,166,352,168,346,168,339,165,333,155,327,155,323,161,320,165,316,169,316,167,312,171,313,168,308,173,309,170,306,177,306,175,308,177,311,174,311,176,316,171,315,174,319,168,320,168,323,175,327,179,332,183,326,184,332,189,323,190,328,194,320,194,325,199,316,201,320,204,313,206,316,208,310,211,305,219,298,226,288,229,279,228,266,224,259,217,253]).setFill(c);
+ g.createPolyline([151,205,151,238,149,252,141,268,128,282,121,301,130,300,126,313,118,324,116,337,120,346,133,352,133,340,137,333,145,329,156,327,153,319,153,291,157,271,170,259,178,277,193,250,174,216]).setFill(c);
+ g.createPolyline([78,127,90,142,95,155,108,164,125,167,139,175,150,206,152,191,141,140,121,148,100,136]).setFill(c);
+ g.createPolyline([21,58,35,63,38,68,32,69,42,74,40,79,47,80,54,83,45,94,34,81,32,73,24,66]).setFill(c);
+ g.createPolyline([71,34,67,34,66,27,59,24,54,17,48,17,39,22,30,26,28,31,31,39,38,46,29,45,36,54,41,61,41,70,50,69,54,71,55,58,67,52,76,43,76,39,68,44]).setFill(c);
+ g.createPolyline([139,74,141,83,143,89,144,104,148,104,155,106,154,86,157,77,155,72,150,77,144,77]).setFill(c);
+ g.createPolyline([105,44,102,53,108,58,111,62,112,55]).setFill(c);
+ g.createPolyline([141,48,141,54,144,58,139,62,137,66,136,59,137,52]).setFill(c);
+ g.createPolyline([98,135,104,130,105,134,108,132,108,135,112,134,113,137,116,136,116,139,119,139,124,141,128,140,133,138,140,133,139,140,126,146,104,144]).setFill(c);
+ g.createPolyline([97,116,103,119,103,116,111,118,116,117,122,114,127,107,135,111,142,107,141,114,145,118,149,121,145,125,140,124,127,121,113,125,100,124]).setFill(c);
+ g.createPolyline([147,33,152,35,157,34,153,31,160,31,156,28,161,28,159,24,163,25,163,21,165,22,170,23,167,17,172,21,174,18,175,23,176,22,177,28,177,33,174,37,176,39,174,44,171,49,168,53,164,57,159,68,156,70,154,60,150,51,146,43,144,35]).setFill(c);
+ g.createPolyline([85,72,89,74,93,75,100,76,105,75,102,79,94,79,88,76]).setFill(c);
+ g.createPolyline([86,214,79,221,76,232,82,225,78,239,82,234,78,245,81,243,79,255,84,250,84,267,87,254,90,271,90,257,95,271,93,256,95,249,92,252,93,243,89,253,89,241,86,250,87,236,83,245,87,231,82,231,90,219,84,221]).setFill(c);
+ c = new dojo.Color("#ffcc7f");
+ g.createPolyline([93,68,96,72,100,73,106,72,108,66,105,63,100,62]).setFill(c);
+ g.createPolyline([144,64,142,68,142,73,146,74,150,73,154,64,149,62]).setFill(c);
+ c = new dojo.Color("#9c826b");
+ g.createPolyline([57,91,42,111,52,105,41,117,53,112,46,120,53,116,50,124,57,119,55,127,61,122,60,130,67,126,66,134,71,129,72,136,77,130,76,137,80,133,82,138,86,135,96,135,94,129,86,124,83,117,77,123,79,117,73,120,75,112,68,116,71,111,65,114,69,107,63,110,68,102,61,107,66,98,61,103,63,97,57,99]).setFill(c);
+ g.createPolyline([83,79,76,79,67,82,75,83,65,88,76,87,65,92,76,91,68,96,77,95,70,99,80,98,72,104,80,102,76,108,85,103,92,101,87,98,93,96,86,94,91,93,85,91,93,89,99,89,105,93,107,85,102,82,92,80]).setFill(c);
+ g.createPolyline([109,77,111,83,109,89,113,94,117,90,117,81,114,78]).setFill(c);
+ g.createPolyline([122,128,127,126,134,127,136,129,134,130,130,128,124,129]).setFill(c);
+ g.createPolyline([78,27,82,32,80,33,82,36,78,37,82,40,78,42,81,46,76,47,78,49,74,50,82,52,87,50,83,48,91,46,86,45,91,42,88,40,92,37,86,34,90,31,86,29,89,26]).setFill(c);
+ g.createPolyline([82,17,92,20,79,21,90,25,81,25,94,28,93,26,101,30,101,26,107,33,108,28,111,40,113,34,115,45,117,39,119,54,121,46,124,58,126,47,129,59,130,49,134,58,133,44,137,48,133,37,137,40,133,32,126,20,135,26,132,19,138,23,135,17,142,18,132,11,116,6,94,6,78,11,92,12,80,14,90,16]).setFill(c);
+ g.createPolyline([142,234,132,227,124,223,115,220,110,225,118,224,127,229,135,236,122,234,115,237,113,242,121,238,139,243,121,245,111,254,95,254,102,244,104,235,110,229,100,231,104,224,113,216,122,215,132,217,141,224,145,230,149,240]).setFill(c);
+ g.createPolyline([115,252,125,248,137,249,143,258,134,255,125,254]).setFill(c);
+ g.createPolyline([114,212,130,213,140,219,147,225,144,214,137,209,128,207]).setFill(c);
+ g.createPolyline([102,263,108,258,117,257,131,258,116,260,109,265]).setFill(c);
+ g.createPolyline([51,241,35,224,40,238,23,224,31,242,19,239,28,247,17,246,25,250,37,254,39,263,44,271,47,294,48,317,51,328,60,351,60,323,53,262,47,246]).setFill(c);
+ g.createPolyline([2,364,9,367,14,366,18,355,20,364,26,366,31,357,35,364,39,364,42,357,47,363,53,360,59,357,54,369,7,373]).setFill(c);
+ g.createPolyline([7,349,19,345,25,339,18,341,23,333,28,326,23,326,27,320,23,316,25,311,20,298,15,277,12,264,9,249,10,223,3,248,5,261,15,307,17,326,11,343]).setFill(c);
+ g.createPolyline([11,226,15,231,25,236,18,227]).setFill(c);
+ g.createPolyline([13,214,19,217,32,227,23,214,16,208,15,190,24,148,31,121,24,137,14,170,8,189]).setFill(c);
+ g.createPolyline([202,254,195,258,199,260,193,263,197,263,190,268,196,268,191,273,188,282,200,272,194,272,201,266,197,265,204,262,200,258,204,256]).setFill(c);
+ c = new dojo.Color("#845433");
+ g.createPolyline([151,213,165,212,179,225,189,246,187,262,179,275,176,263,177,247,171,233,163,230,165,251,157,264,146,298,145,321,133,326,143,285,154,260,153,240]).setFill(c);
+ g.createPolyline([91,132,95,145,97,154,104,148,107,155,109,150,111,158,115,152,118,159,120,153,125,161,126,155,133,164,132,154,137,163,137,152,142,163,147,186,152,192,148,167,141,143,124,145,105,143]).setFill(c);
+ c = new dojo.Color("#9c826b");
+ g.createPolyline([31,57,23,52,26,51,20,44,23,42,21,36,22,29,25,23,24,32,30,43,26,41,30,50,26,48]).setFill(c);
+ g.createPolyline([147,21,149,28,155,21,161,16,167,14,175,15,173,11,161,9]).setFill(c);
+ g.createPolyline([181,39,175,51,169,57,171,65,165,68,165,75,160,76,162,91,171,71,180,51]).setFill(c);
+ g.createPolyline([132,346,139,348,141,346,142,341,147,342,143,355,133,350]).setFill(c);
+ g.createPolyline([146,355,151,352,155,348,157,343,160,349,151,356,147,357]).setFill(c);
+ g.createPolyline([99,266,100,281,94,305,86,322,78,332,72,346,73,331,91,291]).setFill(c);
+ g.createPolyline([20,347,32,342,45,340,54,345,45,350,42,353,38,350,31,353,29,356,23,350,19,353,15,349]).setFill(c);
+ g.createPolyline([78,344,86,344,92,349,88,358,84,352]).setFill(c);
+ g.createPolyline([93,347,104,344,117,345,124,354,121,357,116,351,112,351,108,355,102,351]).setFill(c);
+ c = new dojo.Color("black");
+ g.createPolyline([105,12,111,18,113,24,113,29,119,34,116,23,112,16]).setFill(c);
+ g.createPolyline([122,27,125,34,127,43,128,34,125,29]).setFill(c);
+ g.createPolyline([115,13,122,19,122,15,113,10]).setFill(c);
+ c = new dojo.Color("#ffe5b2");
+ g.createPolyline([116,172,107,182,98,193,98,183,90,199,89,189,84,207,88,206,87,215,95,206,93,219,91,230,98,216,97,226,104,214,112,209,104,208,113,202,126,200,139,207,132,198,142,203,134,192,142,195,134,187,140,185,130,181,136,177,126,177,125,171,116,180]).setFill(c);
+ g.createPolyline([74,220,67,230,67,221,59,235,63,233,60,248,70,232,65,249,71,243,67,256,73,250,69,262,73,259,71,267,76,262,72,271,78,270,76,275,82,274,78,290,86,279,86,289,92,274,88,275,87,264,82,270,82,258,77,257,78,247,73,246,77,233,72,236]).setFill(c);
+ g.createPolyline([133,230,147,242,148,250,145,254,138,247,129,246,142,245,138,241,128,237,137,238]).setFill(c);
+ g.createPolyline([133,261,125,261,116,263,111,267,125,265]).setFill(c);
+ g.createPolyline([121,271,109,273,103,279,99,305,92,316,85,327,83,335,89,340,97,341,94,336,101,336,96,331,103,330,97,327,108,325,99,322,109,321,100,318,110,317,105,314,110,312,107,310,113,308,105,306,114,303,105,301,115,298,107,295,115,294,108,293,117,291,109,289,117,286,109,286,118,283,112,281,118,279,114,278,119,276,115,274]).setFill(c);
+ g.createPolyline([79,364,74,359,74,353,76,347,80,351,83,356,82,360]).setFill(c);
+ g.createPolyline([91,363,93,356,97,353,103,355,105,360,103,366,99,371,94,368]).setFill(c);
+ g.createPolyline([110,355,114,353,118,357,117,363,113,369,111,362]).setFill(c);
+ g.createPolyline([126,354,123,358,124,367,126,369,129,361,129,357]).setFill(c);
+ g.createPolyline([30,154,24,166,20,182,23,194,29,208,37,218,41,210,41,223,46,214,46,227,52,216,52,227,61,216,59,225,68,213,73,219,70,207,77,212,69,200,77,202,70,194,78,197,68,187,76,182,64,182,58,175,58,185,53,177,50,186,46,171,44,182,39,167,36,172,36,162,30,166]).setFill(c);
+ g.createPolyline([44,130,41,137,45,136,43,150,48,142,48,157,53,150,52,164,60,156,61,169,64,165,66,175,70,167,74,176,77,168,80,183,85,172,90,182,93,174,98,181,99,173,104,175,105,169,114,168,102,163,95,157,94,166,90,154,87,162,82,149,75,159,72,148,68,155,67,143,62,148,62,138,58,145,56,133,52,142,52,128,49,134,47,125]).setFill(c);
+ g.createPolyline([13,216,19,219,36,231,22,223,16,222,22,227,12,224,13,220,16,220]).setFill(c);
+ g.createPolyline([10,231,14,236,25,239,27,237,19,234]).setFill(c);
+ g.createPolyline([9,245,14,242,25,245,13,245]).setFill(c);
+ g.createPolyline([33,255,26,253,18,254,25,256,18,258,27,260,18,263,27,265,19,267,29,270,21,272,29,276,21,278,30,281,22,283,31,287,24,288,32,292,23,293,34,298,26,299,37,303,32,305,39,309,33,309,39,314,34,314,40,318,34,317,40,321,34,321,41,326,33,326,40,330,33,332,39,333,33,337,42,337,54,341,49,337,52,335,47,330,50,330,45,325,49,325,45,321,48,321,45,316,46,306,45,286,43,274,36,261]).setFill(c);
+ g.createPolyline([7,358,9,351,14,351,17,359,11,364]).setFill(c);
+ g.createPolyline([44,354,49,351,52,355,49,361]).setFill(c);
+ g.createPolyline([32,357,37,353,40,358,36,361]).setFill(c);
+ g.createPolyline([139,334,145,330,154,330,158,334,154,341,152,348,145,350,149,340,147,336,141,339,139,345,136,342,136,339]).setFill(c);
+ g.createPolyline([208,259,215,259,212,255,220,259,224,263,225,274,224,283,220,292,208,300,206,308,203,304,199,315,197,309,195,318,193,313,190,322,190,316,185,325,182,318,180,325,172,321,178,320,176,313,186,312,180,307,188,307,184,303,191,302,186,299,195,294,187,290,197,288,192,286,201,283,194,280,203,277,198,275,207,271,200,269,209,265,204,265,212,262]).setFill(c);
+ g.createPolyline([106,126,106,131,109,132,111,134,115,132,115,135,119,133,118,137,123,137,128,137,133,134,136,130,136,127,132,124,118,128,112,128,106,126,106,126,106,126]).setFill(c);
+ g.createPolyline([107,114,101,110,98,102,105,97,111,98,119,102,121,108,118,112,113,115]).setFill(c);
+ g.createPolyline([148,106,145,110,146,116,150,118,152,111,151,107]).setFill(c);
+ g.createPolyline([80,55,70,52,75,58,63,57,72,61,57,61,67,66,57,67,62,69,54,71,61,73,54,77,63,78,53,85,60,84,56,90,69,84,63,82,75,76,70,75,77,72,72,71,78,69,72,66,81,67,78,64,82,63,80,60,86,62]).setFill(c);
+ g.createPolyline([87,56,91,52,96,50,102,56,98,56,92,60]).setFill(c);
+ g.createPolyline([85,68,89,73,98,76,106,74,96,73,91,70]).setFill(c);
+ g.createPolyline([115,57,114,64,111,64,115,75,122,81,122,74,126,79,126,74,131,78,130,72,133,77,131,68,126,61,119,57]).setFill(c);
+ g.createPolyline([145,48,143,53,147,59,151,59,150,55]).setFill(c);
+ g.createPolyline([26,22,34,15,43,10,52,10,59,16,47,15,32,22]).setFill(c);
+ g.createPolyline([160,19,152,26,149,34,154,33,152,30,157,30,155,26,158,27,157,23,161,23]).setFill(c);
+ c = new dojo.Color("black");
+ g.createPolyline([98,117,105,122,109,122,105,117,113,120,121,120,130,112,128,108,123,103,123,99,128,101,132,106,135,109,142,105,142,101,145,101,145,91,148,101,145,105,136,112,135,116,143,124,148,120,150,122,142,128,133,122,121,125,112,126,103,125,100,129,96,124]).setFill(c);
+ g.createPolyline([146,118,152,118,152,115,149,115]).setFill(c);
+ g.createPolyline([148,112,154,111,154,109,149,109]).setFill(c);
+ g.createPolyline([106,112,108,115,114,116,118,114]).setFill(c);
+ g.createPolyline([108,108,111,110,116,110,119,108]).setFill(c);
+ g.createPolyline([106,104,109,105,117,106,115,104]).setFill(c);
+ g.createPolyline([50,25,41,26,34,33,39,43,49,58,36,51,47,68,55,69,54,59,61,57,74,46,60,52,67,42,57,48,61,40,54,45,60,36,59,29,48,38,52,30,47,32]).setFill(c);
+ g.createPolyline([147,34,152,41,155,49,161,53,157,47,164,47,158,43,168,44,159,40,164,37,169,37,164,33,169,34,165,28,170,30,170,25,173,29,175,27,176,32,173,36,175,39,172,42,172,46,168,49,170,55,162,57,158,63,155,58,153,50,149,46]).setFill(c);
+ g.createPolyline([155,71,159,80,157,93,157,102,155,108,150,101,149,93,154,101,152,91,151,83,155,79]).setFill(c);
+ g.createPolyline([112,78,115,81,114,91,112,87,113,82]).setFill(c);
+ g.createPolyline([78,28,64,17,58,11,47,9,36,10,28,16,21,26,18,41,20,51,23,61,33,65,28,68,37,74,36,81,43,87,48,90,43,100,40,98,39,90,31,80,30,72,22,71,17,61,14,46,16,28,23,17,33,9,45,6,54,6,65,12]).setFill(c);
+ g.createPolyline([67,18,76,9,87,5,101,2,118,3,135,8,149,20,149,26,144,19,132,12,121,9,105,7,89,8,76,14,70,20]).setFill(c);
+ g.createPolyline([56,98,48,106,56,103,47,112,56,110,52,115,57,113,52,121,62,115,58,123,65,119,63,125,69,121,68,127,74,125,74,129,79,128,83,132,94,135,93,129,85,127,81,122,76,126,75,121,71,124,71,117,66,121,66,117,62,117,64,112,60,113,60,110,57,111,61,105,57,107,60,101,55,102]).setFill(c);
+ g.createPolyline([101,132,103,138,106,134,106,139,112,136,111,142,115,139,114,143,119,142,125,145,131,142,135,138,140,134,140,129,143,135,145,149,150,171,149,184,145,165,141,150,136,147,132,151,131,149,126,152,125,150,121,152,117,148,111,152,110,148,105,149,104,145,98,150,96,138,94,132,94,130,98,132]).setFill(c);
+ g.createPolyline([41,94,32,110,23,132,12,163,6,190,7,217,5,236,3,247,9,230,12,211,12,185,18,160,26,134,35,110,43,99]).setFill(c);
+ g.createPolyline([32,246,41,250,50,257,52,267,53,295,53,323,59,350,54,363,51,365,44,366,42,360,40,372,54,372,59,366,62,353,71,352,75,335,73,330,66,318,68,302,64,294,67,288,63,286,63,279,59,275,58,267,56,262,50,247,42,235,44,246,32,236,35,244]).setFill(c);
+ g.createPolyline([134,324,146,320,159,322,173,327,179,337,179,349,172,355,158,357,170,350,174,343,170,333,163,328,152,326,134,329]).setFill(c);
+ g.createPolyline([173,339,183,334,184,338,191,329,194,332,199,323,202,325,206,318,209,320,213,309,221,303,228,296,232,289,234,279,233,269,230,262,225,256,219,253,208,252,198,252,210,249,223,250,232,257,237,265,238,277,238,291,232,305,221,323,218,335,212,342,200,349,178,348]).setFill(c);
+ g.createPolyline([165,296,158,301,156,310,156,323,162,324,159,318,162,308,162,304]).setFill(c);
+ g.createPolyline([99,252,105,244,107,234,115,228,121,228,131,235,122,233,113,235,109,246,121,239,133,243,121,243,110,251]).setFill(c);
+ g.createPolyline([117,252,124,247,134,249,136,253,126,252]).setFill(c);
+ g.createPolyline([117,218,132,224,144,233,140,225,132,219,117,218,117,218,117,218]).setFill(c);
+ g.createPolyline([122,212,134,214,143,221,141,213,132,210]).setFill(c);
+ g.createPolyline([69,352,70,363,76,373,86,378,97,379,108,379,120,377,128,378,132,373,135,361,133,358,132,366,127,375,121,374,121,362,119,367,117,374,110,376,110,362,107,357,106,371,104,375,97,376,90,375,90,368,86,362,83,364,86,369,85,373,78,370,73,362,71,351]).setFill(c);
+ g.createPolyline([100,360,96,363,99,369,102,364]).setFill(c);
+ g.createPolyline([115,360,112,363,114,369,117,364]).setFill(c);
+ g.createPolyline([127,362,125,364,126,369,128,365]).setFill(c);
+ g.createPolyline([5,255,7,276,11,304,15,320,13,334,6,348,2,353,0,363,5,372,12,374,25,372,38,372,44,369,42,367,36,368,31,369,30,360,27,368,20,370,16,361,15,368,10,369,3,366,3,359,6,352,11,348,17,331,19,316,12,291,9,274]).setFill(c);
+ g.createPolyline([10,358,7,362,10,366,11,362]).setFill(c);
+ g.createPolyline([25,357,22,360,24,366,27,360]).setFill(c);
+ g.createPolyline([37,357,34,361,36,365,38,361]).setFill(c);
+ g.createPolyline([49,356,46,359,47,364,50,360]).setFill(c);
+ g.createPolyline([130,101,132,102,135,101,139,102,143,103,142,101,137,100,133,100]).setFill(c);
+ g.createPolyline([106,48,105,52,108,56,109,52]).setFill(c);
+ g.createPolyline([139,52,139,56,140,60,142,58,141,56]).setFill(c);
+ g.createPolyline([25,349,29,351,30,355,33,350,37,348,42,351,45,347,49,345,44,343,36,345]).setFill(c);
+ g.createPolyline([98,347,105,351,107,354,109,349,115,349,120,353,118,349,113,346,104,346]).setFill(c);
+ g.createPolyline([83,348,87,352,87,357,89,351,87,348]).setFill(c);
+ g.createPolyline([155,107,163,107,170,107,186,108,175,109,155,109]).setFill(c);
+ g.createPolyline([153,114,162,113,175,112,192,114,173,114,154,115]).setFill(c);
+ g.createPolyline([152,118,164,120,180,123,197,129,169,123,151,120]).setFill(c);
+ g.createPolyline([68,109,87,106,107,106,106,108,88,108]).setFill(c);
+ g.createPolyline([105,111,95,112,79,114,71,116,85,115,102,113]).setFill(c);
+ g.createPolyline([108,101,98,99,87,99,78,99,93,100,105,102]).setFill(c);
+ g.createPolyline([85,63,91,63,97,60,104,60,108,62,111,69,112,75,110,74,108,71,103,73,106,69,105,65,103,64,103,67,102,70,99,70,97,66,94,67,97,72,88,67,84,66]).setFill(c);
+ g.createPolyline([140,74,141,66,144,61,150,61,156,62,153,70,150,73,152,65,150,65,151,68,149,71,146,71,144,66,143,70,143,74]).setFill(c);
+ g.createPolyline([146,20,156,11,163,9,172,9,178,14,182,18,184,32,182,42,182,52,177,58,176,67,171,76,165,90,157,105,160,92,164,85,168,78,167,73,173,66,172,62,175,59,174,55,177,53,180,46,181,29,179,21,173,13,166,11,159,13,153,18,148,23]).setFill(c);
+ g.createPolyline([150,187,148,211,150,233,153,247,148,267,135,283,125,299,136,292,131,313,122,328,122,345,129,352,133,359,133,367,137,359,148,356,140,350,131,347,129,340,132,332,140,328,137,322,140,304,154,265,157,244,155,223,161,220,175,229,186,247,185,260,176,275,178,287,185,277,188,261,196,253,189,236,174,213]).setFill(c);
+ g.createPolyline([147,338,142,341,143,345,141,354,147,343]).setFill(c);
+ g.createPolyline([157,342,156,349,150,356,157,353,163,346,162,342]).setFill(c);
+ g.createPolyline([99,265,96,284,92,299,73,339,73,333,87,300]).setFill(c);
+ //surface.createLine({x1: 0, y1: 350, x2: 700, y2: 350}).setStroke("green");
+ //surface.createLine({y1: 0, x1: 350, y2: 700, x2: 350}).setStroke("green");
+ dojo.connect(dijit.byId("rotatingSlider"), "onChange", rotatingEvent);
+ dojo.connect(dijit.byId("scalingSlider"), "onChange", scalingEvent);
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+<style type="text/css">
+ td.pad { padding: 0px 5px 0px 5px; }
+</style>
+</head>
+<body class="tundra">
+ <h1>dojox.gfx: Lion</h1>
+ <p>This example was directly converted from SVG file.</p>
+ <table>
+ <tr><td align="center" class="pad">Rotation (<span id="rotationValue">0</span>)</td></tr>
+ <tr><td>
+ <div id="rotatingSlider" dojoType="dijit.form.HorizontalSlider"
+ value="0" minimum="-180" maximum="180" discreteValues="72" showButtons="false" intermediateChanges="true"
+ style="width: 600px;">
+ <div dojoType="dijit.form.HorizontalRule" container="topDecoration" count="73" style="height:5px;"></div>
+ <div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count="9" style="height:5px;"></div>
+ <div dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" labels="-180,-135,-90,-45,0,45,90,135,180" style="height:1.2em;font-size:75%;color:gray;"></div>
+ </div>
+ </td></tr>
+ <tr><td align="center" class="pad">Scaling (<span id="scaleValue">1.000</span>)</td></tr>
+ <tr><td>
+ <div id="scalingSlider" dojoType="dijit.form.HorizontalSlider"
+ value="1" minimum="0" maximum="1" showButtons="false" intermediateChanges="true"
+ style="width: 600px;">
+ <div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count="5" style="height:5px;"></div>
+ <div dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" labels="10%,18%,32%,56%,100%" style="height:1.2em;font-size:75%;color:gray;"></div>
+ </div>
+ </td></tr>
+ </table>
+ <div id="gfx_holder" style="width: 700px; height: 700px;"></div>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/demos/roundedPane.html b/includes/js/dojox/gfx/demos/roundedPane.html
new file mode 100644
index 0000000..4abb775
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/roundedPane.html
@@ -0,0 +1,191 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <head>
+
+ <title>rounded skeleton page | The Dojo Toolkit</title>
+
+ <script type="text/javascript" src="../../../dojo/dojo.js"
+ djConfig="parseOnLoad:true, isDebug:true"></script>
+
+ <script type="text/javascript">
+
+ dojo.require("dijit.layout.ContentPane");
+ dojo.require("dijit._Templated");
+ dojo.require("dojox.gfx");
+ dojo.require("dojo.dnd.TimedMoveable");
+
+ dojo.declare("my.RoundedContentPane",[dijit.layout.ContentPane,dijit._Templated],{
+ // radius: Integer
+ // radius of the corners
+ radius:15,
+ // moveable: Boolean
+ // if true, the node is movable by either the containerNode, or an optional node
+ // found by the handle attribute
+ moveable:false,
+ // handle: String
+ // a CSS3 selector query to match the handle for this node, scoped to this.domNode
+ handle:".handle",
+
+ // template:
+ templateString:
+ '<div><div style="position:relative;">' +
+ '<div dojoAttachPoint="surfaceNode"></div>' +
+ '<div dojoAttachPoint="containerNode"></div>' +
+ '</div></div>',
+
+ startup:function(){
+
+ this.inherited(arguments);
+ this._initSurface();
+ dojo.style(this.surfaceNode,{
+ position:"absolute",
+ top:0,
+ left:0
+ });
+
+ if(this.moveable){
+ this._mover = new dojo.dnd.TimedMoveable(this.domNode,{
+ handle: dojo.query(this.handle,this.domNode)[0] ||this.containerNode,
+ timeout:69
+ });
+ }
+
+ },
+
+ _initSurface: function(){
+
+ var s = dojo.marginBox(this.domNode);
+ var stroke = 2;
+
+ this.surface = dojox.gfx.createSurface(this.surfaceNode, s.w + stroke * 2, s.h + stroke * 2);
+ this.roundedShape = this.surface.createRect({
+ r: this.radius,
+ width: s.w,
+ height: s.h
+ })
+ .setFill([0, 0, 0, 0.5]) // black, 50% transparency
+ .setStroke({ color:[255,255,255,1], width:stroke }) // solid white
+ ;
+ this.resize(s);
+
+ },
+
+ resize:function(size){
+
+ if(!this.surface){ this._initSurfce(); }
+
+ this.surface.setDimensions(size.w,size.h);
+ this.roundedShape.setShape({
+ width: size.w,
+ height: size.h
+ });
+
+ var _offset = Math.floor(this.radius / 2);
+ dojo.style(this.containerNode,{
+ color: "#fff",
+ position: "absolute",
+ overflow: "auto",
+ top: _offset + "px",
+ left: _offset + "px",
+ height: (size.h - _offset * 2) + "px",
+ width: (size.w - _offset * 2) + "px"
+ });
+
+ }
+
+ });
+ </script>
+
+ <style type="text/css">
+ body { background:#ededed; }
+ </style>
+
+ </head>
+ <body>
+
+ <h1>Some gfx + ContentPane's</h1>
+
+ <div dojoType="my.RoundedContentPane" radius="55" title="Pane 2" style="width:200px; height:400px; float:right">
+ <h3>YO!</h3>
+ <p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p><p>lorem</p>
+ </div>
+
+ <div style="width:400px; height:200px;" dojoType="my.RoundedContentPane">
+ LOREM, ipsum, dollllllllllor:
+ .roundedContent {
+ padding: 31px;
+ font-family: 'Tahoma';
+ font-size: 12px;
+ color:#fff;
+ }<p>.roundedContent {
+ padding: 31px;
+ font-family: 'Tahoma';
+ font-size: 12px;
+ color:#fff;
+ }</p><p>.roundedContent {
+ padding: 31px;
+ font-family: 'Tahoma';
+ font-size: 12px;
+ color:#fff;
+ }</p><p>.roundedContent {
+ padding: 31px;
+ font-family: 'Tahoma';
+ font-size: 12px;
+ color:#fff;
+ }</p><p>.roundedContent {
+ padding: 31px;
+ font-family: 'Tahoma';
+ font-size: 12px;
+ color:#fff;
+ }</p><p>.roundedContent {
+ padding: 31px;
+ font-family: 'Tahoma';
+ font-size: 12px;
+ color:#fff;
+ }</p><p>.roundedContent {
+ padding: 31px;
+ font-family: 'Tahoma';
+ font-size: 12px;
+ color:#fff;
+ }</p><p>.roundedContent {
+ padding: 31px;
+ font-family: 'Tahoma';
+ font-size: 12px;
+ color:#fff;
+ }</p><p>.roundedContent {
+ padding: 31px;
+ font-family: 'Tahoma';
+ font-size: 12px;
+ color:#fff;
+ }</p><p>.roundedContent {
+ padding: 31px;
+ font-family: 'Tahoma';
+ font-size: 12px;
+ color:#fff;
+ }</p><p>.roundedContent {
+ padding: 31px;
+ font-family: 'Tahoma';
+ font-size: 12px;
+ color:#fff;
+ }</p><p>.roundedContent {
+ padding: 31px;
+ font-family: 'Tahoma';
+ font-size: 12px;
+ color:#fff;
+ }</p>
+
+ </div>
+
+
+ <div radius="45" style="width:400px; height:200px;" moveable="true" dojoType="my.RoundedContentPane" handle=".myHandle">
+ <h4 class="myHandle" style="cursor:move; margin-top:0; border:1px solid #666">Moveable Handle</h4>
+ LOREM, ipsum, dollllllllllor:
+ </div>
+
+
+ <div dojoType="my.RoundedContentPane" title="Pane 1" moveable="true" style="width:100px; height:100px;">
+ lorem ipsum (small moveable)
+ </div>
+
+ </body>
+</html>
diff --git a/includes/js/dojox/gfx/demos/tiger.html b/includes/js/dojox/gfx/demos/tiger.html
new file mode 100644
index 0000000..afb45ef
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/tiger.html
@@ -0,0 +1,566 @@
+<html>
+<head>
+<title>dojox.gfx: Tiger</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/themes/tundra/tundra.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<script type="text/javascript">
+
+dojo.require("dijit.form.Slider");
+dojo.require("dojo.parser"); // scan page for widgets
+
+dojo.require("dojox.gfx");
+
+var rotation = 0, scaling = 1;
+var surface, g, m = dojox.gfx.matrix;
+var initial_matrix = m.translate(250, 250);
+
+var updateMatrix = function(){
+ if(g){ g.setTransform([m.rotategAt(rotation, 350, 350), m.scaleAt(scaling, 350, 350), initial_matrix]); }
+};
+
+var rotatingEvent = function(value){
+ rotation = value;
+ dojo.byId("rotationValue").innerHTML = rotation;
+ updateMatrix();
+};
+
+var scalingEvent = function(value){
+ scaling = Math.exp(Math.LN10 * (value - 1));
+ dojo.byId("scaleValue").innerHTML = scaling.toFixed(3);
+ updateMatrix();
+};
+
+makeShapes = function(){
+ surface = dojox.gfx.createSurface(dojo.byId("gfx_holder"), 700, 700);
+ surface.createRect({x: 0, y: 0, width: 700, height: 700}).setFill("#eee");
+ g = surface.createGroup().setTransform(initial_matrix);
+ var f, s = {color: "black", width: 1};
+ f = "#ffffff"; s = {color: "#000000", width: 0.172};
+ g.createPath("M-122.304 84.285C-122.304 84.285 -122.203 86.179 -123.027 86.16C-123.851 86.141 -140.305 38.066 -160.833 40.309C-160.833 40.309 -143.05 32.956 -122.304 84.285z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.172};
+ g.createPath("M-118.774 81.262C-118.774 81.262 -119.323 83.078 -120.092 82.779C-120.86 82.481 -119.977 31.675 -140.043 26.801C-140.043 26.801 -120.82 25.937 -118.774 81.262z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.172};
+ g.createPath("M-91.284 123.59C-91.284 123.59 -89.648 124.55 -90.118 125.227C-90.589 125.904 -139.763 113.102 -149.218 131.459C-149.218 131.459 -145.539 112.572 -91.284 123.59z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.172};
+ g.createPath("M-94.093 133.801C-94.093 133.801 -92.237 134.197 -92.471 134.988C-92.704 135.779 -143.407 139.121 -146.597 159.522C-146.597 159.522 -149.055 140.437 -94.093 133.801z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.172};
+ g.createPath("M-98.304 128.276C-98.304 128.276 -96.526 128.939 -96.872 129.687C-97.218 130.435 -147.866 126.346 -153.998 146.064C-153.998 146.064 -153.646 126.825 -98.304 128.276z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.172};
+ g.createPath("M-109.009 110.072C-109.009 110.072 -107.701 111.446 -108.34 111.967C-108.979 112.488 -152.722 86.634 -166.869 101.676C-166.869 101.676 -158.128 84.533 -109.009 110.072z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.172};
+ g.createPath("M-116.554 114.263C-116.554 114.263 -115.098 115.48 -115.674 116.071C-116.25 116.661 -162.638 95.922 -174.992 112.469C-174.992 112.469 -168.247 94.447 -116.554 114.263z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.172};
+ g.createPath("M-119.154 118.335C-119.154 118.335 -117.546 119.343 -118.036 120.006C-118.526 120.669 -167.308 106.446 -177.291 124.522C-177.291 124.522 -173.066 105.749 -119.154 118.335z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.172};
+ g.createPath("M-108.42 118.949C-108.42 118.949 -107.298 120.48 -107.999 120.915C-108.7 121.35 -148.769 90.102 -164.727 103.207C-164.727 103.207 -153.862 87.326 -108.42 118.949z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.172};
+ g.createPath("M-128.2 90C-128.2 90 -127.6 91.8 -128.4 92C-129.2 92.2 -157.8 50.2 -177.001 57.8C-177.001 57.8 -161.8 46 -128.2 90z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.172};
+ g.createPath("M-127.505 96.979C-127.505 96.979 -126.53 98.608 -127.269 98.975C-128.007 99.343 -164.992 64.499 -182.101 76.061C-182.101 76.061 -169.804 61.261 -127.505 96.979z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.172};
+ g.createPath("M-127.62 101.349C-127.62 101.349 -126.498 102.88 -127.199 103.315C-127.9 103.749 -167.969 72.502 -183.927 85.607C-183.927 85.607 -173.062 69.726 -127.62 101.349z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = "#000000";
+ g.createPath("M-129.83 103.065C-129.327 109.113 -128.339 115.682 -126.6 118.801C-126.6 118.801 -130.2 131.201 -121.4 144.401C-121.4 144.401 -121.8 151.601 -120.2 154.801C-120.2 154.801 -116.2 163.201 -111.4 164.001C-107.516 164.648 -98.793 167.717 -88.932 169.121C-88.932 169.121 -71.8 183.201 -75 196.001C-75 196.001 -75.4 212.401 -79 214.001C-79 214.001 -67.4 202.801 -77 219.601L-81.4 238.401C-81.4 238.401 -55.8 216.801 -71.4 235.201L-81.4 261.201C-81.4 261.201 -61.8 242.801 -69 251.201L-72.2 260.001C-72.2 260.001 -29 232.801 -59.8 262.401C-59.8 262.401 -51.8 258.801 -47.4 261.601C-47.4 261.601 -40.6 260.401 -41.4 262.001C-41.4 262.001 -62.2 272.401 -65.8 290.801C-65.8 290.801 -57.4 280.801 -60.6 291.601L-60.2 303.201C-60.2 303.201 -56.2 281.601 -56.6 319.201C-56.6 319.201 -37.4 301.201 -49 322.001L-49 338.801C-49 338.801 -33.8 322.401 -40.2 335.201C-40.2 335.201 -30.2 326.401 -34.2 341.601C-34.2 341.601 -35 352.001 -30.6 340.801C-30.6 340.801 -14.6 310.201 -20.6 336.401C-20.6 336.401 -21.4 355.601 -16.6 340.801C-16.6 340.801 -16.2 351.201 -7 358.401C-7 358.401 -8.2 307.601 4.6 343.601L8.6 360.001C8.6 360.001 11.4 350.801 11 345.601C11 345.601 25.8 329.201 19 353.601C19 353.601 34.2 330.801 31 344.001C31 344.001 23.4 360.001 25 364.801C25 364.801 41.8 330.001 43 328.401C43 328.401 41 370.802 51.8 334.801C51.8 334.801 57.4 346.801 54.6 351.201C54.6 351.201 62.6 343.201 61.8 340.001C61.8 340.001 66.4 331.801 69.2 345.401C69.2 345.401 71 354.801 72.6 351.601C72.6 351.601 76.6 375.602 77.8 352.801C77.8 352.801 79.4 339.201 72.2 327.601C72.2 327.601 73 324.401 70.2 320.401C70.2 320.401 83.8 342.001 76.6 313.201C76.6 313.201 87.801 321.201 89.001 321.201C89.001 321.201 75.4 298.001 84.2 302.801C84.2 302.801 79 292.401 97.001 304.401C97.001 304.401 81 288.401 98.601 298.001C98.601 298.001 106.601 304.401 99.001 294.401C99.001 294.401 84.6 278.401 106.601 296.401C106.601 296.401 118.201 312.801 119.001 315.601C119.001 315.601 109.001 286.401 104.601 283.601C104.601 283.601 113.001 247.201 154.201 262.801C154.201 262.801 161.001 280.001 165.401 261.601C165.401 261.601 178.201 255.201 189.401 282.801C189.401 282.801 193.401 269.201 192.601 266.401C192.601 266.401 199.401 267.601 198.601 266.401C198.601 266.401 211.801 270.801 213.001 270.001C213.001 270.001 219.801 276.801 220.201 273.201C220.201 273.201 229.401 276.001 227.401 272.401C227.401 272.401 236.201 288.001 236.601 291.601L239.001 277.601L241.001 280.401C241.001 280.401 242.601 272.801 241.801 271.601C241.001 270.401 261.801 278.401 266.601 299.201L268.601 307.601C268.601 307.601 274.601 292.801 273.001 288.801C273.001 288.801 278.201 289.601 278.601 294.001C278.601 294.001 282.601 270.801 277.801 264.801C277.801 264.801 282.201 264.001 283.401 267.601L283.401 260.401C283.401 260.401 290.601 261.201 290.601 258.801C290.601 258.801 295.001 254.801 297.001 259.601C297.001 259.601 284.601 224.401 303.001 243.601C303.001 243.601 310.201 254.401 306.601 235.601C303.001 216.801 299.001 215.201 303.801 214.801C303.801 214.801 304.601 211.201 302.601 209.601C300.601 208.001 303.801 209.601 303.801 209.601C303.801 209.601 308.601 213.601 303.401 191.601C303.401 191.601 309.801 193.201 297.801 164.001C297.801 164.001 300.601 161.601 296.601 153.201C296.601 153.201 304.601 157.601 307.401 156.001C307.401 156.001 307.001 154.401 303.801 150.401C303.801 150.401 282.201 95.6 302.601 117.601C302.601 117.601 314.451 131.151 308.051 108.351C308.051 108.351 298.94 84.341 299.717 80.045L-129.83 103.065z").setFill(f).setStroke(s);
+ f = "#cc7226"; s = "#000000";
+ g.createPath("M299.717 80.245C300.345 80.426 302.551 81.55 303.801 83.2C303.801 83.2 310.601 94 305.401 75.6C305.401 75.6 296.201 46.8 305.001 58C305.001 58 311.001 65.2 307.801 51.6C303.936 35.173 301.401 28.8 301.401 28.8C301.401 28.8 313.001 33.6 286.201 -6L295.001 -2.4C295.001 -2.4 275.401 -42 253.801 -47.2L245.801 -53.2C245.801 -53.2 284.201 -91.2 271.401 -128C271.401 -128 264.601 -133.2 255.001 -124C255.001 -124 248.601 -119.2 242.601 -120.8C242.601 -120.8 211.801 -119.6 209.801 -119.6C207.801 -119.6 173.001 -156.8 107.401 -139.2C107.401 -139.2 102.201 -137.2 97.801 -138.4C97.801 -138.4 79.4 -154.4 30.6 -131.6C30.6 -131.6 20.6 -129.6 19 -129.6C17.4 -129.6 14.6 -129.6 6.6 -123.2C-1.4 -116.8 -1.8 -116 -3.8 -114.4C-3.8 -114.4 -20.2 -103.2 -25 -102.4C-25 -102.4 -36.6 -96 -41 -86L-44.6 -84.8C-44.6 -84.8 -46.2 -77.6 -46.6 -76.4C-46.6 -76.4 -51.4 -72.8 -52.2 -67.2C-52.2 -67.2 -61 -61.2 -60.6 -56.8C-60.6 -56.8 -62.2 -51.6 -63 -46.8C-63 -46.8 -70.2 -42 -69.4 -39.2C-69.4 -39.2 -77 -25.2 -75.8 -18.4C-75.8 -18.4 -82.2 -18.8 -85 -16.4C-85 -16.4 -85.8 -11.6 -87.4 -11.2C-87.4 -11.2 -90.2 -10 -87.8 -6C-87.8 -6 -89.4 -3.2 -89.8 -1.6C-89.8 -1.6 -89 1.2 -93.4 6.8C-93.4 6.8 -99.8 25.6 -97.8 30.8C-97.8 30.8 -97.4 35.6 -100.2 37.2C-100.2 37.2 -103.8 36.8 -95.4 48.8C-95.4 48.8 -94.6 50 -97.8 52.4C-97.8 52.4 -115 56 -117.4 72.4C-117.4 72.4 -131 87.2 -131 92.4C-131 94.705 -130.729 97.852 -130.03 102.465C-130.03 102.465 -130.6 110.801 -103 111.601C-75.4 112.401 299.717 80.245 299.717 80.245z").setFill(f).setStroke(s);
+ f = "#cc7226"; s = null;
+ g.createPath("M-115.6 102.6C-140.6 63.2 -126.2 119.601 -126.2 119.601C-117.4 154.001 12.2 116.401 12.2 116.401C12.2 116.401 181.001 86 192.201 82C203.401 78 298.601 84.4 298.601 84.4L293.001 67.6C228.201 21.2 209.001 44.4 195.401 40.4C181.801 36.4 184.201 46 181.001 46.8C177.801 47.6 138.601 22.8 132.201 23.6C125.801 24.4 100.459 0.649 115.401 32.4C131.401 66.4 57 71.6 40.2 60.4C23.4 49.2 47.4 78.8 47.4 78.8C65.8 98.8 31.4 82 31.4 82C-3 69.2 -27 94.8 -30.2 95.6C-33.4 96.4 -38.2 99.6 -39 93.2C-39.8 86.8 -47.31 70.099 -79 96.4C-99 113.001 -112.8 91 -112.8 91L-115.6 102.6z").setFill(f).setStroke(s);
+ f = "#e87f3a";
+ g.createPath("M133.51 25.346C127.11 26.146 101.743 2.407 116.71 34.146C133.31 69.346 58.31 73.346 41.51 62.146C24.709 50.946 48.71 80.546 48.71 80.546C67.11 100.546 32.709 83.746 32.709 83.746C-1.691 70.946 -25.691 96.546 -28.891 97.346C-32.091 98.146 -36.891 101.346 -37.691 94.946C-38.491 88.546 -45.87 72.012 -77.691 98.146C-98.927 115.492 -112.418 94.037 -112.418 94.037L-115.618 104.146C-140.618 64.346 -125.546 122.655 -125.546 122.655C-116.745 157.056 13.509 118.146 13.509 118.146C13.509 118.146 182.31 87.746 193.51 83.746C204.71 79.746 299.038 86.073 299.038 86.073L293.51 68.764C228.71 22.364 210.31 46.146 196.71 42.146C183.11 38.146 185.51 47.746 182.31 48.546C179.11 49.346 139.91 24.546 133.51 25.346z").setFill(f).setStroke(s);
+ f = "#ea8c4d";
+ g.createPath("M134.819 27.091C128.419 27.891 103.685 3.862 118.019 35.891C134.219 72.092 59.619 75.092 42.819 63.892C26.019 52.692 50.019 82.292 50.019 82.292C68.419 102.292 34.019 85.492 34.019 85.492C-0.381 72.692 -24.382 98.292 -27.582 99.092C-30.782 99.892 -35.582 103.092 -36.382 96.692C-37.182 90.292 -44.43 73.925 -76.382 99.892C-98.855 117.983 -112.036 97.074 -112.036 97.074L-115.636 105.692C-139.436 66.692 -124.891 125.71 -124.891 125.71C-116.091 160.11 14.819 119.892 14.819 119.892C14.819 119.892 183.619 89.492 194.819 85.492C206.019 81.492 299.474 87.746 299.474 87.746L294.02 69.928C229.219 23.528 211.619 47.891 198.019 43.891C184.419 39.891 186.819 49.491 183.619 50.292C180.419 51.092 141.219 26.291 134.819 27.091z").setFill(f).setStroke(s);
+ f = "#ec9961";
+ g.createPath("M136.128 28.837C129.728 29.637 104.999 5.605 119.328 37.637C136.128 75.193 60.394 76.482 44.128 65.637C27.328 54.437 51.328 84.037 51.328 84.037C69.728 104.037 35.328 87.237 35.328 87.237C0.928 74.437 -23.072 100.037 -26.272 100.837C-29.472 101.637 -34.272 104.837 -35.072 98.437C-35.872 92.037 -42.989 75.839 -75.073 101.637C-98.782 120.474 -111.655 100.11 -111.655 100.11L-115.655 107.237C-137.455 70.437 -124.236 128.765 -124.236 128.765C-115.436 163.165 16.128 121.637 16.128 121.637C16.128 121.637 184.928 91.237 196.129 87.237C207.329 83.237 299.911 89.419 299.911 89.419L294.529 71.092C229.729 24.691 212.929 49.637 199.329 45.637C185.728 41.637 188.128 51.237 184.928 52.037C181.728 52.837 142.528 28.037 136.128 28.837z").setFill(f).setStroke(s);
+ f = "#eea575";
+ g.createPath("M137.438 30.583C131.037 31.383 106.814 7.129 120.637 39.383C137.438 78.583 62.237 78.583 45.437 67.383C28.637 56.183 52.637 85.783 52.637 85.783C71.037 105.783 36.637 88.983 36.637 88.983C2.237 76.183 -21.763 101.783 -24.963 102.583C-28.163 103.383 -32.963 106.583 -33.763 100.183C-34.563 93.783 -41.548 77.752 -73.763 103.383C-98.709 122.965 -111.273 103.146 -111.273 103.146L-115.673 108.783C-135.473 73.982 -123.582 131.819 -123.582 131.819C-114.782 166.22 17.437 123.383 17.437 123.383C17.437 123.383 186.238 92.983 197.438 88.983C208.638 84.983 300.347 91.092 300.347 91.092L295.038 72.255C230.238 25.855 214.238 51.383 200.638 47.383C187.038 43.383 189.438 52.983 186.238 53.783C183.038 54.583 143.838 29.783 137.438 30.583z").setFill(f).setStroke(s);
+ f = "#f1b288";
+ g.createPath("M138.747 32.328C132.347 33.128 106.383 9.677 121.947 41.128C141.147 79.928 63.546 80.328 46.746 69.128C29.946 57.928 53.946 87.528 53.946 87.528C72.346 107.528 37.946 90.728 37.946 90.728C3.546 77.928 -20.454 103.528 -23.654 104.328C-26.854 105.128 -31.654 108.328 -32.454 101.928C-33.254 95.528 -40.108 79.665 -72.454 105.128C-98.636 125.456 -110.891 106.183 -110.891 106.183L-115.691 110.328C-133.691 77.128 -122.927 134.874 -122.927 134.874C-114.127 169.274 18.746 125.128 18.746 125.128C18.746 125.128 187.547 94.728 198.747 90.728C209.947 86.728 300.783 92.764 300.783 92.764L295.547 73.419C230.747 27.019 215.547 53.128 201.947 49.128C188.347 45.128 190.747 54.728 187.547 55.528C184.347 56.328 145.147 31.528 138.747 32.328z").setFill(f).setStroke(s);
+ f = "#f3bf9c";
+ g.createPath("M140.056 34.073C133.655 34.873 107.313 11.613 123.255 42.873C143.656 82.874 64.855 82.074 48.055 70.874C31.255 59.674 55.255 89.274 55.255 89.274C73.655 109.274 39.255 92.474 39.255 92.474C4.855 79.674 -19.145 105.274 -22.345 106.074C-25.545 106.874 -30.345 110.074 -31.145 103.674C-31.945 97.274 -38.668 81.578 -71.145 106.874C-98.564 127.947 -110.509 109.219 -110.509 109.219L-115.709 111.874C-131.709 81.674 -122.273 137.929 -122.273 137.929C-113.473 172.329 20.055 126.874 20.055 126.874C20.055 126.874 188.856 96.474 200.056 92.474C211.256 88.474 301.22 94.437 301.22 94.437L296.056 74.583C231.256 28.183 216.856 54.874 203.256 50.874C189.656 46.873 192.056 56.474 188.856 57.274C185.656 58.074 146.456 33.273 140.056 34.073z").setFill(f).setStroke(s);
+ f = "#f5ccb0";
+ g.createPath("M141.365 35.819C134.965 36.619 107.523 13.944 124.565 44.619C146.565 84.219 66.164 83.819 49.364 72.619C32.564 61.419 56.564 91.019 56.564 91.019C74.964 111.019 40.564 94.219 40.564 94.219C6.164 81.419 -17.836 107.019 -21.036 107.819C-24.236 108.619 -29.036 111.819 -29.836 105.419C-30.636 99.019 -37.227 83.492 -69.836 108.619C-98.491 130.438 -110.127 112.256 -110.127 112.256L-115.727 113.419C-130.128 85.019 -121.618 140.983 -121.618 140.983C-112.818 175.384 21.364 128.619 21.364 128.619C21.364 128.619 190.165 98.219 201.365 94.219C212.565 90.219 301.656 96.11 301.656 96.11L296.565 75.746C231.765 29.346 218.165 56.619 204.565 52.619C190.965 48.619 193.365 58.219 190.165 59.019C186.965 59.819 147.765 35.019 141.365 35.819z").setFill(f).setStroke(s);
+ f = "#f8d8c4";
+ g.createPath("M142.674 37.565C136.274 38.365 108.832 15.689 125.874 46.365C147.874 85.965 67.474 85.565 50.674 74.365C33.874 63.165 57.874 92.765 57.874 92.765C76.274 112.765 41.874 95.965 41.874 95.965C7.473 83.165 -16.527 108.765 -19.727 109.565C-22.927 110.365 -27.727 113.565 -28.527 107.165C-29.327 100.765 -35.786 85.405 -68.527 110.365C-98.418 132.929 -109.745 115.293 -109.745 115.293L-115.745 114.965C-129.346 88.564 -120.963 144.038 -120.963 144.038C-112.163 178.438 22.673 130.365 22.673 130.365C22.673 130.365 191.474 99.965 202.674 95.965C213.874 91.965 302.093 97.783 302.093 97.783L297.075 76.91C232.274 30.51 219.474 58.365 205.874 54.365C192.274 50.365 194.674 59.965 191.474 60.765C188.274 61.565 149.074 36.765 142.674 37.565z").setFill(f).setStroke(s);
+ f = "#fae5d7";
+ g.createPath("M143.983 39.31C137.583 40.11 110.529 17.223 127.183 48.11C149.183 88.91 68.783 87.31 51.983 76.11C35.183 64.91 59.183 94.51 59.183 94.51C77.583 114.51 43.183 97.71 43.183 97.71C8.783 84.91 -15.217 110.51 -18.417 111.31C-21.618 112.11 -26.418 115.31 -27.218 108.91C-28.018 102.51 -34.346 87.318 -67.218 112.11C-98.345 135.42 -109.363 118.329 -109.363 118.329L-115.764 116.51C-128.764 92.51 -120.309 147.093 -120.309 147.093C-111.509 181.493 23.983 132.11 23.983 132.11C23.983 132.11 192.783 101.71 203.983 97.71C215.183 93.71 302.529 99.456 302.529 99.456L297.583 78.074C232.783 31.673 220.783 60.11 207.183 56.11C193.583 52.11 195.983 61.71 192.783 62.51C189.583 63.31 150.383 38.51 143.983 39.31z").setFill(f).setStroke(s);
+ f = "#fcf2eb";
+ g.createPath("M145.292 41.055C138.892 41.855 112.917 18.411 128.492 49.855C149.692 92.656 70.092 89.056 53.292 77.856C36.492 66.656 60.492 96.256 60.492 96.256C78.892 116.256 44.492 99.456 44.492 99.456C10.092 86.656 -13.908 112.256 -17.108 113.056C-20.308 113.856 -25.108 117.056 -25.908 110.656C-26.708 104.256 -32.905 89.232 -65.908 113.856C-98.273 137.911 -108.982 121.365 -108.982 121.365L-115.782 118.056C-128.582 94.856 -119.654 150.147 -119.654 150.147C-110.854 184.547 25.292 133.856 25.292 133.856C25.292 133.856 194.093 103.456 205.293 99.456C216.493 95.456 302.965 101.128 302.965 101.128L298.093 79.237C233.292 32.837 222.093 61.856 208.493 57.856C194.893 53.855 197.293 63.456 194.093 64.256C190.892 65.056 151.692 40.255 145.292 41.055z").setFill(f).setStroke(s);
+ f = "#ffffff";
+ g.createPath("M-115.8 119.601C-128.6 97.6 -119 153.201 -119 153.201C-110.2 187.601 26.6 135.601 26.6 135.601C26.6 135.601 195.401 105.2 206.601 101.2C217.801 97.2 303.401 102.8 303.401 102.8L298.601 80.4C233.801 34 223.401 63.6 209.801 59.6C196.201 55.6 198.601 65.2 195.401 66C192.201 66.8 153.001 42 146.601 42.8C140.201 43.6 114.981 19.793 129.801 51.6C152.028 99.307 69.041 89.227 54.6 79.6C37.8 68.4 61.8 98 61.8 98C80.2 118.001 45.8 101.2 45.8 101.2C11.4 88.4 -12.6 114.001 -15.8 114.801C-19 115.601 -23.8 118.801 -24.6 112.401C-25.4 106 -31.465 91.144 -64.6 115.601C-98.2 140.401 -108.6 124.401 -108.6 124.401L-115.8 119.601z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-74.2 149.601C-74.2 149.601 -81.4 161.201 -60.6 174.401C-60.6 174.401 -59.2 175.801 -77.2 171.601C-77.2 171.601 -83.4 169.601 -85 159.201C-85 159.201 -89.8 154.801 -94.6 149.201C-99.4 143.601 -74.2 149.601 -74.2 149.601z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M65.8 102C65.8 102 83.498 128.821 82.9 133.601C81.6 144.001 81.4 153.601 84.6 157.601C87.801 161.601 96.601 194.801 96.601 194.801C96.601 194.801 96.201 196.001 108.601 158.001C108.601 158.001 120.201 142.001 100.201 123.601C100.201 123.601 65 94.8 65.8 102z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-54.2 176.401C-54.2 176.401 -43 183.601 -57.4 214.801L-51 212.401C-51 212.401 -51.8 223.601 -55 226.001L-47.8 222.801C-47.8 222.801 -43 230.801 -47 235.601C-47 235.601 -30.2 243.601 -31 250.001C-31 250.001 -24.6 242.001 -28.6 235.601C-32.6 229.201 -39.8 233.201 -39 214.801L-47.8 218.001C-47.8 218.001 -42.2 209.201 -42.2 202.801L-50.2 205.201C-50.2 205.201 -34.731 178.623 -45.4 177.201C-51.4 176.401 -54.2 176.401 -54.2 176.401z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-21.8 193.201C-21.8 193.201 -19 188.801 -21.8 189.601C-24.6 190.401 -55.8 205.201 -61.8 214.801C-61.8 214.801 -27.4 190.401 -21.8 193.201z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-11.4 201.201C-11.4 201.201 -8.6 196.801 -11.4 197.601C-14.2 198.401 -45.4 213.201 -51.4 222.801C-51.4 222.801 -17 198.401 -11.4 201.201z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M1.8 186.001C1.8 186.001 4.6 181.601 1.8 182.401C-1 183.201 -32.2 198.001 -38.2 207.601C-38.2 207.601 -3.8 183.201 1.8 186.001z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-21.4 229.601C-21.4 229.601 -21.4 223.601 -24.2 224.401C-27 225.201 -63 242.801 -69 252.401C-69 252.401 -27 226.801 -21.4 229.601z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-20.2 218.801C-20.2 218.801 -19 214.001 -21.8 214.801C-23.8 214.801 -50.2 226.401 -56.2 236.001C-56.2 236.001 -26.6 214.401 -20.2 218.801z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-34.6 266.401L-44.6 274.001C-44.6 274.001 -34.2 266.401 -30.6 267.601C-30.6 267.601 -37.4 278.801 -38.2 284.001C-38.2 284.001 -27.8 271.201 -22.2 271.601C-22.2 271.601 -14.6 272.001 -14.6 282.801C-14.6 282.801 -9 272.401 -5.8 272.801C-5.8 272.801 -4.6 279.201 -5.8 286.001C-5.8 286.001 -1.8 278.401 2.2 280.001C2.2 280.001 8.6 278.001 7.8 289.601C7.8 289.601 7.8 300.001 7 302.801C7 302.801 12.6 276.401 15 276.001C15 276.001 23 274.801 27.8 283.601C27.8 283.601 23.8 276.001 28.6 278.001C28.6 278.001 39.4 279.601 42.6 286.401C42.6 286.401 35.8 274.401 41.4 277.601C41.4 277.601 48.2 277.601 49.4 284.001C49.4 284.001 57.8 305.201 59.8 306.801C59.8 306.801 52.2 285.201 53.8 285.201C53.8 285.201 51.8 273.201 57 288.001C57 288.001 53.8 274.001 59.4 274.801C65 275.601 69.4 285.601 77.8 283.201C77.8 283.201 87.401 288.801 89.401 219.601L-34.6 266.401z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-29.8 173.601C-29.8 173.601 -15 167.601 25 173.601C25 173.601 32.2 174.001 39 165.201C45.8 156.401 72.6 149.201 79 151.201L88.601 157.601L89.401 158.801C89.401 158.801 101.801 169.201 102.201 176.801C102.601 184.401 87.801 232.401 78.2 248.401C68.6 264.401 59 276.801 39.8 274.401C39.8 274.401 19 270.401 -6.6 274.401C-6.6 274.401 -35.8 272.801 -38.6 264.801C-41.4 256.801 -27.4 241.601 -27.4 241.601C-27.4 241.601 -23 233.201 -24.2 218.801C-25.4 204.401 -25 176.401 -29.8 173.601z").setFill(f).setStroke(s);
+ f = "#e5668c";
+ g.createPath("M-7.8 175.601C0.6 194.001 -29 259.201 -29 259.201C-31 260.801 -16.34 266.846 -6.2 264.401C4.746 261.763 45 266.001 45 266.001C68.6 250.401 81.4 206.001 81.4 206.001C81.4 206.001 91.801 182.001 74.2 178.801C56.6 175.601 -7.8 175.601 -7.8 175.601z").setFill(f).setStroke(s);
+ f = "#b23259";
+ g.createPath("M-9.831 206.497C-6.505 193.707 -4.921 181.906 -7.8 175.601C-7.8 175.601 54.6 182.001 65.8 161.201C70.041 153.326 84.801 184.001 84.4 193.601C84.4 193.601 21.4 208.001 6.6 196.801L-9.831 206.497z").setFill(f).setStroke(s);
+ f = "#a5264c";
+ g.createPath("M-5.4 222.801C-5.4 222.801 -3.4 230.001 -5.8 234.001C-5.8 234.001 -7.4 234.801 -8.6 235.201C-8.6 235.201 -7.4 238.801 -1.4 240.401C-1.4 240.401 0.6 244.801 3 245.201C5.4 245.601 10.2 251.201 14.2 250.001C18.2 248.801 29.4 244.801 29.4 244.801C29.4 244.801 35 241.601 43.8 245.201C43.8 245.201 46.175 244.399 46.6 240.401C47.1 235.701 50.2 232.001 52.2 230.001C54.2 228.001 63.8 215.201 62.6 214.801C61.4 214.401 -5.4 222.801 -5.4 222.801z").setFill(f).setStroke(s);
+ f = "#ff727f"; s = "#000000";
+ g.createPath("M-9.8 174.401C-9.8 174.401 -12.6 196.801 -9.4 205.201C-6.2 213.601 -7 215.601 -7.8 219.601C-8.6 223.601 -4.2 233.601 1.4 239.601L13.4 241.201C13.4 241.201 28.6 237.601 37.8 240.401C37.8 240.401 46.794 241.744 50.2 226.801C50.2 226.801 55 220.401 62.2 217.601C69.4 214.801 76.6 173.201 72.6 165.201C68.6 157.201 54.2 152.801 38.2 168.401C22.2 184.001 20.2 167.201 -9.8 174.401z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-8.2 249.201C-8.2 249.201 -9 247.201 -13.4 246.801C-13.4 246.801 -35.8 243.201 -44.2 230.801C-44.2 230.801 -51 225.201 -46.6 236.801C-46.6 236.801 -36.2 257.201 -29.4 260.001C-29.4 260.001 -13 264.001 -8.2 249.201z").setFill(f).setStroke(s);
+ f = "#cc3f4c"; s = null;
+ g.createPath("M71.742 185.229C72.401 177.323 74.354 168.709 72.6 165.201C66.154 152.307 49.181 157.695 38.2 168.401C22.2 184.001 20.2 167.201 -9.8 174.401C-9.8 174.401 -11.545 188.364 -10.705 198.376C-10.705 198.376 26.6 186.801 27.4 192.401C27.4 192.401 29 189.201 38.2 189.201C47.4 189.201 70.142 188.029 71.742 185.229z").setFill(f).setStroke(s);
+ s = {color: "#a51926", width: 2}; f = null;
+ g.createPath("M28.6 175.201C28.6 175.201 33.4 180.001 29.8 189.601C29.8 189.601 15.4 205.601 17.4 219.601").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-19.4 260.001C-19.4 260.001 -23.8 247.201 -15 254.001C-15 254.001 -10.2 256.001 -11.4 257.601C-12.6 259.201 -18.2 263.201 -19.4 260.001z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-14.36 261.201C-14.36 261.201 -17.88 250.961 -10.84 256.401C-10.84 256.401 -6.419 258.849 -7.96 259.281C-12.52 260.561 -7.96 263.121 -14.36 261.201z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-9.56 261.201C-9.56 261.201 -13.08 250.961 -6.04 256.401C-6.04 256.401 -1.665 258.711 -3.16 259.281C-6.52 260.561 -3.16 263.121 -9.56 261.201z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-2.96 261.401C-2.96 261.401 -6.48 251.161 0.56 256.601C0.56 256.601 4.943 258.933 3.441 259.481C0.48 260.561 3.441 263.321 -2.96 261.401z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M3.52 261.321C3.52 261.321 0 251.081 7.041 256.521C7.041 256.521 10.881 258.121 9.921 259.401C8.961 260.681 9.921 263.241 3.52 261.321z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M10.2 262.001C10.2 262.001 5.4 249.601 14.6 256.001C14.6 256.001 19.4 258.001 18.2 259.601C17 261.201 18.2 264.401 10.2 262.001z").setFill(f).setStroke(s);
+ s = {color: "#a5264c", width: 2}; f = null;
+ g.createPath("M-18.2 244.801C-18.2 244.801 -5 242.001 1 245.201C1 245.201 7 246.401 8.2 246.001C9.4 245.601 12.6 245.201 12.6 245.201").setFill(f).setStroke(s);
+ s = {color: "#a5264c", width: 2};
+ g.createPath("M15.8 253.601C15.8 253.601 27.8 240.001 39.8 244.401C46.816 246.974 45.8 243.601 46.6 240.801C47.4 238.001 47.6 233.801 52.6 230.801").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M33 237.601C33 237.601 29 226.801 26.2 239.601C23.4 252.401 20.2 256.001 18.6 258.801C18.6 258.801 18.6 264.001 27 263.601C27 263.601 37.8 263.201 38.2 260.401C38.6 257.601 37 246.001 33 237.601z").setFill(f).setStroke(s);
+ s = {color: "#a5264c", width: 2}; f = null;
+ g.createPath("M47 244.801C47 244.801 50.6 242.401 53 243.601").setFill(f).setStroke(s);
+ s = {color: "#a5264c", width: 2};
+ g.createPath("M53.5 228.401C53.5 228.401 56.4 223.501 61.2 222.701").setFill(f).setStroke(s);
+ f = "#b2b2b2"; s = null;
+ g.createPath("M-25.8 265.201C-25.8 265.201 -7.8 268.401 -3.4 266.801C-3.4 266.801 5.4 266.801 -3 268.801C-3 268.801 -15.8 268.801 -23.8 267.601C-23.8 267.601 -35.4 262.001 -25.8 265.201z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-11.8 172.001C-11.8 172.001 5.8 172.001 7.8 172.801C7.8 172.801 15 203.601 11.4 211.201C11.4 211.201 10.2 214.001 7.4 208.401C7.4 208.401 -11 175.601 -14.2 173.601C-17.4 171.601 -13 172.001 -11.8 172.001z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-88.9 169.301C-88.9 169.301 -80 171.001 -67.4 173.601C-67.4 173.601 -62.6 196.001 -59.4 200.801C-56.2 205.601 -59.8 205.601 -63.4 202.801C-67 200.001 -81.8 186.001 -83.8 181.601C-85.8 177.201 -88.9 169.301 -88.9 169.301z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-67.039 173.818C-67.039 173.818 -61.239 175.366 -60.23 177.581C-59.222 179.795 -61.432 183.092 -61.432 183.092C-61.432 183.092 -62.432 186.397 -63.634 184.235C-64.836 182.072 -67.708 174.412 -67.039 173.818z").setFill(f).setStroke(s);
+ f = "#000000"; s = null;
+ g.createPath("M-67 173.601C-67 173.601 -63.4 178.801 -59.8 178.801C-56.2 178.801 -55.818 178.388 -53 179.001C-48.4 180.001 -48.8 178.001 -42.2 179.201C-39.56 179.681 -37 178.801 -34.2 180.001C-31.4 181.201 -28.2 180.401 -27 178.401C-25.8 176.401 -21 172.201 -21 172.201C-21 172.201 -33.8 174.001 -36.6 174.801C-36.6 174.801 -59 176.001 -67 173.601z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-22.4 173.801C-22.4 173.801 -28.85 177.301 -29.25 179.701C-29.65 182.101 -24 185.801 -24 185.801C-24 185.801 -21.25 190.401 -20.65 188.001C-20.05 185.601 -21.6 174.201 -22.4 173.801z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-59.885 179.265C-59.885 179.265 -52.878 190.453 -52.661 179.242C-52.661 179.242 -52.104 177.984 -53.864 177.962C-59.939 177.886 -58.418 173.784 -59.885 179.265z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-52.707 179.514C-52.707 179.514 -44.786 190.701 -45.422 179.421C-45.422 179.421 -45.415 179.089 -47.168 178.936C-51.915 178.522 -51.57 174.004 -52.707 179.514z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-45.494 179.522C-45.494 179.522 -37.534 190.15 -38.203 180.484C-38.203 180.484 -38.084 179.251 -39.738 178.95C-43.63 178.244 -43.841 174.995 -45.494 179.522z").setFill(f).setStroke(s);
+ f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+ g.createPath("M-38.618 179.602C-38.618 179.602 -30.718 191.163 -30.37 181.382C-30.37 181.382 -28.726 180.004 -30.472 179.782C-36.29 179.042 -35.492 174.588 -38.618 179.602z").setFill(f).setStroke(s);
+ f = "#e5e5b2"; s = null;
+ g.createPath("M-74.792 183.132L-82.45 181.601C-85.05 176.601 -87.15 170.451 -87.15 170.451C-87.15 170.451 -80.8 171.451 -68.3 174.251C-68.3 174.251 -67.424 177.569 -65.952 183.364L-74.792 183.132z").setFill(f).setStroke(s);
+ f = "#e5e5b2";
+ g.createPath("M-9.724 178.47C-11.39 175.964 -12.707 174.206 -13.357 173.8C-16.37 171.917 -12.227 172.294 -11.098 172.294C-11.098 172.294 5.473 172.294 7.356 173.047C7.356 173.047 7.88 175.289 8.564 178.68C8.564 178.68 -1.524 176.67 -9.724 178.47z").setFill(f).setStroke(s);
+ f = "#cc7226";
+ g.createPath("M43.88 40.321C71.601 44.281 97.121 8.641 98.881 -1.04C100.641 -10.72 90.521 -22.6 90.521 -22.6C91.841 -25.68 87.001 -39.76 81.721 -49C76.441 -58.24 60.54 -57.266 43 -58.24C27.16 -59.12 8.68 -35.8 7.36 -34.04C6.04 -32.28 12.2 6.001 13.52 11.721C14.84 17.441 12.2 43.841 12.2 43.841C46.44 34.741 16.16 36.361 43.88 40.321z").setFill(f).setStroke(s);
+ f = "#ea8e51";
+ g.createPath("M8.088 -33.392C6.792 -31.664 12.84 5.921 14.136 11.537C15.432 17.153 12.84 43.073 12.84 43.073C45.512 34.193 16.728 35.729 43.944 39.617C71.161 43.505 96.217 8.513 97.945 -0.992C99.673 -10.496 89.737 -22.16 89.737 -22.16C91.033 -25.184 86.281 -39.008 81.097 -48.08C75.913 -57.152 60.302 -56.195 43.08 -57.152C27.528 -58.016 9.384 -35.12 8.088 -33.392z").setFill(f).setStroke(s);
+ f = "#efaa7c";
+ g.createPath("M8.816 -32.744C7.544 -31.048 13.48 5.841 14.752 11.353C16.024 16.865 13.48 42.305 13.48 42.305C44.884 33.145 17.296 35.097 44.008 38.913C70.721 42.729 95.313 8.385 97.009 -0.944C98.705 -10.272 88.953 -21.72 88.953 -21.72C90.225 -24.688 85.561 -38.256 80.473 -47.16C75.385 -56.064 60.063 -55.125 43.16 -56.064C27.896 -56.912 10.088 -34.44 8.816 -32.744z").setFill(f).setStroke(s);
+ f = "#f4c6a8";
+ g.createPath("M9.544 -32.096C8.296 -30.432 14.12 5.761 15.368 11.169C16.616 16.577 14.12 41.537 14.12 41.537C43.556 32.497 17.864 34.465 44.072 38.209C70.281 41.953 94.409 8.257 96.073 -0.895C97.737 -10.048 88.169 -21.28 88.169 -21.28C89.417 -24.192 84.841 -37.504 79.849 -46.24C74.857 -54.976 59.824 -54.055 43.24 -54.976C28.264 -55.808 10.792 -33.76 9.544 -32.096z").setFill(f).setStroke(s);
+ f = "#f9e2d3";
+ g.createPath("M10.272 -31.448C9.048 -29.816 14.76 5.681 15.984 10.985C17.208 16.289 14.76 40.769 14.76 40.769C42.628 31.849 18.432 33.833 44.136 37.505C69.841 41.177 93.505 8.129 95.137 -0.848C96.769 -9.824 87.385 -20.84 87.385 -20.84C88.609 -23.696 84.121 -36.752 79.225 -45.32C74.329 -53.888 59.585 -52.985 43.32 -53.888C28.632 -54.704 11.496 -33.08 10.272 -31.448z").setFill(f).setStroke(s);
+ f = "#ffffff";
+ g.createPath("M44.2 36.8C69.4 40.4 92.601 8 94.201 -0.8C95.801 -9.6 86.601 -20.4 86.601 -20.4C87.801 -23.2 83.4 -36 78.6 -44.4C73.8 -52.8 59.346 -51.914 43.4 -52.8C29 -53.6 12.2 -32.4 11 -30.8C9.8 -29.2 15.4 5.6 16.6 10.8C17.8 16 15.4 40 15.4 40C40.9 31.4 19 33.2 44.2 36.8z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M90.601 2.8C90.601 2.8 62.8 10.4 51.2 8.8C51.2 8.8 35.4 2.2 26.6 24C26.6 24 23 31.2 21 33.2C19 35.2 90.601 2.8 90.601 2.8z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M94.401 0.6C94.401 0.6 65.4 12.8 55.4 12.4C55.4 12.4 39 7.8 30.6 22.4C30.6 22.4 22.2 31.6 19 33.2C19 33.2 18.6 34.8 25 30.8L35.4 36C35.4 36 50.2 45.6 59.8 29.6C59.8 29.6 63.8 18.4 63.8 16.4C63.8 14.4 85 8.8 86.601 8.4C88.201 8 94.801 3.8 94.401 0.6z").setFill(f).setStroke(s);
+ f = "#99cc32";
+ g.createPath("M47 36.514C40.128 36.514 31.755 32.649 31.755 26.4C31.755 20.152 40.128 13.887 47 13.887C53.874 13.887 59.446 18.952 59.446 25.2C59.446 31.449 53.874 36.514 47 36.514z").setFill(f).setStroke(s);
+ f = "#659900";
+ g.createPath("M43.377 19.83C38.531 20.552 33.442 22.055 33.514 21.839C35.054 17.22 41.415 13.887 47 13.887C51.296 13.887 55.084 15.865 57.32 18.875C57.32 18.875 52.004 18.545 43.377 19.83z").setFill(f).setStroke(s);
+ f = "#ffffff";
+ g.createPath("M55.4 19.6C55.4 19.6 51 16.4 51 18.6C51 18.6 54.6 23 55.4 19.6z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M45.4 27.726C42.901 27.726 40.875 25.7 40.875 23.2C40.875 20.701 42.901 18.675 45.4 18.675C47.9 18.675 49.926 20.701 49.926 23.2C49.926 25.7 47.9 27.726 45.4 27.726z").setFill(f).setStroke(s);
+ f = "#cc7226";
+ g.createPath("M-58.6 14.4C-58.6 14.4 -61.8 -6.8 -59.4 -11.2C-59.4 -11.2 -48.6 -21.2 -49 -24.8C-49 -24.8 -49.4 -42.8 -50.6 -43.6C-51.8 -44.4 -59.4 -50.4 -65.4 -44C-65.4 -44 -75.8 -26 -75 -19.6L-75 -17.6C-75 -17.6 -82.6 -18 -84.2 -16C-84.2 -16 -85.4 -10.8 -86.6 -10.4C-86.6 -10.4 -89.4 -8 -87.4 -5.2C-87.4 -5.2 -89.4 -2.8 -89 1.2L-81.4 5.2C-81.4 5.2 -79.4 19.6 -68.6 24.8C-63.764 27.129 -60.6 20.4 -58.6 14.4z").setFill(f).setStroke(s);
+ f = "#ffffff";
+ g.createPath("M-59.6 12.56C-59.6 12.56 -62.48 -6.52 -60.32 -10.48C-60.32 -10.48 -50.6 -19.48 -50.96 -22.72C-50.96 -22.72 -51.32 -38.92 -52.4 -39.64C-53.48 -40.36 -60.32 -45.76 -65.72 -40C-65.72 -40 -75.08 -23.8 -74.36 -18.04L-74.36 -16.24C-74.36 -16.24 -81.2 -16.6 -82.64 -14.8C-82.64 -14.8 -83.72 -10.12 -84.8 -9.76C-84.8 -9.76 -87.32 -7.6 -85.52 -5.08C-85.52 -5.08 -87.32 -2.92 -86.96 0.68L-80.12 4.28C-80.12 4.28 -78.32 17.24 -68.6 21.92C-64.248 24.015 -61.4 17.96 -59.6 12.56z").setFill(f).setStroke(s);
+ f = "#eb955c";
+ g.createPath("M-51.05 -42.61C-52.14 -43.47 -59.63 -49.24 -65.48 -43C-65.48 -43 -75.62 -25.45 -74.84 -19.21L-74.84 -17.26C-74.84 -17.26 -82.25 -17.65 -83.81 -15.7C-83.81 -15.7 -84.98 -10.63 -86.15 -10.24C-86.15 -10.24 -88.88 -7.9 -86.93 -5.17C-86.93 -5.17 -88.88 -2.83 -88.49 1.07L-81.08 4.97C-81.08 4.97 -79.13 19.01 -68.6 24.08C-63.886 26.35 -60.8 19.79 -58.85 13.94C-58.85 13.94 -61.97 -6.73 -59.63 -11.02C-59.63 -11.02 -49.1 -20.77 -49.49 -24.28C-49.49 -24.28 -49.88 -41.83 -51.05 -42.61z").setFill(f).setStroke(s);
+ f = "#f2b892";
+ g.createPath("M-51.5 -41.62C-52.48 -42.54 -59.86 -48.08 -65.56 -42C-65.56 -42 -75.44 -24.9 -74.68 -18.82L-74.68 -16.92C-74.68 -16.92 -81.9 -17.3 -83.42 -15.4C-83.42 -15.4 -84.56 -10.46 -85.7 -10.08C-85.7 -10.08 -88.36 -7.8 -86.46 -5.14C-86.46 -5.14 -88.36 -2.86 -87.98 0.94L-80.76 4.74C-80.76 4.74 -78.86 18.42 -68.6 23.36C-64.006 25.572 -61 19.18 -59.1 13.48C-59.1 13.48 -62.14 -6.66 -59.86 -10.84C-59.86 -10.84 -49.6 -20.34 -49.98 -23.76C-49.98 -23.76 -50.36 -40.86 -51.5 -41.62z").setFill(f).setStroke(s);
+ f = "#f8dcc8";
+ g.createPath("M-51.95 -40.63C-52.82 -41.61 -60.09 -46.92 -65.64 -41C-65.64 -41 -75.26 -24.35 -74.52 -18.43L-74.52 -16.58C-74.52 -16.58 -81.55 -16.95 -83.03 -15.1C-83.03 -15.1 -84.14 -10.29 -85.25 -9.92C-85.25 -9.92 -87.84 -7.7 -85.99 -5.11C-85.99 -5.11 -87.84 -2.89 -87.47 0.81L-80.44 4.51C-80.44 4.51 -78.59 17.83 -68.6 22.64C-64.127 24.794 -61.2 18.57 -59.35 13.02C-59.35 13.02 -62.31 -6.59 -60.09 -10.66C-60.09 -10.66 -50.1 -19.91 -50.47 -23.24C-50.47 -23.24 -50.84 -39.89 -51.95 -40.63z").setFill(f).setStroke(s);
+ f = "#ffffff";
+ g.createPath("M-59.6 12.46C-59.6 12.46 -62.48 -6.52 -60.32 -10.48C-60.32 -10.48 -50.6 -19.48 -50.96 -22.72C-50.96 -22.72 -51.32 -38.92 -52.4 -39.64C-53.16 -40.68 -60.32 -45.76 -65.72 -40C-65.72 -40 -75.08 -23.8 -74.36 -18.04L-74.36 -16.24C-74.36 -16.24 -81.2 -16.6 -82.64 -14.8C-82.64 -14.8 -83.72 -10.12 -84.8 -9.76C-84.8 -9.76 -87.32 -7.6 -85.52 -5.08C-85.52 -5.08 -87.32 -2.92 -86.96 0.68L-80.12 4.28C-80.12 4.28 -78.32 17.24 -68.6 21.92C-64.248 24.015 -61.4 17.86 -59.6 12.46z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-62.7 6.2C-62.7 6.2 -84.3 -4 -85.2 -4.8C-85.2 -4.8 -76.1 3.4 -75.3 3.4C-74.5 3.4 -62.7 6.2 -62.7 6.2z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-79.8 0C-79.8 0 -61.4 3.6 -61.4 8C-61.4 10.912 -61.643 24.331 -67 22.8C-75.4 20.4 -71.8 6 -79.8 0z").setFill(f).setStroke(s);
+ f = "#99cc32";
+ g.createPath("M-71.4 3.8C-71.4 3.8 -62.422 5.274 -61.4 8C-60.8 9.6 -60.137 17.908 -65.6 19C-70.152 19.911 -72.382 9.69 -71.4 3.8z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M14.595 46.349C14.098 44.607 15.409 44.738 17.2 44.2C19.2 43.6 31.4 39.8 32.2 37.2C33 34.6 46.2 39 46.2 39C48 39.8 52.4 42.4 52.4 42.4C57.2 43.6 63.8 44 63.8 44C66.2 45 69.6 47.8 69.6 47.8C84.2 58 96.601 50.8 96.601 50.8C116.601 44.2 110.601 27 110.601 27C107.601 18 110.801 14.6 110.801 14.6C111.001 10.8 118.201 17.2 118.201 17.2C120.801 21.4 121.601 26.4 121.601 26.4C129.601 37.6 126.201 19.8 126.201 19.8C126.401 18.8 123.601 15.2 123.601 14C123.601 12.8 121.801 9.4 121.801 9.4C118.801 6 121.201 -1 121.201 -1C123.001 -14.8 120.801 -13 120.801 -13C119.601 -14.8 110.401 -4.8 110.401 -4.8C108.201 -1.4 102.201 0.2 102.201 0.2C99.401 2 96.001 0.6 96.001 0.6C93.401 0.2 87.801 7.2 87.801 7.2C90.601 7 93.001 11.4 95.401 11.6C97.801 11.8 99.601 9.2 101.201 8.6C102.801 8 105.601 13.8 105.601 13.8C106.001 16.4 100.401 21.2 100.401 21.2C100.001 25.8 98.401 24.2 98.401 24.2C95.401 23.6 94.201 27.4 93.201 32C92.201 36.6 88.001 37 88.001 37C86.401 44.4 85.2 41.4 85.2 41.4C85 35.8 79 41.6 79 41.6C77.8 43.6 73.2 41.4 73.2 41.4C66.4 39.4 68.8 37.4 68.8 37.4C70.6 35.2 81.8 37.4 81.8 37.4C84 35.8 76 31.8 76 31.8C75.4 30 76.4 25.6 76.4 25.6C77.6 22.4 84.4 16.8 84.4 16.8C93.801 15.6 91.001 14 91.001 14C84.801 8.8 79 16.4 79 16.4C76.8 22.6 59.4 37.6 59.4 37.6C54.6 41 57.2 34.2 53.2 37.6C49.2 41 28.6 32 28.6 32C17.038 30.807 14.306 46.549 10.777 43.429C10.777 43.429 16.195 51.949 14.595 46.349z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M209.401 -120C209.401 -120 183.801 -112 181.001 -93.2C181.001 -93.2 178.601 -70.4 199.001 -52.8C199.001 -52.8 199.401 -46.4 201.401 -43.2C201.401 -43.2 199.801 -38.4 218.601 -46L245.801 -54.4C245.801 -54.4 252.201 -56.8 257.401 -65.6C262.601 -74.4 277.801 -93.2 274.201 -118.4C274.201 -118.4 275.401 -129.6 269.401 -130C269.401 -130 261.001 -131.6 253.801 -124C253.801 -124 247.001 -120.8 244.601 -121.2L209.401 -120z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M264.022 -120.99C264.022 -120.99 266.122 -129.92 261.282 -125.08C261.282 -125.08 254.242 -119.36 246.761 -119.36C246.761 -119.36 232.241 -117.16 227.841 -103.96C227.841 -103.96 223.881 -77.12 231.801 -71.4C231.801 -71.4 236.641 -63.92 243.681 -70.52C250.722 -77.12 266.222 -107.35 264.022 -120.99z").setFill(f).setStroke(s);
+ f = "#323232";
+ g.createPath("M263.648 -120.632C263.648 -120.632 265.738 -129.376 260.986 -124.624C260.986 -124.624 254.074 -119.008 246.729 -119.008C246.729 -119.008 232.473 -116.848 228.153 -103.888C228.153 -103.888 224.265 -77.536 232.041 -71.92C232.041 -71.92 236.793 -64.576 243.705 -71.056C250.618 -77.536 265.808 -107.24 263.648 -120.632z").setFill(f).setStroke(s);
+ f = "#666666";
+ g.createPath("M263.274 -120.274C263.274 -120.274 265.354 -128.832 260.69 -124.168C260.69 -124.168 253.906 -118.656 246.697 -118.656C246.697 -118.656 232.705 -116.536 228.465 -103.816C228.465 -103.816 224.649 -77.952 232.281 -72.44C232.281 -72.44 236.945 -65.232 243.729 -71.592C250.514 -77.952 265.394 -107.13 263.274 -120.274z").setFill(f).setStroke(s);
+ f = "#999999";
+ g.createPath("M262.9 -119.916C262.9 -119.916 264.97 -128.288 260.394 -123.712C260.394 -123.712 253.738 -118.304 246.665 -118.304C246.665 -118.304 232.937 -116.224 228.777 -103.744C228.777 -103.744 225.033 -78.368 232.521 -72.96C232.521 -72.96 237.097 -65.888 243.753 -72.128C250.41 -78.368 264.98 -107.02 262.9 -119.916z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M262.526 -119.558C262.526 -119.558 264.586 -127.744 260.098 -123.256C260.098 -123.256 253.569 -117.952 246.633 -117.952C246.633 -117.952 233.169 -115.912 229.089 -103.672C229.089 -103.672 225.417 -78.784 232.761 -73.48C232.761 -73.48 237.249 -66.544 243.777 -72.664C250.305 -78.784 264.566 -106.91 262.526 -119.558z").setFill(f).setStroke(s);
+ f = "#ffffff";
+ g.createPath("M262.151 -119.2C262.151 -119.2 264.201 -127.2 259.801 -122.8C259.801 -122.8 253.401 -117.6 246.601 -117.6C246.601 -117.6 233.401 -115.6 229.401 -103.6C229.401 -103.6 225.801 -79.2 233.001 -74C233.001 -74 237.401 -67.2 243.801 -73.2C250.201 -79.2 264.151 -106.8 262.151 -119.2z").setFill(f).setStroke(s);
+ f = "#992600";
+ g.createPath("M50.6 84C50.6 84 30.2 64.8 22.2 64C22.2 64 -12.2 60 -27 78C-27 78 -9.4 57.6 18.2 63.2C18.2 63.2 -3.4 58.8 -15.8 62C-15.8 62 -32.6 62 -42.2 76L-45 80.8C-45 80.8 -41 66 -22.6 60C-22.6 60 0.2 55.2 11 60C11 60 -10.6 53.2 -20.6 55.2C-20.6 55.2 -51 52.8 -63.8 79.2C-63.8 79.2 -59.8 64.8 -45 57.6C-45 57.6 -31.4 48.8 -11 51.6C-11 51.6 3.4 54.8 8.6 57.2C13.8 59.6 12.6 56.8 4.2 52C4.2 52 -1.4 42 -15.4 42.4C-15.4 42.4 -58.2 46 -68.6 58C-68.6 58 -55 46.8 -44.6 44C-44.6 44 -22.2 36 -13.8 36.8C-13.8 36.8 11 37.8 18.6 33.8C18.6 33.8 7.4 38.8 10.6 42C13.8 45.2 20.6 52.8 20.6 54C20.6 55.2 44.8 77.3 48.4 81.7L50.6 84z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M189 278C189 278 173.5 241.5 161 232C161 232 187 248 190.5 266C190.5 266 190.5 276 189 278z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M236 285.5C236 285.5 209.5 230.5 191 206.5C191 206.5 234.5 244 239.5 270.5L240 276L237 273.5C237 273.5 236.5 282.5 236 285.5z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M292.5 237C292.5 237 230 177.5 228.5 175C228.5 175 289 241 292 248.5C292 248.5 290 239.5 292.5 237z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M104 280.5C104 280.5 123.5 228.5 142.5 251C142.5 251 157.5 261 157 264C157 264 153 257.5 135 258C135 258 116 255 104 280.5z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M294.5 153C294.5 153 249.5 124.5 242 123C230.193 120.639 291.5 152 296.5 162.5C296.5 162.5 298.5 160 294.5 153z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M143.801 259.601C143.801 259.601 164.201 257.601 171.001 250.801L175.401 254.401L193.001 216.001L196.601 221.201C196.601 221.201 211.001 206.401 210.201 198.401C209.401 190.401 223.001 204.401 223.001 204.401C223.001 204.401 222.201 192.801 229.401 199.601C229.401 199.601 227.001 184.001 235.401 192.001C235.401 192.001 224.864 161.844 247.401 187.601C253.001 194.001 248.601 187.201 248.601 187.201C248.601 187.201 222.601 139.201 244.201 153.601C244.201 153.601 246.201 130.801 245.001 126.401C243.801 122.001 241.801 99.6 237.001 94.4C232.201 89.2 237.401 87.6 243.001 92.8C243.001 92.8 231.801 68.8 245.001 80.8C245.001 80.8 241.401 65.6 237.001 62.8C237.001 62.8 231.401 45.6 246.601 56.4C246.601 56.4 242.201 44 239.001 40.8C239.001 40.8 227.401 13.2 234.601 18L239.001 21.6C239.001 21.6 232.201 7.6 238.601 12C245.001 16.4 245.001 16 245.001 16C245.001 16 223.801 -17.2 244.201 0.4C244.201 0.4 236.042 -13.518 232.601 -20.4C232.601 -20.4 213.801 -40.8 228.201 -34.4L233.001 -32.8C233.001 -32.8 224.201 -42.8 216.201 -44.4C208.201 -46 218.601 -52.4 225.001 -50.4C231.401 -48.4 247.001 -40.8 247.001 -40.8C247.001 -40.8 259.801 -22 263.801 -21.6C263.801 -21.6 243.801 -29.2 249.801 -21.2C249.801 -21.2 264.201 -7.2 257.001 -7.6C257.001 -7.6 251.001 -0.4 255.801 8.4C255.801 8.4 237.342 -9.991 252.201 15.6L259.001 32C259.001 32 234.601 7.2 245.801 29.2C245.801 29.2 263.001 52.8 265.001 53.2C267.001 53.6 271.401 62.4 271.401 62.4L267.001 60.4L272.201 69.2C272.201 69.2 261.001 57.2 267.001 70.4L272.601 84.8C272.601 84.8 252.201 62.8 265.801 92.4C265.801 92.4 249.401 87.2 258.201 104.4C258.201 104.4 256.601 120.401 257.001 125.601C257.401 130.801 258.601 159.201 254.201 167.201C249.801 175.201 260.201 194.401 262.201 198.401C264.201 202.401 267.801 213.201 259.001 204.001C250.201 194.801 254.601 200.401 256.601 209.201C258.601 218.001 264.601 233.601 263.801 239.201C263.801 239.201 262.601 240.401 259.401 236.801C259.401 236.801 244.601 214.001 246.201 228.401C246.201 228.401 245.001 236.401 241.801 245.201C241.801 245.201 238.601 256.001 238.601 247.201C238.601 247.201 235.401 230.401 232.601 238.001C229.801 245.601 226.201 251.601 223.401 254.001C220.601 256.401 215.401 233.601 214.201 244.001C214.201 244.001 202.201 231.601 197.401 248.001L185.801 264.401C185.801 264.401 185.401 252.001 184.201 258.001C184.201 258.001 154.201 264.001 143.801 259.601z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M109.401 -97.2C109.401 -97.2 97.801 -105.2 93.801 -104.8C89.801 -104.4 121.401 -113.6 162.601 -86C162.601 -86 167.401 -83.2 171.001 -83.6C171.001 -83.6 174.201 -81.2 171.401 -77.6C171.401 -77.6 162.601 -68 173.801 -56.8C173.801 -56.8 192.201 -50 186.601 -58.8C186.601 -58.8 197.401 -54.8 199.801 -50.8C202.201 -46.8 201.001 -50.8 201.001 -50.8C201.001 -50.8 194.601 -58 188.601 -63.2C188.601 -63.2 183.401 -65.2 180.601 -73.6C177.801 -82 175.401 -92 179.801 -95.2C179.801 -95.2 175.801 -90.8 176.601 -94.8C177.401 -98.8 181.001 -102.4 182.601 -102.8C184.201 -103.2 200.601 -119 207.401 -119.4C207.401 -119.4 198.201 -118 195.201 -119C192.201 -120 165.601 -131.4 159.601 -132.6C159.601 -132.6 142.801 -139.2 154.801 -137.2C154.801 -137.2 190.601 -133.4 208.801 -120.2C208.801 -120.2 201.601 -128.6 183.201 -135.6C183.201 -135.6 161.001 -148.2 125.801 -143.2C125.801 -143.2 108.001 -140 100.201 -138.2C100.201 -138.2 97.601 -138.8 97.001 -139.2C96.401 -139.6 84.6 -148.6 57 -141.6C57 -141.6 40 -137 31.4 -132.2C31.4 -132.2 16.2 -131 12.6 -127.8C12.6 -127.8 -6 -113.2 -8 -112.4C-10 -111.6 -21.4 -104 -22.2 -103.6C-22.2 -103.6 2.4 -110.2 4.8 -112.6C7.2 -115 24.6 -117.6 27 -116.2C29.4 -114.8 37.8 -115.4 28.2 -114.8C28.2 -114.8 103.801 -100 104.601 -98C105.401 -96 109.401 -97.2 109.401 -97.2z").setFill(f).setStroke(s);
+ f = "#cc7226";
+ g.createPath("M180.801 -106.4C180.801 -106.4 170.601 -113.8 168.601 -113.8C166.601 -113.8 154.201 -124 150.001 -123.6C145.801 -123.2 133.601 -133.2 106.201 -125C106.201 -125 105.601 -127 109.201 -127.8C109.201 -127.8 115.601 -130 116.001 -130.6C116.001 -130.6 136.201 -134.8 143.401 -131.2C143.401 -131.2 152.601 -128.6 158.801 -122.4C158.801 -122.4 170.001 -119.2 173.201 -120.2C173.201 -120.2 182.001 -118 182.401 -116.2C182.401 -116.2 188.201 -113.2 186.401 -110.6C186.401 -110.6 186.801 -109 180.801 -106.4z").setFill(f).setStroke(s);
+ f = "#cc7226";
+ g.createPath("M168.33 -108.509C169.137 -107.877 170.156 -107.779 170.761 -106.97C170.995 -106.656 170.706 -106.33 170.391 -106.233C169.348 -105.916 168.292 -106.486 167.15 -105.898C166.748 -105.691 166.106 -105.873 165.553 -106.022C163.921 -106.463 162.092 -106.488 160.401 -105.8C158.416 -106.929 156.056 -106.345 153.975 -107.346C153.917 -107.373 153.695 -107.027 153.621 -107.054C150.575 -108.199 146.832 -107.916 144.401 -110.2C141.973 -110.612 139.616 -111.074 137.188 -111.754C135.37 -112.263 133.961 -113.252 132.341 -114.084C130.964 -114.792 129.507 -115.314 127.973 -115.686C126.11 -116.138 124.279 -116.026 122.386 -116.546C122.293 -116.571 122.101 -116.227 122.019 -116.254C121.695 -116.362 121.405 -116.945 121.234 -116.892C119.553 -116.37 118.065 -117.342 116.401 -117C115.223 -118.224 113.495 -117.979 111.949 -118.421C108.985 -119.269 105.831 -117.999 102.801 -119C106.914 -120.842 111.601 -119.61 115.663 -121.679C117.991 -122.865 120.653 -121.763 123.223 -122.523C123.71 -122.667 124.401 -122.869 124.801 -122.2C124.935 -122.335 125.117 -122.574 125.175 -122.546C127.625 -121.389 129.94 -120.115 132.422 -119.049C132.763 -118.903 133.295 -119.135 133.547 -118.933C135.067 -117.717 137.01 -117.82 138.401 -116.6C140.099 -117.102 141.892 -116.722 143.621 -117.346C143.698 -117.373 143.932 -117.032 143.965 -117.054C145.095 -117.802 146.25 -117.531 147.142 -117.227C147.48 -117.112 148.143 -116.865 148.448 -116.791C149.574 -116.515 150.43 -116.035 151.609 -115.852C151.723 -115.834 151.908 -116.174 151.98 -116.146C153.103 -115.708 154.145 -115.764 154.801 -114.6C154.936 -114.735 155.101 -114.973 155.183 -114.946C156.21 -114.608 156.859 -113.853 157.96 -113.612C158.445 -113.506 159.057 -112.88 159.633 -112.704C162.025 -111.973 163.868 -110.444 166.062 -109.549C166.821 -109.239 167.697 -109.005 168.33 -108.509z").setFill(f).setStroke(s);
+ f = "#cc7226";
+ g.createPath("M91.696 -122.739C89.178 -124.464 86.81 -125.57 84.368 -127.356C84.187 -127.489 83.827 -127.319 83.625 -127.441C82.618 -128.05 81.73 -128.631 80.748 -129.327C80.209 -129.709 79.388 -129.698 78.88 -129.956C76.336 -131.248 73.707 -131.806 71.2 -133C71.882 -133.638 73.004 -133.394 73.6 -134.2C73.795 -133.92 74.033 -133.636 74.386 -133.827C76.064 -134.731 77.914 -134.884 79.59 -134.794C81.294 -134.702 83.014 -134.397 84.789 -134.125C85.096 -134.078 85.295 -133.555 85.618 -133.458C87.846 -132.795 90.235 -133.32 92.354 -132.482C93.945 -131.853 95.515 -131.03 96.754 -129.755C97.006 -129.495 96.681 -129.194 96.401 -129C96.789 -129.109 97.062 -128.903 97.173 -128.59C97.257 -128.351 97.257 -128.049 97.173 -127.81C97.061 -127.498 96.782 -127.397 96.408 -127.346C95.001 -127.156 96.773 -128.536 96.073 -128.088C94.8 -127.274 95.546 -125.868 94.801 -124.6C94.521 -124.794 94.291 -125.012 94.401 -125.4C94.635 -124.878 94.033 -124.588 93.865 -124.272C93.48 -123.547 92.581 -122.132 91.696 -122.739z").setFill(f).setStroke(s);
+ f = "#cc7226";
+ g.createPath("M59.198 -115.391C56.044 -116.185 52.994 -116.07 49.978 -117.346C49.911 -117.374 49.688 -117.027 49.624 -117.054C48.258 -117.648 47.34 -118.614 46.264 -119.66C45.351 -120.548 43.693 -120.161 42.419 -120.648C42.095 -120.772 41.892 -121.284 41.591 -121.323C40.372 -121.48 39.445 -122.429 38.4 -123C40.736 -123.795 43.147 -123.764 45.609 -124.148C45.722 -124.166 45.867 -123.845 46 -123.845C46.136 -123.845 46.266 -124.066 46.4 -124.2C46.595 -123.92 46.897 -123.594 47.154 -123.848C47.702 -124.388 48.258 -124.198 48.798 -124.158C48.942 -124.148 49.067 -123.845 49.2 -123.845C49.336 -123.845 49.467 -124.156 49.6 -124.156C49.736 -124.155 49.867 -123.845 50 -123.845C50.136 -123.845 50.266 -124.066 50.4 -124.2C51.092 -123.418 51.977 -123.972 52.799 -123.793C53.837 -123.566 54.104 -122.418 55.178 -122.12C59.893 -120.816 64.03 -118.671 68.393 -116.584C68.7 -116.437 68.91 -116.189 68.8 -115.8C69.067 -115.8 69.38 -115.888 69.57 -115.756C70.628 -115.024 71.669 -114.476 72.366 -113.378C72.582 -113.039 72.253 -112.632 72.02 -112.684C67.591 -113.679 63.585 -114.287 59.198 -115.391z").setFill(f).setStroke(s);
+ f = "#cc7226";
+ g.createPath("M45.338 -71.179C43.746 -72.398 43.162 -74.429 42.034 -76.221C41.82 -76.561 42.094 -76.875 42.411 -76.964C42.971 -77.123 43.514 -76.645 43.923 -76.443C45.668 -75.581 47.203 -74.339 49.2 -74.2C51.19 -71.966 55.45 -71.581 55.457 -68.2C55.458 -67.341 54.03 -68.259 53.6 -67.4C51.149 -68.403 48.76 -68.3 46.38 -69.767C45.763 -70.148 46.093 -70.601 45.338 -71.179z").setFill(f).setStroke(s);
+ f = "#cc7226";
+ g.createPath("M17.8 -123.756C17.935 -123.755 24.966 -123.522 24.949 -123.408C24.904 -123.099 17.174 -122.05 16.81 -122.22C16.646 -122.296 9.134 -119.866 9 -120C9.268 -120.135 17.534 -123.756 17.8 -123.756z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M33.2 -114C33.2 -114 18.4 -112.2 14 -111C9.6 -109.8 -9 -102.2 -12 -100.2C-12 -100.2 -25.4 -94.8 -42.4 -74.8C-42.4 -74.8 -34.8 -78.2 -32.6 -81C-32.6 -81 -19 -93.6 -19.2 -91C-19.2 -91 -7 -99.6 -7.6 -97.4C-7.6 -97.4 16.8 -108.6 14.8 -105.4C14.8 -105.4 36.4 -110 35.4 -108C35.4 -108 54.2 -103.6 51.4 -103.4C51.4 -103.4 45.6 -102.2 52 -98.6C52 -98.6 48.6 -94.2 43.2 -98.2C37.8 -102.2 40.8 -100 35.8 -99C35.8 -99 33.2 -98.2 28.6 -102.2C28.6 -102.2 23 -106.8 14.2 -103.2C14.2 -103.2 -16.4 -90.6 -18.4 -90C-18.4 -90 -22 -87.2 -24.4 -83.6C-24.4 -83.6 -30.2 -79.2 -33.2 -77.8C-33.2 -77.8 -46 -66.2 -47.2 -64.8C-47.2 -64.8 -50.6 -59.6 -51.4 -59.2C-51.4 -59.2 -45 -63 -43 -65C-43 -65 -29 -75 -23.6 -75.8C-23.6 -75.8 -19.2 -78.8 -18.4 -80.2C-18.4 -80.2 -4 -89.4 0.2 -89.4C0.2 -89.4 9.4 -84.2 11.8 -91.2C11.8 -91.2 17.6 -93 23.2 -91.8C23.2 -91.8 26.4 -94.4 25.6 -96.6C25.6 -96.6 27.2 -98.4 28.2 -94.6C28.2 -94.6 31.6 -91 36.4 -93C36.4 -93 40.4 -93.2 38.4 -90.8C38.4 -90.8 34 -87 22.2 -86.8C22.2 -86.8 9.8 -86.2 -6.6 -78.6C-6.6 -78.6 -36.4 -68.2 -45.6 -57.8C-45.6 -57.8 -52 -49 -57.4 -47.8C-57.4 -47.8 -63.2 -47 -69.2 -39.6C-69.2 -39.6 -59.4 -45.4 -50.4 -45.4C-50.4 -45.4 -46.4 -47.8 -50.2 -44.2C-50.2 -44.2 -53.8 -36.6 -52.2 -31.2C-52.2 -31.2 -52.8 -26 -53.6 -24.4C-53.6 -24.4 -61.4 -11.6 -61.4 -9.2C-61.4 -6.8 -60.2 3 -59.8 3.6C-59.4 4.2 -60.8 2 -57 4.4C-53.2 6.8 -50.4 8.4 -49.6 11.2C-48.8 14 -51.6 5.8 -51.8 4C-52 2.2 -56.2 -5 -55.4 -7.4C-55.4 -7.4 -54.4 -6.4 -53.6 -5C-53.6 -5 -54.2 -5.6 -53.6 -9.2C-53.6 -9.2 -52.8 -14.4 -51.4 -17.6C-50 -20.8 -48 -24.6 -47.6 -25.4C-47.2 -26.2 -47.2 -32 -45.8 -29.4L-42.4 -26.8C-42.4 -26.8 -45.2 -29.4 -43 -31.6C-43 -31.6 -44 -37.2 -42.2 -39.8C-42.2 -39.8 -35.2 -48.2 -33.6 -49.2C-32 -50.2 -33.4 -49.8 -33.4 -49.8C-33.4 -49.8 -27.4 -54 -33.2 -52.4C-33.2 -52.4 -37.2 -50.8 -40.2 -50.8C-40.2 -50.8 -47.8 -48.8 -43.8 -53C-39.8 -57.2 -29.8 -62.6 -26 -62.4L-25.2 -60.8L-14 -63.2L-15.2 -62.4C-15.2 -62.4 -15.4 -62.6 -11.2 -63C-7 -63.4 -1.2 -62 0.2 -63.8C1.6 -65.6 5 -66.6 4.6 -65.2C4.2 -63.8 4 -61.8 4 -61.8C4 -61.8 9 -67.6 8.4 -65.4C7.8 -63.2 -0.4 -58 -1.8 -51.8L8.6 -60L12.2 -63C12.2 -63 15.8 -60.8 16 -62.4C16.2 -64 20.8 -69.8 22 -69.6C23.2 -69.4 25.2 -72.2 25 -69.6C24.8 -67 32.4 -61.6 32.4 -61.6C32.4 -61.6 35.6 -63.4 37 -62C38.4 -60.6 42.6 -81.8 42.6 -81.8L67.6 -92.4L111.201 -95.8L94.201 -102.6L33.2 -114z").setFill(f).setStroke(s);
+ s = {color: "#4c0000", width: 2}; f = null;
+ g.createPath("M51.4 85C51.4 85 36.4 68.2 28 65.6C28 65.6 14.6 58.8 -10 66.6").setFill(f).setStroke(s);
+ s = {color: "#4c0000", width: 2};
+ g.createPath("M24.8 64.2C24.8 64.2 -0.4 56.2 -15.8 60.4C-15.8 60.4 -34.2 62.4 -42.6 76.2").setFill(f).setStroke(s);
+ s = {color: "#4c0000", width: 2};
+ g.createPath("M21.2 63C21.2 63 4.2 55.8 -10.6 53.6C-10.6 53.6 -27.2 51 -43.8 58.2C-43.8 58.2 -56 64.2 -61.4 74.4").setFill(f).setStroke(s);
+ s = {color: "#4c0000", width: 2};
+ g.createPath("M22.2 63.4C22.2 63.4 6.8 52.4 5.8 51C5.8 51 -1.2 40 -14.2 39.6C-14.2 39.6 -35.6 40.4 -52.8 48.4").setFill(f).setStroke(s);
+ f = "#000000"; s = null;
+ g.createPath("M20.895 54.407C22.437 55.87 49.4 84.8 49.4 84.8C84.6 121.401 56.6 87.2 56.6 87.2C49 82.4 39.8 63.6 39.8 63.6C38.6 60.8 53.8 70.8 53.8 70.8C57.8 71.6 71.4 90.8 71.4 90.8C64.6 88.4 69.4 95.6 69.4 95.6C72.2 97.6 92.601 113.201 92.601 113.201C96.201 117.201 100.201 118.801 100.201 118.801C114.201 113.601 107.801 126.801 107.801 126.801C110.201 133.601 115.801 122.001 115.801 122.001C127.001 105.2 110.601 107.601 110.601 107.601C80.6 110.401 73.8 94.4 73.8 94.4C71.4 92 80.2 94.4 80.2 94.4C88.601 96.4 73 82 73 82C75.4 82 84.6 88.8 84.6 88.8C95.001 98 97.001 96 97.001 96C115.001 87.2 125.401 94.8 125.401 94.8C127.401 96.4 121.801 103.2 123.401 108.401C125.001 113.601 129.801 126.001 129.801 126.001C127.401 127.601 127.801 138.401 127.801 138.401C144.601 161.601 135.001 159.601 135.001 159.601C119.401 159.201 134.201 166.801 134.201 166.801C137.401 168.801 146.201 176.001 146.201 176.001C143.401 174.801 141.801 180.001 141.801 180.001C146.601 184.001 143.801 188.801 143.801 188.801C137.801 190.001 136.601 194.001 136.601 194.001C143.401 202.001 133.401 202.401 133.401 202.401C137.001 206.801 132.201 218.801 132.201 218.801C127.401 218.801 121.001 224.401 121.001 224.401C123.401 229.201 113.001 234.801 113.001 234.801C104.601 236.401 107.401 243.201 107.401 243.201C99.401 249.201 97.001 265.201 97.001 265.201C96.201 275.601 93.801 278.801 99.001 276.801C104.201 274.801 103.401 262.401 103.401 262.401C98.601 246.801 141.401 230.801 141.401 230.801C145.401 229.201 146.201 224.001 146.201 224.001C148.201 224.401 157.001 232.001 157.001 232.001C164.601 243.201 165.001 234.001 165.001 234.001C166.201 230.401 164.601 224.401 164.601 224.401C170.601 202.801 156.601 196.401 156.601 196.401C146.601 162.801 160.601 171.201 160.601 171.201C163.401 176.801 174.201 182.001 174.201 182.001L177.801 179.601C176.201 174.801 184.601 168.801 184.601 168.801C187.401 175.201 193.401 167.201 193.401 167.201C197.001 142.801 209.401 157.201 209.401 157.201C213.401 158.401 214.601 151.601 214.601 151.601C218.201 141.201 214.601 127.601 214.601 127.601C218.201 127.201 227.801 133.201 227.801 133.201C230.601 129.601 221.401 112.801 225.401 115.201C229.401 117.601 233.801 119.201 233.801 119.201C234.601 117.201 224.601 104.801 224.601 104.801C220.201 102 215.001 81.6 215.001 81.6C222.201 85.2 212.201 70 212.201 70C212.201 66.8 218.201 55.6 218.201 55.6C217.401 48.8 218.201 49.2 218.201 49.2C221.001 50.4 229.001 52 222.201 45.6C215.401 39.2 223.001 34.4 223.001 34.4C227.401 31.6 213.801 32 213.801 32C208.601 27.6 209.001 23.6 209.001 23.6C217.001 25.6 202.601 11.2 200.201 7.6C197.801 4 207.401 -1.2 207.401 -1.2C220.601 -4.8 209.001 -8 209.001 -8C189.401 -7.6 200.201 -18.4 200.201 -18.4C206.201 -18 204.601 -20.4 204.601 -20.4C199.401 -21.6 189.801 -28 189.801 -28C185.801 -31.6 189.401 -30.8 189.401 -30.8C206.201 -29.6 177.401 -40.8 177.401 -40.8C185.401 -40.8 167.401 -51.2 167.401 -51.2C165.401 -52.8 162.201 -60.4 162.201 -60.4C156.201 -65.6 151.401 -72.4 151.401 -72.4C151.001 -76.8 146.201 -81.6 146.201 -81.6C134.601 -95.2 129.001 -94.8 129.001 -94.8C114.201 -98.4 109.001 -97.6 109.001 -97.6L56.2 -93.2C29.8 -80.4 37.6 -59.4 37.6 -59.4C44 -51 53.2 -54.8 53.2 -54.8C57.8 -61 69.4 -58.8 69.4 -58.8C89.801 -55.6 87.201 -59.2 87.201 -59.2C84.801 -63.8 68.6 -70 68.4 -70.6C68.2 -71.2 59.4 -74.6 59.4 -74.6C56.4 -75.8 52 -85 52 -85C48.8 -88.4 64.6 -82.6 64.6 -82.6C63.4 -81.6 70.8 -77.6 70.8 -77.6C88.201 -78.6 98.801 -67.8 98.801 -67.8C109.601 -51.2 109.801 -59.4 109.801 -59.4C112.601 -68.8 100.801 -90 100.801 -90C101.201 -92 109.401 -85.4 109.401 -85.4C110.801 -87.4 111.601 -81.6 111.601 -81.6C111.801 -79.2 115.601 -71.2 115.601 -71.2C118.401 -58.2 122.001 -65.6 122.001 -65.6L126.601 -56.2C128.001 -53.6 122.001 -46 122.001 -46C121.801 -43.2 122.601 -43.4 117.001 -35.8C111.401 -28.2 114.801 -23.8 114.801 -23.8C113.401 -17.2 122.201 -17.6 122.201 -17.6C124.801 -15.4 128.201 -15.4 128.201 -15.4C130.001 -13.4 132.401 -14 132.401 -14C134.001 -17.8 140.201 -15.8 140.201 -15.8C141.601 -18.2 149.801 -18.6 149.801 -18.6C150.801 -21.2 151.201 -22.8 154.601 -23.4C158.001 -24 133.401 -67 133.401 -67C139.801 -67.8 131.601 -80.2 131.601 -80.2C129.401 -86.8 140.801 -72.2 143.001 -70.8C145.201 -69.4 146.201 -67.2 144.601 -67.4C143.001 -67.6 141.201 -65.4 142.601 -65.2C144.001 -65 157.001 -50 160.401 -39.8C163.801 -29.6 169.801 -25.6 176.001 -19.6C182.201 -13.6 181.401 10.6 181.401 10.6C181.001 19.4 187.001 30 187.001 30C189.001 33.8 184.801 52 184.801 52C182.801 54.2 184.201 55 184.201 55C185.201 56.2 192.001 69.4 192.001 69.4C190.201 69.2 193.801 72.8 193.801 72.8C199.001 78.8 192.601 75.8 192.601 75.8C186.601 74.2 193.601 84 193.601 84C194.801 85.8 185.801 81.2 185.801 81.2C176.601 80.6 188.201 87.8 188.201 87.8C196.801 95 185.401 90.6 185.401 90.6C180.801 88.8 184.001 95.6 184.001 95.6C187.201 97.2 204.401 104.2 204.401 104.2C204.801 108.001 201.801 113.001 201.801 113.001C202.201 117.001 200.001 120.401 200.001 120.401C198.801 128.601 198.201 129.401 198.201 129.401C194.001 129.601 186.601 143.401 186.601 143.401C184.801 146.001 174.601 158.001 174.601 158.001C172.601 165.001 154.601 157.801 154.601 157.801C148.001 161.201 150.001 157.801 150.001 157.801C149.601 155.601 154.401 149.601 154.401 149.601C161.401 147.001 158.801 136.201 158.801 136.201C162.801 134.801 151.601 132.001 151.801 130.801C152.001 129.601 157.801 128.201 157.801 128.201C165.801 126.201 161.401 123.801 161.401 123.801C160.801 119.801 163.801 114.201 163.801 114.201C175.401 113.401 163.801 97.2 163.801 97.2C153.001 89.6 152.001 83.8 152.001 83.8C164.601 75.6 156.401 63.2 156.601 59.6C156.801 56 158.001 34.4 158.001 34.4C156.001 28.2 153.001 14.6 153.001 14.6C155.201 9.4 162.601 -3.2 162.601 -3.2C165.401 -7.4 174.201 -12.2 172.001 -15.2C169.801 -18.2 162.001 -16.4 162.001 -16.4C154.201 -17.8 154.801 -12.6 154.801 -12.6C153.201 -11.6 152.401 -6.6 152.401 -6.6C151.68 1.333 142.801 7.6 142.801 7.6C131.601 13.8 140.801 17.8 140.801 17.8C146.801 24.4 137.001 24.6 137.001 24.6C126.001 22.8 134.201 33 134.201 33C145.001 45.8 142.001 48.6 142.001 48.6C131.801 49.6 144.401 58.8 144.401 58.8C144.401 58.8 143.601 56.8 143.801 58.6C144.001 60.4 147.001 64.6 147.801 66.6C148.601 68.6 144.601 68.8 144.601 68.8C145.201 78.4 129.801 74.2 129.801 74.2C129.801 74.2 129.801 74.2 128.201 74.4C126.601 74.6 115.401 73.8 109.601 71.6C103.801 69.4 97.001 69.4 97.001 69.4C97.001 69.4 93.001 71.2 85.4 71C77.8 70.8 69.8 73.6 69.8 73.6C65.4 73.2 74 68.8 74.2 69C74.4 69.2 80 63.6 72 64.2C50.203 65.835 39.4 55.6 39.4 55.6C37.4 54.2 34.8 51.4 34.8 51.4C24.8 49.4 36.2 63.8 36.2 63.8C37.4 65.2 36 66.2 36 66.2C35.2 64.6 27.4 59.2 27.4 59.2C24.589 58.227 23.226 56.893 20.895 54.407z").setFill(f).setStroke(s);
+ f = "#4c0000";
+ g.createPath("M-3 42.8C-3 42.8 8.6 48.4 11.2 51.2C13.8 54 27.8 65.4 27.8 65.4C27.8 65.4 22.4 63.4 19.8 61.6C17.2 59.8 6.4 51.6 6.4 51.6C6.4 51.6 2.6 45.6 -3 42.8z").setFill(f).setStroke(s);
+ f = "#99cc32";
+ g.createPath("M-61.009 11.603C-60.672 11.455 -61.196 8.743 -61.4 8.2C-62.422 5.474 -71.4 4 -71.4 4C-71.627 5.365 -71.682 6.961 -71.576 8.599C-71.576 8.599 -66.708 14.118 -61.009 11.603z").setFill(f).setStroke(s);
+ f = "#659900";
+ g.createPath("M-61.009 11.403C-61.458 11.561 -61.024 8.669 -61.2 8.2C-62.222 5.474 -71.4 3.9 -71.4 3.9C-71.627 5.265 -71.682 6.861 -71.576 8.499C-71.576 8.499 -67.308 13.618 -61.009 11.403z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-65.4 11.546C-66.025 11.546 -66.531 10.406 -66.531 9C-66.531 7.595 -66.025 6.455 -65.4 6.455C-64.775 6.455 -64.268 7.595 -64.268 9C-64.268 10.406 -64.775 11.546 -65.4 11.546z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-65.4 9z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-111 109.601C-111 109.601 -116.6 119.601 -91.8 113.601C-91.8 113.601 -77.8 112.401 -75.4 110.001C-74.2 110.801 -65.834 113.734 -63 114.401C-56.2 116.001 -47.8 106 -47.8 106C-47.8 106 -43.2 95.5 -40.4 95.5C-37.6 95.5 -40.8 97.1 -40.8 97.1C-40.8 97.1 -47.4 107.201 -47 108.801C-47 108.801 -52.2 128.801 -68.2 129.601C-68.2 129.601 -84.35 130.551 -83 136.401C-83 136.401 -74.2 134.001 -71.8 136.401C-71.8 136.401 -61 136.001 -69 142.401L-75.8 154.001C-75.8 154.001 -75.66 157.919 -85.8 154.401C-95.6 151.001 -105.9 138.101 -105.9 138.101C-105.9 138.101 -121.85 123.551 -111 109.601z").setFill(f).setStroke(s);
+ f = "#e59999";
+ g.createPath("M-112.2 113.601C-112.2 113.601 -114.2 123.201 -77.4 112.801C-77.4 112.801 -73 112.801 -70.6 113.601C-68.2 114.401 -56.2 117.201 -54.2 116.001C-54.2 116.001 -61.4 129.601 -73 128.001C-73 128.001 -86.2 129.601 -85.8 134.401C-85.8 134.401 -81.8 141.601 -77 144.001C-77 144.001 -74.2 146.401 -74.6 149.601C-75 152.801 -77.8 154.401 -79.8 155.201C-81.8 156.001 -85 152.801 -86.6 152.801C-88.2 152.801 -96.6 146.401 -101 141.601C-105.4 136.801 -113.8 124.801 -113.4 122.001C-113 119.201 -112.2 113.601 -112.2 113.601z").setFill(f).setStroke(s);
+ f = "#b26565";
+ g.createPath("M-109 131.051C-106.4 135.001 -103.2 139.201 -101 141.601C-96.6 146.401 -88.2 152.801 -86.6 152.801C-85 152.801 -81.8 156.001 -79.8 155.201C-77.8 154.401 -75 152.801 -74.6 149.601C-74.2 146.401 -77 144.001 -77 144.001C-80.066 142.468 -82.806 138.976 -84.385 136.653C-84.385 136.653 -84.2 139.201 -89.4 138.401C-94.6 137.601 -99.8 134.801 -101.4 131.601C-103 128.401 -105.4 126.001 -103.8 129.601C-102.2 133.201 -99.8 136.801 -98.2 137.201C-96.6 137.601 -97 138.801 -99.4 138.401C-101.8 138.001 -104.6 137.601 -109 132.401z").setFill(f).setStroke(s);
+ f = "#992600";
+ g.createPath("M-111.6 110.001C-111.6 110.001 -109.8 96.4 -108.6 92.4C-108.6 92.4 -109.4 85.6 -107 81.4C-104.6 77.2 -102.6 71 -99.6 65.6C-96.6 60.2 -96.4 56.2 -92.4 54.6C-88.4 53 -82.4 44.4 -79.6 43.4C-76.8 42.4 -77 43.2 -77 43.2C-77 43.2 -70.2 28.4 -56.6 32.4C-56.6 32.4 -72.8 29.6 -57 20.2C-57 20.2 -61.8 21.3 -58.5 14.3C-56.299 9.632 -56.8 16.4 -67.8 28.2C-67.8 28.2 -72.8 36.8 -78 39.8C-83.2 42.8 -95.2 49.8 -96.4 53.6C-97.6 57.4 -100.8 63.2 -102.8 64.8C-104.8 66.4 -107.6 70.6 -108 74C-108 74 -109.2 78 -110.6 79.2C-112 80.4 -112.2 83.6 -112.2 85.6C-112.2 87.6 -114.2 90.4 -114 92.8C-114 92.8 -113.2 111.801 -113.6 113.801L-111.6 110.001z").setFill(f).setStroke(s);
+ f = "#ffffff";
+ g.createPath("M-120.2 114.601C-120.2 114.601 -122.2 113.201 -126.6 119.201C-126.6 119.201 -119.3 152.201 -119.3 153.601C-119.3 153.601 -118.2 151.501 -119.5 144.301C-120.8 137.101 -121.7 124.401 -121.7 124.401L-120.2 114.601z").setFill(f).setStroke(s);
+ f = "#992600";
+ g.createPath("M-98.6 54C-98.6 54 -116.2 57.2 -115.8 86.4L-116.6 111.201C-116.6 111.201 -117.8 85.6 -119 84C-120.2 82.4 -116.2 71.2 -119.4 77.2C-119.4 77.2 -133.4 91.2 -125.4 112.401C-125.4 112.401 -123.9 115.701 -126.9 111.101C-126.9 111.101 -131.5 98.5 -130.4 92.1C-130.4 92.1 -130.2 89.9 -128.3 87.1C-128.3 87.1 -119.7 75.4 -117 73.1C-117 73.1 -115.2 58.7 -99.8 53.5C-99.8 53.5 -94.1 51.2 -98.6 54z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M40.8 -12.2C41.46 -12.554 41.451 -13.524 42.031 -13.697C43.18 -14.041 43.344 -15.108 43.862 -15.892C44.735 -17.211 44.928 -18.744 45.51 -20.235C45.782 -20.935 45.809 -21.89 45.496 -22.55C44.322 -25.031 43.62 -27.48 42.178 -29.906C41.91 -30.356 41.648 -31.15 41.447 -31.748C40.984 -33.132 39.727 -34.123 38.867 -35.443C38.579 -35.884 39.104 -36.809 38.388 -36.893C37.491 -36.998 36.042 -37.578 35.809 -36.552C35.221 -33.965 36.232 -31.442 37.2 -29C36.418 -28.308 36.752 -27.387 36.904 -26.62C37.614 -23.014 36.416 -19.662 35.655 -16.188C35.632 -16.084 35.974 -15.886 35.946 -15.824C34.724 -13.138 33.272 -10.693 31.453 -8.312C30.695 -7.32 29.823 -6.404 29.326 -5.341C28.958 -4.554 28.55 -3.588 28.8 -2.6C25.365 0.18 23.115 4.025 20.504 7.871C20.042 8.551 20.333 9.76 20.884 10.029C21.697 10.427 22.653 9.403 23.123 8.557C23.512 7.859 23.865 7.209 24.356 6.566C24.489 6.391 24.31 5.972 24.445 5.851C27.078 3.504 28.747 0.568 31.2 -1.8C33.15 -2.129 34.687 -3.127 36.435 -4.14C36.743 -4.319 37.267 -4.07 37.557 -4.265C39.31 -5.442 39.308 -7.478 39.414 -9.388C39.464 -10.272 39.66 -11.589 40.8 -12.2z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M31.959 -16.666C32.083 -16.743 31.928 -17.166 32.037 -17.382C32.199 -17.706 32.602 -17.894 32.764 -18.218C32.873 -18.434 32.71 -18.814 32.846 -18.956C35.179 -21.403 35.436 -24.427 34.4 -27.4C35.424 -28.02 35.485 -29.282 35.06 -30.129C34.207 -31.829 34.014 -33.755 33.039 -35.298C32.237 -36.567 30.659 -37.811 29.288 -36.508C28.867 -36.108 28.546 -35.321 28.824 -34.609C28.888 -34.446 29.173 -34.3 29.146 -34.218C29.039 -33.894 28.493 -33.67 28.487 -33.398C28.457 -31.902 27.503 -30.391 28.133 -29.062C28.905 -27.433 29.724 -25.576 30.4 -23.8C29.166 -21.684 30.199 -19.235 28.446 -17.358C28.31 -17.212 28.319 -16.826 28.441 -16.624C28.733 -16.138 29.139 -15.732 29.625 -15.44C29.827 -15.319 30.175 -15.317 30.375 -15.441C30.953 -15.803 31.351 -16.29 31.959 -16.666z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M94.771 -26.977C96.16 -25.185 96.45 -22.39 94.401 -21C94.951 -17.691 98.302 -19.67 100.401 -20.2C100.292 -20.588 100.519 -20.932 100.802 -20.937C101.859 -20.952 102.539 -21.984 103.601 -21.8C104.035 -23.357 105.673 -24.059 106.317 -25.439C108.043 -29.134 107.452 -33.407 104.868 -36.653C104.666 -36.907 104.883 -37.424 104.759 -37.786C104.003 -39.997 101.935 -40.312 100.001 -41C98.824 -44.875 98.163 -48.906 96.401 -52.6C94.787 -52.85 94.089 -54.589 92.752 -55.309C91.419 -56.028 90.851 -54.449 90.892 -53.403C90.899 -53.198 91.351 -52.974 91.181 -52.609C91.105 -52.445 90.845 -52.334 90.845 -52.2C90.846 -52.065 91.067 -51.934 91.201 -51.8C90.283 -50.98 88.86 -50.503 88.565 -49.358C87.611 -45.648 90.184 -42.523 91.852 -39.322C92.443 -38.187 91.707 -36.916 90.947 -35.708C90.509 -35.013 90.617 -33.886 90.893 -33.03C91.645 -30.699 93.236 -28.96 94.771 -26.977z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M57.611 -8.591C56.124 -6.74 52.712 -4.171 55.629 -2.243C55.823 -2.114 56.193 -2.11 56.366 -2.244C58.387 -3.809 60.39 -4.712 62.826 -5.294C62.95 -5.323 63.224 -4.856 63.593 -5.017C65.206 -5.72 67.216 -5.662 68.4 -7C72.167 -6.776 75.732 -7.892 79.123 -9.2C80.284 -9.648 81.554 -10.207 82.755 -10.709C84.131 -11.285 85.335 -12.213 86.447 -13.354C86.58 -13.49 86.934 -13.4 87.201 -13.4C87.161 -14.263 88.123 -14.39 88.37 -15.012C88.462 -15.244 88.312 -15.64 88.445 -15.742C90.583 -17.372 91.503 -19.39 90.334 -21.767C90.049 -22.345 89.8 -22.963 89.234 -23.439C88.149 -24.35 87.047 -23.496 86 -23.8C85.841 -23.172 85.112 -23.344 84.726 -23.146C83.867 -22.707 82.534 -23.292 81.675 -22.854C80.313 -22.159 79.072 -21.99 77.65 -21.613C77.338 -21.531 76.56 -21.627 76.4 -21C76.266 -21.134 76.118 -21.368 76.012 -21.346C74.104 -20.95 72.844 -20.736 71.543 -19.044C71.44 -18.911 70.998 -19.09 70.839 -18.955C69.882 -18.147 69.477 -16.913 68.376 -16.241C68.175 -16.118 67.823 -16.286 67.629 -16.157C66.983 -15.726 66.616 -15.085 65.974 -14.638C65.645 -14.409 65.245 -14.734 65.277 -14.99C65.522 -16.937 66.175 -18.724 65.6 -20.6C67.677 -23.12 70.194 -25.069 72 -27.8C72.015 -29.966 72.707 -32.112 72.594 -34.189C72.584 -34.382 72.296 -35.115 72.17 -35.462C71.858 -36.316 72.764 -37.382 71.92 -38.106C70.516 -39.309 69.224 -38.433 68.4 -37C66.562 -36.61 64.496 -35.917 62.918 -37.151C61.911 -37.938 61.333 -38.844 60.534 -39.9C59.549 -41.202 59.884 -42.638 59.954 -44.202C59.96 -44.33 59.645 -44.466 59.645 -44.6C59.646 -44.735 59.866 -44.866 60 -45C59.294 -45.626 59.019 -46.684 58 -47C58.305 -48.092 57.629 -48.976 56.758 -49.278C54.763 -49.969 53.086 -48.057 51.194 -47.984C50.68 -47.965 50.213 -49.003 49.564 -49.328C49.132 -49.544 48.428 -49.577 48.066 -49.311C47.378 -48.807 46.789 -48.693 46.031 -48.488C44.414 -48.052 43.136 -46.958 41.656 -46.103C40.171 -45.246 39.216 -43.809 38.136 -42.489C37.195 -41.337 37.059 -38.923 38.479 -38.423C40.322 -37.773 41.626 -40.476 43.592 -40.15C43.904 -40.099 44.11 -39.788 44 -39.4C44.389 -39.291 44.607 -39.52 44.8 -39.8C45.658 -38.781 46.822 -38.444 47.76 -37.571C48.73 -36.667 50.476 -37.085 51.491 -36.088C53.02 -34.586 52.461 -31.905 54.4 -30.6C53.814 -29.287 53.207 -28.01 52.872 -26.583C52.59 -25.377 53.584 -24.18 54.795 -24.271C56.053 -24.365 56.315 -25.124 56.8 -26.2C57.067 -25.933 57.536 -25.636 57.495 -25.42C57.038 -23.033 56.011 -21.04 55.553 -18.609C55.494 -18.292 55.189 -18.09 54.8 -18.2C54.332 -14.051 50.28 -11.657 47.735 -8.492C47.332 -7.99 47.328 -6.741 47.737 -6.338C49.14 -4.951 51.1 -6.497 52.8 -7C53.013 -8.206 53.872 -9.148 55.204 -9.092C55.46 -9.082 55.695 -9.624 56.019 -9.754C56.367 -9.892 56.869 -9.668 57.155 -9.866C58.884 -11.061 60.292 -12.167 62.03 -13.356C62.222 -13.487 62.566 -13.328 62.782 -13.436C63.107 -13.598 63.294 -13.985 63.617 -14.17C63.965 -14.37 64.207 -14.08 64.4 -13.8C63.754 -13.451 63.75 -12.494 63.168 -12.292C62.393 -12.024 61.832 -11.511 61.158 -11.064C60.866 -10.871 60.207 -11.119 60.103 -10.94C59.505 -9.912 58.321 -9.474 57.611 -8.591z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M2.2 -58C2.2 -58 -7.038 -60.872 -18.2 -35.2C-18.2 -35.2 -20.6 -30 -23 -28C-25.4 -26 -36.6 -22.4 -38.6 -18.4L-49 -2.4C-49 -2.4 -34.2 -18.4 -31 -20.8C-31 -20.8 -23 -29.2 -26.2 -22.4C-26.2 -22.4 -40.2 -11.6 -39 -2.4C-39 -2.4 -44.6 12 -45.4 14C-45.4 14 -29.4 -18 -27 -19.2C-24.6 -20.4 -23.4 -20.4 -24.6 -16.8C-25.8 -13.2 -26.2 3.2 -29 5.2C-29 5.2 -21 -15.2 -21.8 -18.4C-21.8 -18.4 -18.6 -22 -16.2 -16.8L-17.4 -0.8L-13 11.2C-13 11.2 -15.4 0 -13.8 -15.6C-13.8 -15.6 -15.8 -26 -11.8 -20.4C-7.8 -14.8 1.8 -8.8 1.8 -4C1.8 -4 -3.4 -21.6 -12.6 -26.4L-16.6 -20.4L-17.8 -22.4C-17.8 -22.4 -21.4 -23.2 -17 -30C-12.6 -36.8 -13 -37.6 -13 -37.6C-13 -37.6 -6.6 -30.4 -5 -30.4C-5 -30.4 8.2 -38 9.4 -13.6C9.4 -13.6 16.2 -28 7 -34.8C7 -34.8 -7.8 -36.8 -6.6 -42L0.6 -54.4C4.2 -59.6 2.6 -56.8 2.6 -56.8z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-17.8 -41.6C-17.8 -41.6 -30.6 -41.6 -33.8 -36.4L-41 -26.8C-41 -26.8 -23.8 -36.8 -19.8 -38C-15.8 -39.2 -17.8 -41.6 -17.8 -41.6z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-57.8 -35.2C-57.8 -35.2 -59.8 -34 -60.2 -31.2C-60.6 -28.4 -63 -28 -62.2 -25.2C-61.4 -22.4 -59.4 -20 -59.4 -24C-59.4 -28 -57.8 -30 -57 -31.2C-56.2 -32.4 -54.6 -36.8 -57.8 -35.2z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-66.6 26C-66.6 26 -75 22 -78.2 18.4C-81.4 14.8 -80.948 19.966 -85.8 19.6C-91.647 19.159 -90.6 3.2 -90.6 3.2L-94.6 10.8C-94.6 10.8 -95.8 25.2 -87.8 22.8C-83.893 21.628 -82.6 23.2 -84.2 24C-85.8 24.8 -78.6 25.2 -81.4 26.8C-84.2 28.4 -69.8 23.2 -72.2 33.6L-66.6 26z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-79.2 40.4C-79.2 40.4 -94.6 44.8 -98.2 35.2C-98.2 35.2 -103 37.6 -100.8 40.6C-98.6 43.6 -97.4 44 -97.4 44C-97.4 44 -92 45.2 -92.6 46C-93.2 46.8 -95.6 50.2 -95.6 50.2C-95.6 50.2 -85.4 44.2 -79.2 40.4z").setFill(f).setStroke(s);
+ f = "#ffffff";
+ g.createPath("M149.201 118.601C148.774 120.735 147.103 121.536 145.201 122.201C143.284 121.243 140.686 118.137 138.801 120.201C138.327 119.721 137.548 119.661 137.204 118.999C136.739 118.101 137.011 117.055 136.669 116.257C136.124 114.985 135.415 113.619 135.601 112.201C137.407 111.489 138.002 109.583 137.528 107.82C137.459 107.563 137.03 107.366 137.23 107.017C137.416 106.694 137.734 106.467 138.001 106.2C137.866 106.335 137.721 106.568 137.61 106.548C137 106.442 137.124 105.805 137.254 105.418C137.839 103.672 139.853 103.408 141.201 104.6C141.457 104.035 141.966 104.229 142.401 104.2C142.351 103.621 142.759 103.094 142.957 102.674C143.475 101.576 145.104 102.682 145.901 102.07C146.977 101.245 148.04 100.546 149.118 101.149C150.927 102.162 152.636 103.374 153.835 105.115C154.41 105.949 154.65 107.23 154.592 108.188C154.554 108.835 153.173 108.483 152.83 109.412C152.185 111.16 154.016 111.679 154.772 113.017C154.97 113.366 154.706 113.67 154.391 113.768C153.98 113.896 153.196 113.707 153.334 114.16C154.306 117.353 151.55 118.031 149.201 118.601z").setFill(f).setStroke(s);
+ f = "#ffffff";
+ g.createPath("M139.6 138.201C139.593 136.463 137.992 134.707 139.201 133.001C139.336 133.135 139.467 133.356 139.601 133.356C139.736 133.356 139.867 133.135 140.001 133.001C141.496 135.217 145.148 136.145 145.006 138.991C144.984 139.438 143.897 140.356 144.801 141.001C142.988 142.349 142.933 144.719 142.001 146.601C140.763 146.315 139.551 145.952 138.401 145.401C138.753 143.915 138.636 142.231 139.456 140.911C139.89 140.213 139.603 139.134 139.6 138.201z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-26.6 129.201C-26.6 129.201 -43.458 139.337 -29.4 124.001C-20.6 114.401 -10.6 108.801 -10.6 108.801C-10.6 108.801 -0.2 104.4 3.4 103.2C7 102 22.2 96.8 25.4 96.4C28.6 96 38.2 92 45 96C51.8 100 59.8 104.4 59.8 104.4C59.8 104.4 43.4 96 39.8 98.4C36.2 100.8 29 100.4 23 103.6C23 103.6 8.2 108.001 5 110.001C1.8 112.001 -8.6 123.601 -10.2 122.801C-11.8 122.001 -9.8 121.601 -8.6 118.801C-7.4 116.001 -9.4 114.401 -17.4 120.801C-25.4 127.201 -26.6 129.201 -26.6 129.201z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-19.195 123.234C-19.195 123.234 -17.785 110.194 -9.307 111.859C-9.307 111.859 -1.081 107.689 1.641 105.721C1.641 105.721 9.78 104.019 11.09 103.402C29.569 94.702 44.288 99.221 44.835 98.101C45.381 96.982 65.006 104.099 68.615 108.185C69.006 108.628 58.384 102.588 48.686 100.697C40.413 99.083 18.811 100.944 7.905 106.48C4.932 107.989 -4.013 113.773 -6.544 113.662C-9.075 113.55 -19.195 123.234 -19.195 123.234z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-23 148.801C-23 148.801 -38.2 146.401 -21.4 144.801C-21.4 144.801 -3.4 142.801 0.6 137.601C0.6 137.601 14.2 128.401 17 128.001C19.8 127.601 49.8 120.401 50.2 118.001C50.6 115.601 56.2 115.601 57.8 116.401C59.4 117.201 58.6 118.401 55.8 119.201C53 120.001 21.8 136.401 15.4 137.601C9 138.801 -2.6 146.401 -7.4 147.601C-12.2 148.801 -23 148.801 -23 148.801z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-3.48 141.403C-3.48 141.403 -12.062 140.574 -3.461 139.755C-3.461 139.755 5.355 136.331 7.403 133.668C7.403 133.668 14.367 128.957 15.8 128.753C17.234 128.548 31.194 124.861 31.399 123.633C31.604 122.404 65.67 109.823 70.09 113.013C73.001 115.114 63.1 113.437 53.466 117.847C52.111 118.467 18.258 133.054 14.981 133.668C11.704 134.283 5.765 138.174 3.307 138.788C0.85 139.403 -3.48 141.403 -3.48 141.403z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-11.4 143.601C-11.4 143.601 -6.2 143.201 -7.4 144.801C-8.6 146.401 -11 145.601 -11 145.601L-11.4 143.601z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-18.6 145.201C-18.6 145.201 -13.4 144.801 -14.6 146.401C-15.8 148.001 -18.2 147.201 -18.2 147.201L-18.6 145.201z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-29 146.801C-29 146.801 -23.8 146.401 -25 148.001C-26.2 149.601 -28.6 148.801 -28.6 148.801L-29 146.801z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-36.6 147.601C-36.6 147.601 -31.4 147.201 -32.6 148.801C-33.8 150.401 -36.2 149.601 -36.2 149.601L-36.6 147.601z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M1.8 108.001C1.8 108.001 6.2 108.001 5 109.601C3.8 111.201 0.6 110.801 0.6 110.801L1.8 108.001z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-8.2 113.601C-8.2 113.601 -1.694 111.46 -4.2 114.801C-5.4 116.401 -7.8 115.601 -7.8 115.601L-8.2 113.601z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-19.4 118.401C-19.4 118.401 -14.2 118.001 -15.4 119.601C-16.6 121.201 -19 120.401 -19 120.401L-19.4 118.401z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-27 124.401C-27 124.401 -21.8 124.001 -23 125.601C-24.2 127.201 -26.6 126.401 -26.6 126.401L-27 124.401z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-33.8 129.201C-33.8 129.201 -28.6 128.801 -29.8 130.401C-31 132.001 -33.4 131.201 -33.4 131.201L-33.8 129.201z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M5.282 135.598C5.282 135.598 12.203 135.066 10.606 137.195C9.009 139.325 5.814 138.26 5.814 138.26L5.282 135.598z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M15.682 130.798C15.682 130.798 22.603 130.266 21.006 132.395C19.409 134.525 16.214 133.46 16.214 133.46L15.682 130.798z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M26.482 126.398C26.482 126.398 33.403 125.866 31.806 127.995C30.209 130.125 27.014 129.06 27.014 129.06L26.482 126.398z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M36.882 121.598C36.882 121.598 43.803 121.066 42.206 123.195C40.609 125.325 37.414 124.26 37.414 124.26L36.882 121.598z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M9.282 103.598C9.282 103.598 16.203 103.066 14.606 105.195C13.009 107.325 9.014 107.06 9.014 107.06L9.282 103.598z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M19.282 100.398C19.282 100.398 26.203 99.866 24.606 101.995C23.009 104.125 18.614 103.86 18.614 103.86L19.282 100.398z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-3.4 140.401C-3.4 140.401 1.8 140.001 0.6 141.601C-0.6 143.201 -3 142.401 -3 142.401L-3.4 140.401z").setFill(f).setStroke(s);
+ f = "#992600";
+ g.createPath("M-76.6 41.2C-76.6 41.2 -81 50 -81.4 53.2C-81.4 53.2 -80.6 44.4 -79.4 42.4C-78.2 40.4 -76.6 41.2 -76.6 41.2z").setFill(f).setStroke(s);
+ f = "#992600";
+ g.createPath("M-95 55.2C-95 55.2 -98.2 69.6 -97.8 72.4C-97.8 72.4 -99 60.8 -98.6 59.6C-98.2 58.4 -95 55.2 -95 55.2z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-74.2 -19.4L-74.4 -16.2L-76.6 -16C-76.6 -16 -62.4 -3.4 -61.8 4.2C-61.8 4.2 -61 -4 -74.2 -19.4z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-70.216 -18.135C-70.647 -18.551 -70.428 -19.296 -70.836 -19.556C-71.645 -20.072 -69.538 -20.129 -69.766 -20.845C-70.149 -22.051 -69.962 -22.072 -70.084 -23.348C-70.141 -23.946 -69.553 -25.486 -69.168 -25.926C-67.722 -27.578 -69.046 -30.51 -67.406 -32.061C-67.102 -32.35 -66.726 -32.902 -66.441 -33.32C-65.782 -34.283 -64.598 -34.771 -63.648 -35.599C-63.33 -35.875 -63.531 -36.702 -62.962 -36.61C-62.248 -36.495 -61.007 -36.625 -61.052 -35.784C-61.165 -33.664 -62.494 -31.944 -63.774 -30.276C-63.323 -29.572 -63.781 -28.937 -64.065 -28.38C-65.4 -25.76 -65.211 -22.919 -65.385 -20.079C-65.39 -19.994 -65.697 -19.916 -65.689 -19.863C-65.336 -17.528 -64.752 -15.329 -63.873 -13.1C-63.507 -12.17 -63.036 -11.275 -62.886 -10.348C-62.775 -9.662 -62.672 -8.829 -63.08 -8.124C-61.045 -5.234 -62.354 -2.583 -61.185 0.948C-60.978 1.573 -59.286 3.487 -59.749 3.326C-62.262 2.455 -62.374 2.057 -62.551 1.304C-62.697 0.681 -63.027 -0.696 -63.264 -1.298C-63.328 -1.462 -63.499 -3.346 -63.577 -3.468C-65.09 -5.85 -63.732 -5.674 -65.102 -8.032C-66.53 -8.712 -67.496 -9.816 -68.619 -10.978C-68.817 -11.182 -67.674 -11.906 -67.855 -12.119C-68.947 -13.408 -70.1 -14.175 -69.764 -15.668C-69.609 -16.358 -69.472 -17.415 -70.216 -18.135z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-73.8 -16.4C-73.8 -16.4 -73.4 -9.6 -71 -8C-68.6 -6.4 -69.8 -7.2 -73 -8.4C-76.2 -9.6 -75 -10.4 -75 -10.4C-75 -10.4 -77.8 -10 -75.4 -8C-73 -6 -69.4 -3.6 -71 -3.6C-72.6 -3.6 -80.2 -7.6 -80.2 -10.4C-80.2 -13.2 -81.2 -17.3 -81.2 -17.3C-81.2 -17.3 -80.1 -18.1 -75.3 -18C-75.3 -18 -73.9 -17.3 -73.8 -16.4z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-74.6 2.2C-74.6 2.2 -83.12 -0.591 -101.6 2.8C-101.6 2.8 -92.569 0.722 -73.8 3C-63.5 4.25 -74.6 2.2 -74.6 2.2z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-72.502 2.129C-72.502 2.129 -80.748 -1.389 -99.453 0.392C-99.453 0.392 -90.275 -0.897 -71.774 2.995C-61.62 5.131 -72.502 2.129 -72.502 2.129z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-70.714 2.222C-70.714 2.222 -78.676 -1.899 -97.461 -1.514C-97.461 -1.514 -88.213 -2.118 -70.052 3.14C-60.086 6.025 -70.714 2.222 -70.714 2.222z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-69.444 2.445C-69.444 2.445 -76.268 -1.862 -93.142 -2.96C-93.142 -2.96 -84.803 -2.79 -68.922 3.319C-60.206 6.672 -69.444 2.445 -69.444 2.445z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M45.84 12.961C45.84 12.961 44.91 13.605 45.124 12.424C45.339 11.243 73.547 -1.927 77.161 -1.677C77.161 -1.677 46.913 11.529 45.84 12.961z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M42.446 13.6C42.446 13.6 41.57 14.315 41.691 13.121C41.812 11.927 68.899 -3.418 72.521 -3.452C72.521 -3.452 43.404 12.089 42.446 13.6z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M39.16 14.975C39.16 14.975 38.332 15.747 38.374 14.547C38.416 13.348 58.233 -2.149 68.045 -4.023C68.045 -4.023 50.015 4.104 39.16 14.975z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M36.284 16.838C36.284 16.838 35.539 17.532 35.577 16.453C35.615 15.373 53.449 1.426 62.28 -0.26C62.28 -0.26 46.054 7.054 36.284 16.838z").setFill(f).setStroke(s);
+ f = "#cccccc"; s = null;
+ g.createPath("M4.6 164.801C4.6 164.801 -10.6 162.401 6.2 160.801C6.2 160.801 24.2 158.801 28.2 153.601C28.2 153.601 41.8 144.401 44.6 144.001C47.4 143.601 63.8 140.001 64.2 137.601C64.6 135.201 70.6 132.801 72.2 133.601C73.8 134.401 73.8 143.601 71 144.401C68.2 145.201 49.4 152.401 43 153.601C36.6 154.801 25 162.401 20.2 163.601C15.4 164.801 4.6 164.801 4.6 164.801z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M77.6 127.401C77.6 127.401 74.6 129.001 73.4 131.601C73.4 131.601 67 142.201 52.8 145.401C52.8 145.401 29.8 154.401 22 156.401C22 156.401 8.6 161.401 1.2 160.601C1.2 160.601 -5.8 160.801 0.4 162.401C0.4 162.401 20.6 160.401 24 158.601C24 158.601 39.6 153.401 42.6 150.801C45.6 148.201 63.8 143.201 66 141.201C68.2 139.201 78 130.801 77.6 127.401z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M18.882 158.911C18.882 158.911 24.111 158.685 22.958 160.234C21.805 161.784 19.357 160.91 19.357 160.91L18.882 158.911z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M11.68 160.263C11.68 160.263 16.908 160.037 15.756 161.586C14.603 163.136 12.155 162.263 12.155 162.263L11.68 160.263z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M1.251 161.511C1.251 161.511 6.48 161.284 5.327 162.834C4.174 164.383 1.726 163.51 1.726 163.51L1.251 161.511z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-6.383 162.055C-6.383 162.055 -1.154 161.829 -2.307 163.378C-3.46 164.928 -5.908 164.054 -5.908 164.054L-6.383 162.055z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M35.415 151.513C35.415 151.513 42.375 151.212 40.84 153.274C39.306 155.336 36.047 154.174 36.047 154.174L35.415 151.513z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M45.73 147.088C45.73 147.088 51.689 143.787 51.155 148.849C50.885 151.405 46.362 149.749 46.362 149.749L45.73 147.088z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M54.862 144.274C54.862 144.274 62.021 140.573 60.287 146.035C59.509 148.485 55.493 146.935 55.493 146.935L54.862 144.274z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M64.376 139.449C64.376 139.449 68.735 134.548 69.801 141.21C70.207 143.748 65.008 142.11 65.008 142.11L64.376 139.449z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M26.834 155.997C26.834 155.997 32.062 155.77 30.91 157.32C29.757 158.869 27.308 157.996 27.308 157.996L26.834 155.997z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M62.434 34.603C62.434 34.603 61.708 35.268 61.707 34.197C61.707 33.127 79.191 19.863 88.034 18.479C88.034 18.479 71.935 25.208 62.434 34.603z").setFill(f).setStroke(s);
+ f = "#000000"; s = null;
+ g.createPath("M65.4 98.4C65.4 98.4 87.401 120.801 96.601 124.401C96.601 124.401 105.801 135.601 101.801 161.601C101.801 161.601 98.601 169.201 95.401 148.401C95.401 148.401 98.601 123.201 87.401 139.201C87.401 139.201 79 129.301 85.4 129.601C85.4 129.601 88.601 131.601 89.001 130.001C89.401 128.401 81.4 114.801 64.2 100.4C47 86 65.4 98.4 65.4 98.4z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M7 137.201C7 137.201 6.8 135.401 8.6 136.201C10.4 137.001 104.601 143.201 136.201 167.201C136.201 167.201 91.001 144.001 7 137.201z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M17.4 132.801C17.4 132.801 17.2 131.001 19 131.801C20.8 132.601 157.401 131.601 181.001 164.001C181.001 164.001 159.001 138.801 17.4 132.801z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M29 128.801C29 128.801 28.8 127.001 30.6 127.801C32.4 128.601 205.801 115.601 229.401 148.001C229.401 148.001 219.801 122.401 29 128.801z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M39 124.001C39 124.001 38.8 122.201 40.6 123.001C42.4 123.801 164.601 85.2 188.201 117.601C188.201 117.601 174.801 93 39 124.001z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-19 146.801C-19 146.801 -19.2 145.001 -17.4 145.801C-15.6 146.601 2.2 148.801 4.2 187.601C4.2 187.601 -3 145.601 -19 146.801z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-27.8 148.401C-27.8 148.401 -28 146.601 -26.2 147.401C-24.4 148.201 -10.2 143.601 -13 182.401C-13 182.401 -11.8 147.201 -27.8 148.401z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-35.8 148.801C-35.8 148.801 -36 147.001 -34.2 147.801C-32.4 148.601 -17 149.201 -29.4 171.601C-29.4 171.601 -19.8 147.601 -35.8 148.801z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M11.526 104.465C11.526 104.465 11.082 106.464 12.631 105.247C28.699 92.622 61.141 33.72 116.826 28.086C116.826 28.086 78.518 15.976 11.526 104.465z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M22.726 102.665C22.726 102.665 21.363 101.472 23.231 100.847C25.099 100.222 137.541 27.72 176.826 35.686C176.826 35.686 149.719 28.176 22.726 102.665z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M1.885 108.767C1.885 108.767 1.376 110.366 3.087 109.39C12.062 104.27 15.677 47.059 59.254 45.804C59.254 45.804 26.843 31.09 1.885 108.767z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-18.038 119.793C-18.038 119.793 -19.115 121.079 -17.162 120.825C-6.916 119.493 14.489 78.222 58.928 83.301C58.928 83.301 26.962 68.955 -18.038 119.793z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-6.8 113.667C-6.8 113.667 -7.611 115.136 -5.742 114.511C4.057 111.237 17.141 66.625 61.729 63.078C61.729 63.078 27.603 55.135 -6.8 113.667z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-25.078 124.912C-25.078 124.912 -25.951 125.954 -24.369 125.748C-16.07 124.669 1.268 91.24 37.264 95.354C37.264 95.354 11.371 83.734 -25.078 124.912z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-32.677 130.821C-32.677 130.821 -33.682 131.866 -32.091 131.748C-27.923 131.439 2.715 98.36 21.183 113.862C21.183 113.862 9.168 95.139 -32.677 130.821z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M36.855 98.898C36.855 98.898 35.654 97.543 37.586 97.158C39.518 96.774 160.221 39.061 198.184 51.927C198.184 51.927 172.243 41.053 36.855 98.898z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M3.4 163.201C3.4 163.201 3.2 161.401 5 162.201C6.8 163.001 22.2 163.601 9.8 186.001C9.8 186.001 19.4 162.001 3.4 163.201z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M13.8 161.601C13.8 161.601 13.6 159.801 15.4 160.601C17.2 161.401 35 163.601 37 202.401C37 202.401 29.8 160.401 13.8 161.601z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M20.6 160.001C20.6 160.001 20.4 158.201 22.2 159.001C24 159.801 48.6 163.201 72.2 195.601C72.2 195.601 36.6 158.801 20.6 160.001z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M28.225 157.972C28.225 157.972 27.788 156.214 29.678 156.768C31.568 157.322 52.002 155.423 90.099 189.599C90.099 189.599 43.924 154.656 28.225 157.972z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M38.625 153.572C38.625 153.572 38.188 151.814 40.078 152.368C41.968 152.922 76.802 157.423 128.499 192.399C128.499 192.399 54.324 150.256 38.625 153.572z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-1.8 142.001C-1.8 142.001 -2 140.201 -0.2 141.001C1.6 141.801 55 144.401 85.4 171.201C85.4 171.201 50.499 146.426 -1.8 142.001z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M-11.8 146.001C-11.8 146.001 -12 144.201 -10.2 145.001C-8.4 145.801 16.2 149.201 39.8 181.601C39.8 181.601 4.2 144.801 -11.8 146.001z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M49.503 148.962C49.503 148.962 48.938 147.241 50.864 147.655C52.79 148.068 87.86 150.004 141.981 181.098C141.981 181.098 64.317 146.704 49.503 148.962z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M57.903 146.562C57.903 146.562 57.338 144.841 59.264 145.255C61.19 145.668 96.26 147.604 150.381 178.698C150.381 178.698 73.317 143.904 57.903 146.562z").setFill(f).setStroke(s);
+ f = "#ffffff"; s = {color: "#000000", width: 0.1};
+ g.createPath("M67.503 141.562C67.503 141.562 66.938 139.841 68.864 140.255C70.79 140.668 113.86 145.004 203.582 179.298C203.582 179.298 82.917 138.904 67.503 141.562z").setFill(f).setStroke(s);
+ f = "#000000"; s = null;
+ g.createPath("M-43.8 148.401C-43.8 148.401 -38.6 148.001 -39.8 149.601C-41 151.201 -43.4 150.401 -43.4 150.401L-43.8 148.401z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-13 162.401C-13 162.401 -7.8 162.001 -9 163.601C-10.2 165.201 -12.6 164.401 -12.6 164.401L-13 162.401z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-21.8 162.001C-21.8 162.001 -16.6 161.601 -17.8 163.201C-19 164.801 -21.4 164.001 -21.4 164.001L-21.8 162.001z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-117.169 150.182C-117.169 150.182 -112.124 151.505 -113.782 152.624C-115.439 153.744 -117.446 152.202 -117.446 152.202L-117.169 150.182z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-115.169 140.582C-115.169 140.582 -110.124 141.905 -111.782 143.024C-113.439 144.144 -115.446 142.602 -115.446 142.602L-115.169 140.582z").setFill(f).setStroke(s);
+ f = "#000000";
+ g.createPath("M-122.369 136.182C-122.369 136.182 -117.324 137.505 -118.982 138.624C-120.639 139.744 -122.646 138.202 -122.646 138.202L-122.369 136.182z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-42.6 211.201C-42.6 211.201 -44.2 211.201 -48.2 213.201C-50.2 213.201 -61.4 216.801 -67 226.801C-67 226.801 -54.6 217.201 -42.6 211.201z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M45.116 303.847C45.257 304.105 45.312 304.525 45.604 304.542C46.262 304.582 47.495 304.883 47.37 304.247C46.522 299.941 45.648 295.004 41.515 293.197C40.876 292.918 39.434 293.331 39.36 294.215C39.233 295.739 39.116 297.088 39.425 298.554C39.725 299.975 41.883 299.985 42.8 298.601C43.736 300.273 44.168 302.116 45.116 303.847z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M34.038 308.581C34.786 309.994 34.659 311.853 36.074 312.416C36.814 312.71 38.664 311.735 38.246 310.661C37.444 308.6 37.056 306.361 35.667 304.55C35.467 304.288 35.707 303.755 35.547 303.427C34.953 302.207 33.808 301.472 32.4 301.801C31.285 304.004 32.433 306.133 33.955 307.842C34.091 307.994 33.925 308.37 34.038 308.581z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-5.564 303.391C-5.672 303.014 -5.71 302.551 -5.545 302.23C-5.014 301.197 -4.221 300.075 -4.558 299.053C-4.906 297.997 -6.022 298.179 -6.672 298.748C-7.807 299.742 -7.856 301.568 -8.547 302.927C-8.743 303.313 -8.692 303.886 -9.133 304.277C-9.607 304.698 -10.047 306.222 -9.951 306.793C-9.898 307.106 -10.081 317.014 -9.859 316.751C-9.24 316.018 -6.19 306.284 -6.121 305.392C-6.064 304.661 -5.332 304.196 -5.564 303.391z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-31.202 296.599C-28.568 294.1 -25.778 291.139 -26.22 287.427C-26.336 286.451 -28.111 286.978 -28.298 287.824C-29.1 291.449 -31.139 294.11 -33.707 296.502C-35.903 298.549 -37.765 304.893 -38 305.401C-34.303 300.145 -32.046 297.399 -31.202 296.599z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-44.776 290.635C-44.253 290.265 -44.555 289.774 -44.338 289.442C-43.385 287.984 -42.084 286.738 -42.066 285C-42.063 284.723 -42.441 284.414 -42.776 284.638C-43.053 284.822 -43.395 284.952 -43.503 285.082C-45.533 287.531 -46.933 290.202 -48.376 293.014C-48.559 293.371 -49.703 297.862 -49.39 297.973C-49.151 298.058 -47.431 293.877 -47.221 293.763C-45.958 293.077 -45.946 291.462 -44.776 290.635z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-28.043 310.179C-27.599 309.31 -26.023 308.108 -26.136 307.219C-26.254 306.291 -25.786 304.848 -26.698 305.536C-27.955 306.484 -31.404 307.833 -31.674 313.641C-31.7 314.212 -28.726 311.519 -28.043 310.179z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-13.6 293.001C-13.2 292.333 -12.492 292.806 -12.033 292.543C-11.385 292.171 -10.774 291.613 -10.482 290.964C-9.512 288.815 -7.743 286.995 -7.6 284.601C-9.091 283.196 -9.77 285.236 -10.4 286.201C-11.723 284.554 -12.722 286.428 -14.022 286.947C-14.092 286.975 -14.305 286.628 -14.38 286.655C-15.557 287.095 -16.237 288.176 -17.235 288.957C-17.406 289.091 -17.811 288.911 -17.958 289.047C-18.61 289.65 -19.583 289.975 -19.863 290.657C-20.973 293.364 -24.113 295.459 -26 303.001C-25.619 303.91 -21.488 296.359 -21.001 295.661C-20.165 294.465 -20.047 297.322 -18.771 296.656C-18.72 296.629 -18.534 296.867 -18.4 297.001C-18.206 296.721 -17.988 296.492 -17.6 296.601C-17.6 296.201 -17.734 295.645 -17.533 295.486C-16.296 294.509 -16.38 293.441 -15.6 292.201C-15.142 292.99 -14.081 292.271 -13.6 293.001z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M46.2 347.401C46.2 347.401 53.6 327.001 49.2 315.801C49.2 315.801 60.6 337.401 56 348.601C56 348.601 55.6 338.201 51.6 333.201C51.6 333.201 47.6 346.001 46.2 347.401z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M31.4 344.801C31.4 344.801 36.8 336.001 28.8 317.601C28.8 317.601 28 338.001 21.2 349.001C21.2 349.001 35.4 328.801 31.4 344.801z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M21.4 342.801C21.4 342.801 21.2 322.801 21.6 319.801C21.6 319.801 17.8 336.401 7.6 346.001C7.6 346.001 22 334.001 21.4 342.801z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M11.8 310.801C11.8 310.801 17.8 324.401 7.8 342.801C7.8 342.801 14.2 330.601 9.4 323.601C9.4 323.601 12 320.201 11.8 310.801z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-7.4 342.401C-7.4 342.401 -8.4 326.801 -6.6 324.601C-6.6 324.601 -6.4 318.201 -6.8 317.201C-6.8 317.201 -2.8 311.001 -2.6 318.401C-2.6 318.401 -1.2 326.201 1.6 330.801C1.6 330.801 5.2 336.201 5 342.601C5 342.601 -5 312.401 -7.4 342.401z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-11 314.801C-11 314.801 -17.6 325.601 -19.4 344.601C-19.4 344.601 -20.8 338.401 -17 324.001C-17 324.001 -12.8 308.601 -11 314.801z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-32.8 334.601C-32.8 334.601 -27.8 329.201 -26.4 324.201C-26.4 324.201 -22.8 308.401 -29.2 317.001C-29.2 317.001 -29 325.001 -37.2 332.401C-37.2 332.401 -32.4 330.001 -32.8 334.601z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-38.6 329.601C-38.6 329.601 -35.2 312.201 -34.4 311.401C-34.4 311.401 -32.6 308.001 -35.4 311.201C-35.4 311.201 -44.2 330.401 -48.2 337.001C-48.2 337.001 -40.2 327.801 -38.6 329.601z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-44.4 313.001C-44.4 313.001 -32.8 290.601 -54.6 316.401C-54.6 316.401 -43.6 306.601 -44.4 313.001z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M-59.8 298.401C-59.8 298.401 -55 279.601 -52.4 279.801C-52.4 279.801 -44.2 270.801 -50.8 281.401C-50.8 281.401 -56.8 291.001 -56.2 300.801C-56.2 300.801 -56.8 291.201 -59.8 298.401z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M270.5 287C270.5 287 258.5 277 256 273.5C256 273.5 269.5 292 269.5 299C269.5 299 272 291.5 270.5 287z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M276 265C276 265 255 250 251.5 242.5C251.5 242.5 278 272 278 276.5C278 276.5 278.5 267.5 276 265z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M293 111C293 111 281 103 279.5 105C279.5 105 290 111.5 292.5 120C292.5 120 291 111 293 111z").setFill(f).setStroke(s);
+ f = "#cccccc";
+ g.createPath("M301.5 191.5L284 179.5C284 179.5 303 196.5 303.5 200.5L301.5 191.5z").setFill(f).setStroke(s);
+ s = "#000000"; f = null;
+ g.createPath("M-89.25 169L-67.25 173.75").setFill(f).setStroke(s);
+ s = "#000000";
+ g.createPath("M-39 331C-39 331 -39.5 327.5 -48.5 338").setFill(f).setStroke(s);
+ s = "#000000";
+ g.createPath("M-33.5 336C-33.5 336 -31.5 329.5 -38 334").setFill(f).setStroke(s);
+ s = "#000000";
+ g.createPath("M20.5 344.5C20.5 344.5 22 333.5 10.5 346.5").setFill(f).setStroke(s);
+ //surface.createLine({x1: 0, y1: 350, x2: 700, y2: 350}).setStroke("green");
+ //surface.createLine({y1: 0, x1: 350, y2: 700, x2: 350}).setStroke("green");
+ dojo.connect(dijit.byId("rotatingSlider"), "onChange", rotatingEvent);
+ dojo.connect(dijit.byId("scalingSlider"), "onChange", scalingEvent);
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+<style type="text/css">
+ td.pad { padding: 0px 5px 0px 5px; }
+</style>
+</head>
+<body class="tundra">
+ <h1>dojox.gfx: Tiger</h1>
+ <p>This example was directly converted from SVG file.</p>
+ <table>
+ <tr><td align="center" class="pad">Rotation (<span id="rotationValue">0</span>)</td></tr>
+ <tr><td>
+ <div id="rotatingSlider" dojoType="dijit.form.HorizontalSlider"
+ value="0" minimum="-180" maximum="180" discreteValues="72" showButtons="false" intermediateChanges="true"
+ style="width: 600px;">
+ <div dojoType="dijit.form.HorizontalRule" container="topDecoration" count="73" style="height:5px;"></div>
+ <div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count="9" style="height:5px;"></div>
+ <div dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" labels="-180,-135,-90,-45,0,45,90,135,180" style="height:1.2em;font-size:75%;color:gray;"></div>
+ </div>
+ </td></tr>
+ <tr><td align="center" class="pad">Scaling (<span id="scaleValue">1.000</span>)</td></tr>
+ <tr><td>
+ <div id="scalingSlider" dojoType="dijit.form.HorizontalSlider"
+ value="1" minimum="0" maximum="1" showButtons="false" intermediateChanges="true"
+ style="width: 600px;">
+ <div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count="5" style="height:5px;"></div>
+ <div dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" labels="10%,18%,32%,56%,100%" style="height:1.2em;font-size:75%;color:gray;"></div>
+ </div>
+ </td></tr>
+ </table>
+ <div id="gfx_holder" style="width: 700px; height: 700px;"></div>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/demos/tooltip.html b/includes/js/dojox/gfx/demos/tooltip.html
new file mode 100644
index 0000000..96bb694
--- /dev/null
+++ b/includes/js/dojox/gfx/demos/tooltip.html
@@ -0,0 +1,238 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
+<head>
+ <title>A Sample ToolTip using dijit and dojox.gfx</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+ @import "../../../dijit/themes/tundra/tundra.css";
+ .tooltipBody {
+ color:#fff;
+ }
+ </style>
+ <!--
+ The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+ <script type="text/javascript" src="Silverlight.js"></script>
+ -->
+ <script type="text/javascript" djConfig="parseOnLoad:true, isDebug:true" src="../../../dojo/dojo.js"></script>
+ <script type="text/javascript">
+ dojo.require("dijit.form.Button");
+
+ dojo.require("dojox.gfx");
+ dojo.require("dojox.gfx.move");
+ dojo.require("dijit._Widget"); dojo.require("dijit._Templated");
+
+ dojo.declare("demo.Tooltip",[dijit._Widget,dijit._Templated],{
+
+ // attachId: String|DomNode?
+ // the Id or domNode to attach this tooltip to
+ attachId:"",
+
+ // attachHover: Boolean
+ // disable hover behavior for the target
+ attachHover:true,
+
+ // attachParent: Boolean
+ // automatically attach to our parentnode rather than byId or query
+ attachParent:false,
+
+ // attachQuery: String?
+ // an optional selector query to attach this tooltip to
+ attachQuery:"",
+
+ // attachScope: String|DomNode?
+ // and optional scope to run the query against, passed as the
+ // second arg to dojo.query()
+ queryScope:"",
+
+ // hideDelay: Int
+ // time in my to delay automatically closing the node
+ hideDelay: 123, // ms
+
+ // persists: Boolean
+ // if true, the node will stay visible until explicitly closed
+ // via _hide() or click on closeIcon
+ persists:false,
+
+ templateString:
+ '<div class="foo">'
+ +'<div style="position:relative;">'
+ +'<div dojoAttachPoint="surfaceNode"></div>'
+ +'<div class="tooltipBody" dojoAttachPoint="containerNode"></div>'
+ +'</div>'
+ +'</div>',
+
+ postCreate:function(){
+ // call _Widget postCreate first
+ this.inherited(arguments);
+ // gfx version of "_Templated" idea:
+ this._initSurface();
+
+ if(this.attachParent){
+ // over-ride and reuse attachId as domNode from now on
+ this.attachId = this.domNode.parentNode;
+ }
+ if(this.attachId){
+ // domNode again. setup connections
+ this.attachId = dojo.byId(this.attachId);
+ if(this.attachHover){
+ this.connect(this.attachId,"onmouseenter","_show");
+ }
+ if(!this.persists){
+ this.connect(this.attachId,"onmouseleave","_initHide");
+ }
+ }else if(this.attachQuery){
+ // setup connections via dojo.query for multi-tooltips
+ var nl = dojo.query(this.attachQuery,this.queryScope);
+ if(this.attachHover){ nl.connect("onmouseenter",this,"_show") }
+ if(!this.persists){ nl.connect("onmouseleave",this,"_initHide") }
+ }
+ // place the tooltip
+ dojo.body().appendChild(this.domNode);
+ dojo.style(this.domNode,{
+ position:"absolute"
+ });
+ // could do this in css:
+ dojo.style(this.containerNode,{
+ position:"absolute",
+ top:"15px",
+ left:"12px",
+ height:"83px",
+ width:"190px"
+ });
+ // setup our animations
+ this._hideAnim = dojo.fadeOut({ node:this.domNode, duration:150 });
+ this._showAnim = dojo.fadeIn({ node:this.domNode, duration:75 });
+ this.connect(this._hideAnim,"onEnd","_postHide");
+ if(!this.persists){
+ this.connect(this.domNode,"onmouseleave","_initHide");
+ }
+ // hide quickly
+ this._postHide();
+ },
+
+ _initHide: function(e){
+ // summary: start the timer for the hideDelay
+ if(!this.persists && this.hideDelay){
+ this._delay = setTimeout(dojo.hitch(this,"_hide",e||null),this.hideDelay);
+ }
+ },
+
+ _clearDelay: function(){
+ // summary: clear our hide delay timeout
+ if(this._delay){ clearTimeout(this._delay); }
+ },
+
+ _show: function(e){
+ // summary: show the widget
+ this._clearDelay();
+ var pos = dojo.coords(e.target || this.attachId,true)
+ // we need to more accurately position the domNode:
+ dojo.style(this.domNode,{
+ top: pos.y - (pos.h / 2) - 50,
+ left: pos.x + pos.w - 25,
+ display:"block"
+ });
+ dojo.fadeIn({ node: this.domNode, duration:75 }).play();
+ },
+
+ _hide: function(e){
+ // summary: hide the tooltip
+ this._hideAnim.play();
+ },
+
+ _postHide: function(){
+ // summary: after hide animation cleanup
+ dojo.style(this.domNode,"display","none");
+ },
+
+ _initSurface:function(){
+ // made generally from an SVG file:
+ this.surface = dojox.gfx.createSurface(this.surfaceNode,220,120);
+ this.tooltip = this.surface.createGroup();
+ this.tooltip.createPath("M213,101.072c0,6.675-5.411,12.086-12.086,12.086H13.586 c-6.675,0-12.086-5.411-12.086-12.086V21.004c0-6.675,5.411-12.086,12.086-12.086h187.328c6.675,0,12.086,5.411,12.086,12.086 V101.072z")
+ .setFill("rgba(0,0,0,0.25)");
+
+ this.tooltip.createPath("M211.5,97.418c0,6.627-5.373,12-12,12 h-186c-6.627,0-12-5.373-12-12v-79.5c0-6.627,5.373-12,12-12h186c6.627,0,12,5.373,12,12V97.418z")
+ .setStroke({ width:2, color:"#FFF" })
+ .setFill("rgba(0,0,0,0.5)")
+ .connect("onmouseover",dojo.hitch(this,"_clearDelay"));
+
+ if(this.persists){
+ // make the close icon
+ this._toolButton = this.surface.createGroup();
+ this._toolButton.createEllipse({ cx:207.25, cy:12.32, rx: 7.866, ry: 7.099 })
+ .setFill("#ededed");
+ this._toolButton.createCircle({ cx:207.25, cy: 9.25, r:8.25 })
+ .setStroke({ width:2, color:"#FFF" })
+ .setFill("#000")
+ ;
+ this._toolButton.connect("onclick",dojo.hitch(this,"_hide"));
+ // the X
+ this._toolButton.createLine({ x1:203.618, y1:5.04, x2: 210.89, y2:12.979 })
+ .setStroke({ width:2, color:"#d6d6d6" });
+ this._toolButton.createLine({ x1:203.539, y1:12.979, x2: 210.89, y2:5.04 })
+ .setStroke({ width:2, color:"#d6d6d6" });
+ }
+ }
+ });
+ </script>
+
+</head>
+<body class="tundra">
+
+ <h1>dojox.gfx: A Sample tooltip</h1>
+
+ <ul style="width:150px; border:2px solid #ededed; cursor:pointer">
+
+
+ <!-- you can put any content you want in there -->
+ <li id="warn2">
+ Tooltip + Button
+ <div attachId="warn2" id="warn2tt" dojoType="demo.Tooltip"><p style="margin-top:0">Canvas renderer doesn't implement event handling.
+ <button dojoType="dijit.form.Button">
+ Button
+ <script type="dojo/method" event="onClick">
+ alert(" woo hoo! ");
+ dijit.byId("warn2tt")._hide();
+ </script>
+ </button>
+ </p></div>
+ </li>
+
+ <!-- a simple tooltip -->
+ <li id="warn1">
+ Hover trigger / persists
+ <div persists="true" attachId="warn1" dojoType="demo.Tooltip">Canvas renderer doesn't implement event handling.</div>
+ </li>
+
+ <!-- these get the same tooltip from the attachQuery=".multitip" below -->
+ <li class="multitip">MultiTip trigger 1</li>
+ <li>I do nothing</li>
+ <li class="multitip">Trigger two</li>
+
+ <li><a href="#" onclick="dijit.byId('nohover')._show(arguments[0])">show this way
+ <label dojoType="demo.Tooltip" attachParent="true" attachHover="false" id="nohover">some text</label>
+ </a>
+ </li>
+
+ <!-- attachParent makes the tooltip look for domNode.parentNode before moving to body() -->
+ <li>
+ Parent Attached Tooltip
+ <div attachParent="true" persists="true" dojoType="demo.Tooltip">
+ <form id="fooForm">
+ <p style="margin-top:0;">
+ Name:<br> <input type="text" name="username" style="border:1px solid #ededed" /><br>
+ Pass:<br> <input type="password" name="password" style="border:1px solid #ededed" />
+ </p>
+ </form>
+ </div>
+ </li>
+
+ </ul>
+
+ <!-- attach a single tooltip message to a number of nodes at once -->
+ <div attachQuery=".multitip" dojoType="demo.Tooltip">Canvas renderer doesn't implement event handling. (shared tooltip)</div>
+
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/fx.js b/includes/js/dojox/gfx/fx.js
new file mode 100644
index 0000000..2b576d6
--- /dev/null
+++ b/includes/js/dojox/gfx/fx.js
@@ -0,0 +1,281 @@
+if(!dojo._hasResource["dojox.gfx.fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.fx"] = true;
+dojo.provide("dojox.gfx.fx");
+
+dojo.require("dojox.gfx.matrix");
+
+(function(){
+ var d = dojo, g = dojox.gfx, m = g.matrix;
+
+ // Generic interpolators. Should they be moved to dojox.fx?
+
+ var InterpolNumber = function(start, end){
+ this.start = start, this.end = end;
+ };
+ d.extend(InterpolNumber, {
+ getValue: function(r){
+ return (this.end - this.start) * r + this.start;
+ }
+ });
+
+ var InterpolUnit = function(start, end, unit){
+ this.start = start, this.end = end;
+ this.unit = unit;
+ };
+ d.extend(InterpolUnit, {
+ getValue: function(r){
+ return (this.end - this.start) * r + this.start + this.unit;
+ }
+ });
+
+ var InterpolColor = function(start, end){
+ this.start = start, this.end = end;
+ this.temp = new dojo.Color();
+ };
+ d.extend(InterpolColor, {
+ getValue: function(r){
+ return d.blendColors(this.start, this.end, r, this.temp);
+ }
+ });
+
+ var InterpolValues = function(values){
+ this.values = values;
+ this.length = values.length;
+ };
+ d.extend(InterpolValues, {
+ getValue: function(r){
+ return this.values[Math.min(Math.floor(r * this.length), this.length - 1)];
+ }
+ });
+
+ var InterpolObject = function(values, def){
+ this.values = values;
+ this.def = def ? def : {};
+ };
+ d.extend(InterpolObject, {
+ getValue: function(r){
+ var ret = dojo.clone(this.def);
+ for(var i in this.values){
+ ret[i] = this.values[i].getValue(r);
+ }
+ return ret;
+ }
+ });
+
+ var InterpolTransform = function(stack, original){
+ this.stack = stack;
+ this.original = original;
+ };
+ d.extend(InterpolTransform, {
+ getValue: function(r){
+ var ret = [];
+ dojo.forEach(this.stack, function(t){
+ if(t instanceof m.Matrix2D){
+ ret.push(t);
+ return;
+ }
+ if(t.name == "original" && this.original){
+ ret.push(this.original);
+ return;
+ }
+ if(!(t.name in m)){ return; }
+ var f = m[t.name];
+ if(typeof f != "function"){
+ // constant
+ ret.push(f);
+ return;
+ }
+ var val = dojo.map(t.start, function(v, i){
+ return (t.end[i] - v) * r + v;
+ }),
+ matrix = f.apply(m, val);
+ if(matrix instanceof m.Matrix2D){
+ ret.push(matrix);
+ }
+ }, this);
+ return ret;
+ }
+ });
+
+ var transparent = new d.Color(0, 0, 0, 0);
+
+ var getColorInterpol = function(prop, obj, name, def){
+ if(prop.values){
+ return new InterpolValues(prop.values);
+ }
+ var value, start, end;
+ if(prop.start){
+ start = g.normalizeColor(prop.start);
+ }else{
+ start = value = obj ? (name ? obj[name] : obj) : def;
+ }
+ if(prop.end){
+ end = g.normalizeColor(prop.end);
+ }else{
+ if(!value){
+ value = obj ? (name ? obj[name] : obj) : def;
+ }
+ end = value;
+ }
+ return new InterpolColor(start, end);
+ };
+
+ var getNumberInterpol = function(prop, obj, name, def){
+ if(prop.values){
+ return new InterpolValues(prop.values);
+ }
+ var value, start, end;
+ if(prop.start){
+ start = prop.start;
+ }else{
+ start = value = obj ? obj[name] : def;
+ }
+ if(prop.end){
+ end = prop.end;
+ }else{
+ if(typeof value != "number"){
+ value = obj ? obj[name] : def;
+ }
+ end = value;
+ }
+ return new InterpolNumber(start, end);
+ };
+
+ g.fx.animateStroke = function(/*Object*/ args){
+ // summary:
+ // returns the animation, which will change stroke properties over time
+ // example:
+ // | dojox.gfx.fx.animateStroke{{
+ // | shape: shape,
+ // | duration: 500,
+ // | color: {start: "red", end: "green"},
+ // | width: {end: 15},
+ // | join: {values: ["miter", "bevel", "round"]}
+ // | }).play();
+ if(!args.easing){ args.easing = d._defaultEasing; }
+ var anim = new d._Animation(args), shape = args.shape, stroke;
+ d.connect(anim, "beforeBegin", anim, function(){
+ stroke = shape.getStroke();
+ var prop = args.color, values = {}, value, start, end;
+ if(prop){
+ values.color = getColorInterpol(prop, stroke, "color", transparent);
+ }
+ prop = args.style;
+ if(prop && prop.values){
+ values.style = new InterpolValues(prop.values);
+ }
+ prop = args.width;
+ if(prop){
+ values.width = getNumberInterpol(prop, stroke, "width", 1);
+ }
+ prop = args.cap;
+ if(prop && prop.values){
+ values.cap = new InterpolValues(prop.values);
+ }
+ prop = args.join;
+ if(prop){
+ if(prop.values){
+ values.join = new InterpolValues(prop.values);
+ }else{
+ start = prop.start ? prop.start : (stroke && stroke.join || 0);
+ end = prop.end ? prop.end : (stroke && stroke.join || 0);
+ if(typeof start == "number" && typeof end == "number"){
+ values.join = new InterpolNumber(start, end);
+ }
+ }
+ }
+ this.curve = new InterpolObject(values, stroke);
+ });
+ d.connect(anim, "onAnimate", shape, "setStroke");
+ return anim;
+ };
+
+ g.fx.animateFill = function(/*Object*/ args){
+ // summary:
+ // returns the animation, which will change fill color over time,
+ // only solid fill color is supported at the moment
+ // example:
+ // | dojox.gfx.fx.animateFill{{
+ // | shape: shape,
+ // | duration: 500,
+ // | color: {start: "red", end: "green"}
+ // | }).play();
+ if(!args.easing){ args.easing = d._defaultEasing; }
+ var anim = new d._Animation(args), shape = args.shape, fill;
+ d.connect(anim, "beforeBegin", anim, function(){
+ fill = shape.getFill();
+ var prop = args.color, values = {};
+ if(prop){
+ this.curve = getColorInterpol(prop, fill, "", transparent);
+ }
+ });
+ d.connect(anim, "onAnimate", shape, "setFill");
+ return anim;
+ };
+
+ g.fx.animateFont = function(/*Object*/ args){
+ // summary:
+ // returns the animation, which will change font properties over time
+ // example:
+ // | dojox.gfx.fx.animateFont{{
+ // | shape: shape,
+ // | duration: 500,
+ // | variant: {values: ["normal", "small-caps"]},
+ // | size: {end: 10, unit: "pt"}
+ // | }).play();
+ if(!args.easing){ args.easing = d._defaultEasing; }
+ var anim = new d._Animation(args), shape = args.shape, font;
+ d.connect(anim, "beforeBegin", anim, function(){
+ font = shape.getFont();
+ var prop = args.style, values = {}, value, start, end;
+ if(prop && prop.values){
+ values.style = new InterpolValues(prop.values);
+ }
+ prop = args.variant;
+ if(prop && prop.values){
+ values.variant = new InterpolValues(prop.values);
+ }
+ prop = args.weight;
+ if(prop && prop.values){
+ values.weight = new InterpolValues(prop.values);
+ }
+ prop = args.family;
+ if(prop && prop.values){
+ values.family = new InterpolValues(prop.values);
+ }
+ prop = args.size;
+ if(prop && prop.unit){
+ start = parseFloat(prop.start ? prop.start : (shape.font && shape.font.size || "0"));
+ end = parseFloat(prop.end ? prop.end : (shape.font && shape.font.size || "0"));
+ values.size = new InterpolUnit(start, end, prop.unit);
+ }
+ this.curve = new InterpolObject(values, font);
+ });
+ d.connect(anim, "onAnimate", shape, "setFont");
+ return anim;
+ };
+
+ g.fx.animateTransform = function(/*Object*/ args){
+ // summary:
+ // returns the animation, which will change transformation over time
+ // example:
+ // | dojox.gfx.fx.animateTransform{{
+ // | shape: shape,
+ // | duration: 500,
+ // | transform: [
+ // | {name: "translate", start: [0, 0], end: [200, 200]},
+ // | {name: "original"}
+ // | ]
+ // | }).play();
+ if(!args.easing){ args.easing = d._defaultEasing; }
+ var anim = new d._Animation(args), shape = args.shape, original;
+ d.connect(anim, "beforeBegin", anim, function(){
+ original = shape.getTransform();
+ this.curve = new InterpolTransform(args.transform, original);
+ });
+ d.connect(anim, "onAnimate", shape, "setTransform");
+ return anim;
+ };
+})();
+
+}
diff --git a/includes/js/dojox/gfx/matrix.js b/includes/js/dojox/gfx/matrix.js
new file mode 100644
index 0000000..f3402b1
--- /dev/null
+++ b/includes/js/dojox/gfx/matrix.js
@@ -0,0 +1,444 @@
+if(!dojo._hasResource["dojox.gfx.matrix"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.matrix"] = true;
+dojo.provide("dojox.gfx.matrix");
+
+(function(){
+ var m = dojox.gfx.matrix;
+
+ // candidates for dojox.math:
+ m._degToRad = function(degree){ return Math.PI * degree / 180; };
+ m._radToDeg = function(radian){ return radian / Math.PI * 180; };
+
+ m.Matrix2D = function(arg){
+ // summary: a 2D matrix object
+ // description: Normalizes a 2D matrix-like object. If arrays is passed,
+ // all objects of the array are normalized and multiplied sequentially.
+ // arg: Object
+ // a 2D matrix-like object, a number, or an array of such objects
+ if(arg){
+ if(typeof arg == "number"){
+ this.xx = this.yy = arg;
+ }else if(arg instanceof Array){
+ if(arg.length > 0){
+ var matrix = m.normalize(arg[0]);
+ // combine matrices
+ for(var i = 1; i < arg.length; ++i){
+ var l = matrix, r = dojox.gfx.matrix.normalize(arg[i]);
+ matrix = new m.Matrix2D();
+ matrix.xx = l.xx * r.xx + l.xy * r.yx;
+ matrix.xy = l.xx * r.xy + l.xy * r.yy;
+ matrix.yx = l.yx * r.xx + l.yy * r.yx;
+ matrix.yy = l.yx * r.xy + l.yy * r.yy;
+ matrix.dx = l.xx * r.dx + l.xy * r.dy + l.dx;
+ matrix.dy = l.yx * r.dx + l.yy * r.dy + l.dy;
+ }
+ dojo.mixin(this, matrix);
+ }
+ }else{
+ dojo.mixin(this, arg);
+ }
+ }
+ };
+
+ // the default (identity) matrix, which is used to fill in missing values
+ dojo.extend(m.Matrix2D, {xx: 1, xy: 0, yx: 0, yy: 1, dx: 0, dy: 0});
+
+ dojo.mixin(m, {
+ // summary: class constants, and methods of dojox.gfx.matrix
+
+ // matrix constants
+
+ // identity: dojox.gfx.matrix.Matrix2D
+ // an identity matrix constant: identity * (x, y) == (x, y)
+ identity: new m.Matrix2D(),
+
+ // flipX: dojox.gfx.matrix.Matrix2D
+ // a matrix, which reflects points at x = 0 line: flipX * (x, y) == (-x, y)
+ flipX: new m.Matrix2D({xx: -1}),
+
+ // flipY: dojox.gfx.matrix.Matrix2D
+ // a matrix, which reflects points at y = 0 line: flipY * (x, y) == (x, -y)
+ flipY: new m.Matrix2D({yy: -1}),
+
+ // flipXY: dojox.gfx.matrix.Matrix2D
+ // a matrix, which reflects points at the origin of coordinates: flipXY * (x, y) == (-x, -y)
+ flipXY: new m.Matrix2D({xx: -1, yy: -1}),
+
+ // matrix creators
+
+ translate: function(a, b){
+ // summary: forms a translation matrix
+ // description: The resulting matrix is used to translate (move) points by specified offsets.
+ // a: Number: an x coordinate value
+ // b: Number: a y coordinate value
+ if(arguments.length > 1){
+ return new m.Matrix2D({dx: a, dy: b}); // dojox.gfx.matrix.Matrix2D
+ }
+ // branch
+ // a: dojox.gfx.Point: a point-like object, which specifies offsets for both dimensions
+ // b: null
+ return new m.Matrix2D({dx: a.x, dy: a.y}); // dojox.gfx.matrix.Matrix2D
+ },
+ scale: function(a, b){
+ // summary: forms a scaling matrix
+ // description: The resulting matrix is used to scale (magnify) points by specified offsets.
+ // a: Number: a scaling factor used for the x coordinate
+ // b: Number: a scaling factor used for the y coordinate
+ if(arguments.length > 1){
+ return new m.Matrix2D({xx: a, yy: b}); // dojox.gfx.matrix.Matrix2D
+ }
+ if(typeof a == "number"){
+ // branch
+ // a: Number: a uniform scaling factor used for the both coordinates
+ // b: null
+ return new m.Matrix2D({xx: a, yy: a}); // dojox.gfx.matrix.Matrix2D
+ }
+ // branch
+ // a: dojox.gfx.Point: a point-like object, which specifies scale factors for both dimensions
+ // b: null
+ return new m.Matrix2D({xx: a.x, yy: a.y}); // dojox.gfx.matrix.Matrix2D
+ },
+ rotate: function(angle){
+ // summary: forms a rotating matrix
+ // description: The resulting matrix is used to rotate points
+ // around the origin of coordinates (0, 0) by specified angle.
+ // angle: Number: an angle of rotation in radians (>0 for CW)
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+ return new m.Matrix2D({xx: c, xy: -s, yx: s, yy: c}); // dojox.gfx.matrix.Matrix2D
+ },
+ rotateg: function(degree){
+ // summary: forms a rotating matrix
+ // description: The resulting matrix is used to rotate points
+ // around the origin of coordinates (0, 0) by specified degree.
+ // See dojox.gfx.matrix.rotate() for comparison.
+ // degree: Number: an angle of rotation in degrees (>0 for CW)
+ return m.rotate(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D
+ },
+ skewX: function(angle) {
+ // summary: forms an x skewing matrix
+ // description: The resulting matrix is used to skew points in the x dimension
+ // around the origin of coordinates (0, 0) by specified angle.
+ // angle: Number: an skewing angle in radians
+ return new m.Matrix2D({xy: -Math.tan(angle)}); // dojox.gfx.matrix.Matrix2D
+ },
+ skewXg: function(degree){
+ // summary: forms an x skewing matrix
+ // description: The resulting matrix is used to skew points in the x dimension
+ // around the origin of coordinates (0, 0) by specified degree.
+ // See dojox.gfx.matrix.skewX() for comparison.
+ // degree: Number: an skewing angle in degrees
+ return m.skewX(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D
+ },
+ skewY: function(angle){
+ // summary: forms a y skewing matrix
+ // description: The resulting matrix is used to skew points in the y dimension
+ // around the origin of coordinates (0, 0) by specified angle.
+ // angle: Number: an skewing angle in radians
+ return new m.Matrix2D({yx: Math.tan(angle)}); // dojox.gfx.matrix.Matrix2D
+ },
+ skewYg: function(degree){
+ // summary: forms a y skewing matrix
+ // description: The resulting matrix is used to skew points in the y dimension
+ // around the origin of coordinates (0, 0) by specified degree.
+ // See dojox.gfx.matrix.skewY() for comparison.
+ // degree: Number: an skewing angle in degrees
+ return m.skewY(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D
+ },
+ reflect: function(a, b){
+ // summary: forms a reflection matrix
+ // description: The resulting matrix is used to reflect points around a vector,
+ // which goes through the origin.
+ // a: dojox.gfx.Point: a point-like object, which specifies a vector of reflection
+ // b: null
+ if(arguments.length == 1){
+ b = a.y;
+ a = a.x;
+ }
+ // branch
+ // a: Number: an x coordinate value
+ // b: Number: a y coordinate value
+
+ // make a unit vector
+ var a2 = a * a, b2 = b * b, n2 = a2 + b2, xy = 2 * a * b / n2;
+ return new m.Matrix2D({xx: 2 * a2 / n2 - 1, xy: xy, yx: xy, yy: 2 * b2 / n2 - 1}); // dojox.gfx.matrix.Matrix2D
+ },
+ project: function(a, b){
+ // summary: forms an orthogonal projection matrix
+ // description: The resulting matrix is used to project points orthogonally on a vector,
+ // which goes through the origin.
+ // a: dojox.gfx.Point: a point-like object, which specifies a vector of projection
+ // b: null
+ if(arguments.length == 1){
+ b = a.y;
+ a = a.x;
+ }
+ // branch
+ // a: Number: an x coordinate value
+ // b: Number: a y coordinate value
+
+ // make a unit vector
+ var a2 = a * a, b2 = b * b, n2 = a2 + b2, xy = a * b / n2;
+ return new m.Matrix2D({xx: a2 / n2, xy: xy, yx: xy, yy: b2 / n2}); // dojox.gfx.matrix.Matrix2D
+ },
+
+ // ensure matrix 2D conformance
+ normalize: function(matrix){
+ // summary: converts an object to a matrix, if necessary
+ // description: Converts any 2D matrix-like object or an array of
+ // such objects to a valid dojox.gfx.matrix.Matrix2D object.
+ // matrix: Object: an object, which is converted to a matrix, if necessary
+ return (matrix instanceof m.Matrix2D) ? matrix : new m.Matrix2D(matrix); // dojox.gfx.matrix.Matrix2D
+ },
+
+ // common operations
+
+ clone: function(matrix){
+ // summary: creates a copy of a 2D matrix
+ // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be cloned
+ var obj = new m.Matrix2D();
+ for(var i in matrix){
+ if(typeof(matrix[i]) == "number" && typeof(obj[i]) == "number" && obj[i] != matrix[i]) obj[i] = matrix[i];
+ }
+ return obj; // dojox.gfx.matrix.Matrix2D
+ },
+ invert: function(matrix){
+ // summary: inverts a 2D matrix
+ // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be inverted
+ var M = m.normalize(matrix),
+ D = M.xx * M.yy - M.xy * M.yx,
+ M = new m.Matrix2D({
+ xx: M.yy/D, xy: -M.xy/D,
+ yx: -M.yx/D, yy: M.xx/D,
+ dx: (M.xy * M.dy - M.yy * M.dx) / D,
+ dy: (M.yx * M.dx - M.xx * M.dy) / D
+ });
+ return M; // dojox.gfx.matrix.Matrix2D
+ },
+ _multiplyPoint: function(matrix, x, y){
+ // summary: applies a matrix to a point
+ // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
+ // x: Number: an x coordinate of a point
+ // y: Number: a y coordinate of a point
+ return {x: matrix.xx * x + matrix.xy * y + matrix.dx, y: matrix.yx * x + matrix.yy * y + matrix.dy}; // dojox.gfx.Point
+ },
+ multiplyPoint: function(matrix, /* Number||Point */ a, /* Number, optional */ b){
+ // summary: applies a matrix to a point
+ // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
+ // a: Number: an x coordinate of a point
+ // b: Number: a y coordinate of a point
+ var M = m.normalize(matrix);
+ if(typeof a == "number" && typeof b == "number"){
+ return m._multiplyPoint(M, a, b); // dojox.gfx.Point
+ }
+ // branch
+ // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
+ // a: dojox.gfx.Point: a point
+ // b: null
+ return m._multiplyPoint(M, a.x, a.y); // dojox.gfx.Point
+ },
+ multiply: function(matrix){
+ // summary: combines matrices by multiplying them sequentially in the given order
+ // matrix: dojox.gfx.matrix.Matrix2D...: a 2D matrix-like object,
+ // all subsequent arguments are matrix-like objects too
+ var M = m.normalize(matrix);
+ // combine matrices
+ for(var i = 1; i < arguments.length; ++i){
+ var l = M, r = m.normalize(arguments[i]);
+ M = new m.Matrix2D();
+ M.xx = l.xx * r.xx + l.xy * r.yx;
+ M.xy = l.xx * r.xy + l.xy * r.yy;
+ M.yx = l.yx * r.xx + l.yy * r.yx;
+ M.yy = l.yx * r.xy + l.yy * r.yy;
+ M.dx = l.xx * r.dx + l.xy * r.dy + l.dx;
+ M.dy = l.yx * r.dx + l.yy * r.dy + l.dy;
+ }
+ return M; // dojox.gfx.matrix.Matrix2D
+ },
+
+ // high level operations
+
+ _sandwich: function(matrix, x, y){
+ // summary: applies a matrix at a centrtal point
+ // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object, which is applied at a central point
+ // x: Number: an x component of the central point
+ // y: Number: a y component of the central point
+ return m.multiply(m.translate(x, y), matrix, m.translate(-x, -y)); // dojox.gfx.matrix.Matrix2D
+ },
+ scaleAt: function(a, b, c, d){
+ // summary: scales a picture using a specified point as a center of scaling
+ // description: Compare with dojox.gfx.matrix.scale().
+ // a: Number: a scaling factor used for the x coordinate
+ // b: Number: a scaling factor used for the y coordinate
+ // c: Number: an x component of a central point
+ // d: Number: a y component of a central point
+
+ // accepts several signatures:
+ // 1) uniform scale factor, Point
+ // 2) uniform scale factor, x, y
+ // 3) x scale, y scale, Point
+ // 4) x scale, y scale, x, y
+
+ switch(arguments.length){
+ case 4:
+ // a and b are scale factor components, c and d are components of a point
+ return m._sandwich(m.scale(a, b), c, d); // dojox.gfx.matrix.Matrix2D
+ case 3:
+ if(typeof c == "number"){
+ // branch
+ // a: Number: a uniform scaling factor used for both coordinates
+ // b: Number: an x component of a central point
+ // c: Number: a y component of a central point
+ // d: null
+ return m._sandwich(m.scale(a), b, c); // dojox.gfx.matrix.Matrix2D
+ }
+ // branch
+ // a: Number: a scaling factor used for the x coordinate
+ // b: Number: a scaling factor used for the y coordinate
+ // c: dojox.gfx.Point: a central point
+ // d: null
+ return m._sandwich(m.scale(a, b), c.x, c.y); // dojox.gfx.matrix.Matrix2D
+ }
+ // branch
+ // a: Number: a uniform scaling factor used for both coordinates
+ // b: dojox.gfx.Point: a central point
+ // c: null
+ // d: null
+ return m._sandwich(m.scale(a), b.x, b.y); // dojox.gfx.matrix.Matrix2D
+ },
+ rotateAt: function(angle, a, b){
+ // summary: rotates a picture using a specified point as a center of rotation
+ // description: Compare with dojox.gfx.matrix.rotate().
+ // angle: Number: an angle of rotation in radians (>0 for CW)
+ // a: Number: an x component of a central point
+ // b: Number: a y component of a central point
+
+ // accepts several signatures:
+ // 1) rotation angle in radians, Point
+ // 2) rotation angle in radians, x, y
+
+ if(arguments.length > 2){
+ return m._sandwich(m.rotate(angle), a, b); // dojox.gfx.matrix.Matrix2D
+ }
+
+ // branch
+ // angle: Number: an angle of rotation in radians (>0 for CCW)
+ // a: dojox.gfx.Point: a central point
+ // b: null
+ return m._sandwich(m.rotate(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+ },
+ rotategAt: function(degree, a, b){
+ // summary: rotates a picture using a specified point as a center of rotation
+ // description: Compare with dojox.gfx.matrix.rotateg().
+ // degree: Number: an angle of rotation in degrees (>0 for CW)
+ // a: Number: an x component of a central point
+ // b: Number: a y component of a central point
+
+ // accepts several signatures:
+ // 1) rotation angle in degrees, Point
+ // 2) rotation angle in degrees, x, y
+
+ if(arguments.length > 2){
+ return m._sandwich(m.rotateg(degree), a, b); // dojox.gfx.matrix.Matrix2D
+ }
+
+ // branch
+ // degree: Number: an angle of rotation in degrees (>0 for CCW)
+ // a: dojox.gfx.Point: a central point
+ // b: null
+ return m._sandwich(m.rotateg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+ },
+ skewXAt: function(angle, a, b){
+ // summary: skews a picture along the x axis using a specified point as a center of skewing
+ // description: Compare with dojox.gfx.matrix.skewX().
+ // angle: Number: an skewing angle in radians
+ // a: Number: an x component of a central point
+ // b: Number: a y component of a central point
+
+ // accepts several signatures:
+ // 1) skew angle in radians, Point
+ // 2) skew angle in radians, x, y
+
+ if(arguments.length > 2){
+ return m._sandwich(m.skewX(angle), a, b); // dojox.gfx.matrix.Matrix2D
+ }
+
+ // branch
+ // angle: Number: an skewing angle in radians
+ // a: dojox.gfx.Point: a central point
+ // b: null
+ return m._sandwich(m.skewX(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+ },
+ skewXgAt: function(degree, a, b){
+ // summary: skews a picture along the x axis using a specified point as a center of skewing
+ // description: Compare with dojox.gfx.matrix.skewXg().
+ // degree: Number: an skewing angle in degrees
+ // a: Number: an x component of a central point
+ // b: Number: a y component of a central point
+
+ // accepts several signatures:
+ // 1) skew angle in degrees, Point
+ // 2) skew angle in degrees, x, y
+
+ if(arguments.length > 2){
+ return m._sandwich(m.skewXg(degree), a, b); // dojox.gfx.matrix.Matrix2D
+ }
+
+ // branch
+ // degree: Number: an skewing angle in degrees
+ // a: dojox.gfx.Point: a central point
+ // b: null
+ return m._sandwich(m.skewXg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+ },
+ skewYAt: function(angle, a, b){
+ // summary: skews a picture along the y axis using a specified point as a center of skewing
+ // description: Compare with dojox.gfx.matrix.skewY().
+ // angle: Number: an skewing angle in radians
+ // a: Number: an x component of a central point
+ // b: Number: a y component of a central point
+
+ // accepts several signatures:
+ // 1) skew angle in radians, Point
+ // 2) skew angle in radians, x, y
+
+ if(arguments.length > 2){
+ return m._sandwich(m.skewY(angle), a, b); // dojox.gfx.matrix.Matrix2D
+ }
+
+ // branch
+ // angle: Number: an skewing angle in radians
+ // a: dojox.gfx.Point: a central point
+ // b: null
+ return m._sandwich(m.skewY(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+ },
+ skewYgAt: function(/* Number */ degree, /* Number||Point */ a, /* Number, optional */ b){
+ // summary: skews a picture along the y axis using a specified point as a center of skewing
+ // description: Compare with dojox.gfx.matrix.skewYg().
+ // degree: Number: an skewing angle in degrees
+ // a: Number: an x component of a central point
+ // b: Number: a y component of a central point
+
+ // accepts several signatures:
+ // 1) skew angle in degrees, Point
+ // 2) skew angle in degrees, x, y
+
+ if(arguments.length > 2){
+ return m._sandwich(m.skewYg(degree), a, b); // dojox.gfx.matrix.Matrix2D
+ }
+
+ // branch
+ // degree: Number: an skewing angle in degrees
+ // a: dojox.gfx.Point: a central point
+ // b: null
+ return m._sandwich(m.skewYg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+ }
+
+ //TODO: rect-to-rect mapping, scale-to-fit (isotropic and anisotropic versions)
+
+ });
+})();
+
+// propagate Matrix2D up
+dojox.gfx.Matrix2D = dojox.gfx.matrix.Matrix2D;
+
+}
diff --git a/includes/js/dojox/gfx/move.js b/includes/js/dojox/gfx/move.js
new file mode 100644
index 0000000..dba5ced
--- /dev/null
+++ b/includes/js/dojox/gfx/move.js
@@ -0,0 +1,8 @@
+if(!dojo._hasResource["dojox.gfx.move"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.move"] = true;
+dojo.provide("dojox.gfx.move");
+
+dojo.require("dojox.gfx.Mover");
+dojo.require("dojox.gfx.Moveable");
+
+}
diff --git a/includes/js/dojox/gfx/path.js b/includes/js/dojox/gfx/path.js
new file mode 100644
index 0000000..657136b
--- /dev/null
+++ b/includes/js/dojox/gfx/path.js
@@ -0,0 +1,361 @@
+if(!dojo._hasResource["dojox.gfx.path"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.path"] = true;
+dojo.provide("dojox.gfx.path");
+
+dojo.require("dojox.gfx.shape");
+
+dojo.declare("dojox.gfx.path.Path", dojox.gfx.Shape, {
+ // summary: a generalized path shape
+
+ constructor: function(rawNode){
+ // summary: a path constructor
+ // rawNode: Node: a DOM node to be used by this path object
+ this.shape = dojo.clone(dojox.gfx.defaultPath);
+ this.segments = [];
+ this.absolute = true;
+ this.last = {};
+ this.rawNode = rawNode;
+ },
+
+ // mode manipulations
+ setAbsoluteMode: function(mode){
+ // summary: sets an absolute or relative mode for path points
+ // mode: Boolean: true/false or "absolute"/"relative" to specify the mode
+ this.absolute = typeof mode == "string" ? (mode == "absolute") : mode;
+ return this; // self
+ },
+ getAbsoluteMode: function(){
+ // summary: returns a current value of the absolute mode
+ return this.absolute; // Boolean
+ },
+
+ getBoundingBox: function(){
+ // summary: returns the bounding box {x, y, width, height} or null
+ return (this.bbox && ("l" in this.bbox)) ? {x: this.bbox.l, y: this.bbox.t, width: this.bbox.r - this.bbox.l, height: this.bbox.b - this.bbox.t} : null; // dojox.gfx.Rectangle
+ },
+
+ getLastPosition: function(){
+ // summary: returns the last point in the path, or null
+ return "x" in this.last ? this.last : null; // Object
+ },
+
+ // segment interpretation
+ _updateBBox: function(x, y){
+ // summary: updates the bounding box of path with new point
+ // x: Number: an x coordinate
+ // y: Number: a y coordinate
+
+ // we use {l, b, r, t} representation of a bbox
+ if(this.bbox && ("l" in this.bbox)){
+ if(this.bbox.l > x) this.bbox.l = x;
+ if(this.bbox.r < x) this.bbox.r = x;
+ if(this.bbox.t > y) this.bbox.t = y;
+ if(this.bbox.b < y) this.bbox.b = y;
+ }else{
+ this.bbox = {l: x, b: y, r: x, t: y};
+ }
+ },
+ _updateWithSegment: function(segment){
+ // summary: updates the bounding box of path with new segment
+ // segment: Object: a segment
+ var n = segment.args, l = n.length;
+ // update internal variables: bbox, absolute, last
+ switch(segment.action){
+ case "M":
+ case "L":
+ case "C":
+ case "S":
+ case "Q":
+ case "T":
+ for(var i = 0; i < l; i += 2){
+ this._updateBBox(n[i], n[i + 1]);
+ }
+ this.last.x = n[l - 2];
+ this.last.y = n[l - 1];
+ this.absolute = true;
+ break;
+ case "H":
+ for(var i = 0; i < l; ++i){
+ this._updateBBox(n[i], this.last.y);
+ }
+ this.last.x = n[l - 1];
+ this.absolute = true;
+ break;
+ case "V":
+ for(var i = 0; i < l; ++i){
+ this._updateBBox(this.last.x, n[i]);
+ }
+ this.last.y = n[l - 1];
+ this.absolute = true;
+ break;
+ case "m":
+ var start = 0;
+ if(!("x" in this.last)){
+ this._updateBBox(this.last.x = n[0], this.last.y = n[1]);
+ start = 2;
+ }
+ for(var i = start; i < l; i += 2){
+ this._updateBBox(this.last.x += n[i], this.last.y += n[i + 1]);
+ }
+ this.absolute = false;
+ break;
+ case "l":
+ case "t":
+ for(var i = 0; i < l; i += 2){
+ this._updateBBox(this.last.x += n[i], this.last.y += n[i + 1]);
+ }
+ this.absolute = false;
+ break;
+ case "h":
+ for(var i = 0; i < l; ++i){
+ this._updateBBox(this.last.x += n[i], this.last.y);
+ }
+ this.absolute = false;
+ break;
+ case "v":
+ for(var i = 0; i < l; ++i){
+ this._updateBBox(this.last.x, this.last.y += n[i]);
+ }
+ this.absolute = false;
+ break;
+ case "c":
+ for(var i = 0; i < l; i += 6){
+ this._updateBBox(this.last.x + n[i], this.last.y + n[i + 1]);
+ this._updateBBox(this.last.x + n[i + 2], this.last.y + n[i + 3]);
+ this._updateBBox(this.last.x += n[i + 4], this.last.y += n[i + 5]);
+ }
+ this.absolute = false;
+ break;
+ case "s":
+ case "q":
+ for(var i = 0; i < l; i += 4){
+ this._updateBBox(this.last.x + n[i], this.last.y + n[i + 1]);
+ this._updateBBox(this.last.x += n[i + 2], this.last.y += n[i + 3]);
+ }
+ this.absolute = false;
+ break;
+ case "A":
+ for(var i = 0; i < l; i += 7){
+ this._updateBBox(n[i + 5], n[i + 6]);
+ }
+ this.last.x = n[l - 2];
+ this.last.y = n[l - 1];
+ this.absolute = true;
+ break;
+ case "a":
+ for(var i = 0; i < l; i += 7){
+ this._updateBBox(this.last.x += n[i + 5], this.last.y += n[i + 6]);
+ }
+ this.absolute = false;
+ break;
+ }
+ // add an SVG path segment
+ var path = [segment.action];
+ for(var i = 0; i < l; ++i){
+ path.push(dojox.gfx.formatNumber(n[i], true));
+ }
+ if(typeof this.shape.path == "string"){
+ this.shape.path += path.join("");
+ }else{
+ var l = path.length, a = this.shape.path;
+ for(var i = 0; i < l; ++i){
+ a.push(path[i]);
+ }
+ }
+ },
+
+ // a dictionary, which maps segment type codes to a number of their argemnts
+ _validSegments: {m: 2, l: 2, h: 1, v: 1, c: 6, s: 4, q: 4, t: 2, a: 7, z: 0},
+
+ _pushSegment: function(action, args){
+ // summary: adds a segment
+ // action: String: valid SVG code for a segment's type
+ // args: Array: a list of parameters for this segment
+ var group = this._validSegments[action.toLowerCase()];
+ if(typeof group == "number"){
+ if(group){
+ if(args.length >= group){
+ var segment = {action: action, args: args.slice(0, args.length - args.length % group)};
+ this.segments.push(segment);
+ this._updateWithSegment(segment);
+ }
+ }else{
+ var segment = {action: action, args: []};
+ this.segments.push(segment);
+ this._updateWithSegment(segment);
+ }
+ }
+ },
+
+ _collectArgs: function(array, args){
+ // summary: converts an array of arguments to plain numeric values
+ // array: Array: an output argument (array of numbers)
+ // args: Array: an input argument (can be values of Boolean, Number, dojox.gfx.Point, or an embedded array of them)
+ for(var i = 0; i < args.length; ++i){
+ var t = args[i];
+ if(typeof t == "boolean"){
+ array.push(t ? 1 : 0);
+ }else if(typeof t == "number"){
+ array.push(t);
+ }else if(t instanceof Array){
+ this._collectArgs(array, t);
+ }else if("x" in t && "y" in t){
+ array.push(t.x, t.y);
+ }
+ }
+ },
+
+ // segments
+ moveTo: function(){
+ // summary: formes a move segment
+ var args = [];
+ this._collectArgs(args, arguments);
+ this._pushSegment(this.absolute ? "M" : "m", args);
+ return this; // self
+ },
+ lineTo: function(){
+ // summary: formes a line segment
+ var args = [];
+ this._collectArgs(args, arguments);
+ this._pushSegment(this.absolute ? "L" : "l", args);
+ return this; // self
+ },
+ hLineTo: function(){
+ // summary: formes a horizontal line segment
+ var args = [];
+ this._collectArgs(args, arguments);
+ this._pushSegment(this.absolute ? "H" : "h", args);
+ return this; // self
+ },
+ vLineTo: function(){
+ // summary: formes a vertical line segment
+ var args = [];
+ this._collectArgs(args, arguments);
+ this._pushSegment(this.absolute ? "V" : "v", args);
+ return this; // self
+ },
+ curveTo: function(){
+ // summary: formes a curve segment
+ var args = [];
+ this._collectArgs(args, arguments);
+ this._pushSegment(this.absolute ? "C" : "c", args);
+ return this; // self
+ },
+ smoothCurveTo: function(){
+ // summary: formes a smooth curve segment
+ var args = [];
+ this._collectArgs(args, arguments);
+ this._pushSegment(this.absolute ? "S" : "s", args);
+ return this; // self
+ },
+ qCurveTo: function(){
+ // summary: formes a quadratic curve segment
+ var args = [];
+ this._collectArgs(args, arguments);
+ this._pushSegment(this.absolute ? "Q" : "q", args);
+ return this; // self
+ },
+ qSmoothCurveTo: function(){
+ // summary: formes a quadratic smooth curve segment
+ var args = [];
+ this._collectArgs(args, arguments);
+ this._pushSegment(this.absolute ? "T" : "t", args);
+ return this; // self
+ },
+ arcTo: function(){
+ // summary: formes an elliptic arc segment
+ var args = [];
+ this._collectArgs(args, arguments);
+ this._pushSegment(this.absolute ? "A" : "a", args);
+ return this; // self
+ },
+ closePath: function(){
+ // summary: closes a path
+ this._pushSegment("Z", []);
+ return this; // self
+ },
+
+ // setShape
+ _setPath: function(path){
+ // summary: forms a path using an SVG path string
+ // path: String: an SVG path string
+ var p = dojo.isArray(path) ? path : path.match(dojox.gfx.pathSvgRegExp);
+ this.segments = [];
+ this.absolute = true;
+ this.bbox = {};
+ this.last = {};
+ if(!p) return;
+ // create segments
+ var action = "", // current action
+ args = [], // current arguments
+ l = p.length;
+ for(var i = 0; i < l; ++i){
+ var t = p[i], x = parseFloat(t);
+ if(isNaN(x)){
+ if(action){
+ this._pushSegment(action, args);
+ }
+ args = [];
+ action = t;
+ }else{
+ args.push(x);
+ }
+ }
+ this._pushSegment(action, args);
+ },
+ setShape: function(newShape){
+ // summary: forms a path using a shape
+ // newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
+ dojox.gfx.Shape.prototype.setShape.call(this, typeof newShape == "string" ? {path: newShape} : newShape);
+ var path = this.shape.path;
+ // switch to non-updating version of path building
+ this.shape.path = [];
+ this._setPath(path);
+ // switch back to the string path
+ this.shape.path = this.shape.path.join("");
+ return this; // self
+ },
+
+ // useful constant for descendants
+ _2PI: Math.PI * 2
+});
+
+dojo.declare("dojox.gfx.path.TextPath", dojox.gfx.path.Path, {
+ // summary: a generalized TextPath shape
+
+ constructor: function(rawNode){
+ // summary: a TextPath shape constructor
+ // rawNode: Node: a DOM node to be used by this TextPath object
+ if(!("text" in this)){
+ this.text = dojo.clone(dojox.gfx.defaultTextPath);
+ }
+ if(!("fontStyle" in this)){
+ this.fontStyle = dojo.clone(dojox.gfx.defaultFont);
+ }
+ },
+ getText: function(){
+ // summary: returns the current text object or null
+ return this.text; // Object
+ },
+ setText: function(newText){
+ // summary: sets a text to be drawn along the path
+ this.text = dojox.gfx.makeParameters(this.text,
+ typeof newText == "string" ? {text: newText} : newText);
+ this._setText();
+ return this; // self
+ },
+ getFont: function(){
+ // summary: returns the current font object or null
+ return this.fontStyle; // Object
+ },
+ setFont: function(newFont){
+ // summary: sets a font for text
+ this.fontStyle = typeof newFont == "string" ?
+ dojox.gfx.splitFontString(newFont) :
+ dojox.gfx.makeParameters(dojox.gfx.defaultFont, newFont);
+ this._setFont();
+ return this; // self
+ }
+});
+
+}
diff --git a/includes/js/dojox/gfx/shape.js b/includes/js/dojox/gfx/shape.js
new file mode 100644
index 0000000..179f6c5
--- /dev/null
+++ b/includes/js/dojox/gfx/shape.js
@@ -0,0 +1,691 @@
+if(!dojo._hasResource["dojox.gfx.shape"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.shape"] = true;
+dojo.provide("dojox.gfx.shape");
+
+dojo.require("dojox.gfx._base");
+
+dojo.declare("dojox.gfx.Shape", null, {
+ // summary: a Shape object, which knows how to apply
+ // graphical attributes and transformations
+
+ constructor: function(){
+ // rawNode: Node: underlying node
+ this.rawNode = null;
+
+ // shape: Object: an abstract shape object
+ // (see dojox.gfx.defaultPath,
+ // dojox.gfx.defaultPolyline,
+ // dojox.gfx.defaultRect,
+ // dojox.gfx.defaultEllipse,
+ // dojox.gfx.defaultCircle,
+ // dojox.gfx.defaultLine,
+ // or dojox.gfx.defaultImage)
+ this.shape = null;
+
+ // matrix: dojox.gfx.Matrix2D: a transformation matrix
+ this.matrix = null;
+
+ // fillStyle: Object: a fill object
+ // (see dojox.gfx.defaultLinearGradient,
+ // dojox.gfx.defaultRadialGradient,
+ // dojox.gfx.defaultPattern,
+ // or dojo.Color)
+ this.fillStyle = null;
+
+ // strokeStyle: Object: a stroke object
+ // (see dojox.gfx.defaultStroke)
+ this.strokeStyle = null;
+
+ // bbox: dojox.gfx.Rectangle: a bounding box of this shape
+ // (see dojox.gfx.defaultRect)
+ this.bbox = null;
+
+ // virtual group structure
+
+ // parent: Object: a parent or null
+ // (see dojox.gfx.Surface,
+ // dojox.gfx.shape.VirtualGroup,
+ // or dojox.gfx.Group)
+ this.parent = null;
+
+ // parentMatrix: dojox.gfx.Matrix2D
+ // a transformation matrix inherited from the parent
+ this.parentMatrix = null;
+ },
+
+ // trivial getters
+
+ getNode: function(){
+ // summary: returns the current DOM Node or null
+ return this.rawNode; // Node
+ },
+ getShape: function(){
+ // summary: returns the current shape object or null
+ // (see dojox.gfx.defaultPath,
+ // dojox.gfx.defaultPolyline,
+ // dojox.gfx.defaultRect,
+ // dojox.gfx.defaultEllipse,
+ // dojox.gfx.defaultCircle,
+ // dojox.gfx.defaultLine,
+ // or dojox.gfx.defaultImage)
+ return this.shape; // Object
+ },
+ getTransform: function(){
+ // summary: returns the current transformation matrix or null
+ return this.matrix; // dojox.gfx.Matrix2D
+ },
+ getFill: function(){
+ // summary: returns the current fill object or null
+ // (see dojox.gfx.defaultLinearGradient,
+ // dojox.gfx.defaultRadialGradient,
+ // dojox.gfx.defaultPattern,
+ // or dojo.Color)
+ return this.fillStyle; // Object
+ },
+ getStroke: function(){
+ // summary: returns the current stroke object or null
+ // (see dojox.gfx.defaultStroke)
+ return this.strokeStyle; // Object
+ },
+ getParent: function(){
+ // summary: returns the parent or null
+ // (see dojox.gfx.Surface,
+ // dojox.gfx.shape.VirtualGroup,
+ // or dojox.gfx.Group)
+ return this.parent; // Object
+ },
+ getBoundingBox: function(){
+ // summary: returns the bounding box or null
+ // (see dojox.gfx.defaultRect)
+ return this.bbox; // dojox.gfx.Rectangle
+ },
+ getTransformedBoundingBox: function(){
+ // summary: returns an array of four points or null
+ // four points represent four corners of the untransformed bounding box
+ var b = this.getBoundingBox();
+ if(!b){
+ return null; // null
+ }
+ var m = this._getRealMatrix();
+ var r = [];
+ var g = dojox.gfx.matrix;
+ r.push(g.multiplyPoint(m, b.x, b.y));
+ r.push(g.multiplyPoint(m, b.x + b.width, b.y));
+ r.push(g.multiplyPoint(m, b.x + b.width, b.y + b.height));
+ r.push(g.multiplyPoint(m, b.x, b.y + b.height));
+ return r; // Array
+ },
+ getEventSource: function(){
+ // summary: returns a Node, which is used as
+ // a source of events for this shape
+
+ // COULD BE RE-IMPLEMENTED BY THE RENDERER!
+
+ return this.rawNode; // Node
+ },
+
+ // empty settings
+
+ setShape: function(shape){
+ // summary: sets a shape object
+ // (the default implementation simply ignores it)
+ // shape: Object: a shape object
+ // (see dojox.gfx.defaultPath,
+ // dojox.gfx.defaultPolyline,
+ // dojox.gfx.defaultRect,
+ // dojox.gfx.defaultEllipse,
+ // dojox.gfx.defaultCircle,
+ // dojox.gfx.defaultLine,
+ // or dojox.gfx.defaultImage)
+
+ // COULD BE RE-IMPLEMENTED BY THE RENDERER!
+
+ this.shape = dojox.gfx.makeParameters(this.shape, shape);
+ this.bbox = null;
+ return this; // self
+ },
+ setFill: function(fill){
+ // summary: sets a fill object
+ // (the default implementation simply ignores it)
+ // fill: Object: a fill object
+ // (see dojox.gfx.defaultLinearGradient,
+ // dojox.gfx.defaultRadialGradient,
+ // dojox.gfx.defaultPattern,
+ // or dojo.Color)
+
+ // COULD BE RE-IMPLEMENTED BY THE RENDERER!
+
+ if(!fill){
+ // don't fill
+ this.fillStyle = null;
+ return this; // self
+ }
+ var f = null;
+ if(typeof(fill) == "object" && "type" in fill){
+ // gradient or pattern
+ switch(fill.type){
+ case "linear":
+ f = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill);
+ break;
+ case "radial":
+ f = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill);
+ break;
+ case "pattern":
+ f = dojox.gfx.makeParameters(dojox.gfx.defaultPattern, fill);
+ break;
+ }
+ }else{
+ // color object
+ f = dojox.gfx.normalizeColor(fill);
+ }
+ this.fillStyle = f;
+ return this; // self
+ },
+ setStroke: function(stroke){
+ // summary: sets a stroke object
+ // (the default implementation simply ignores it)
+ // stroke: Object: a stroke object
+ // (see dojox.gfx.defaultStroke)
+
+ // COULD BE RE-IMPLEMENTED BY THE RENDERER!
+
+ if(!stroke){
+ // don't stroke
+ this.strokeStyle = null;
+ return this; // self
+ }
+ // normalize the stroke
+ if(typeof stroke == "string"){
+ stroke = {color: stroke};
+ }
+ var s = this.strokeStyle = dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke);
+ s.color = dojox.gfx.normalizeColor(s.color);
+ return this; // self
+ },
+ setTransform: function(matrix){
+ // summary: sets a transformation matrix
+ // matrix: dojox.gfx.Matrix2D: a matrix or a matrix-like object
+ // (see an argument of dojox.gfx.Matrix2D
+ // constructor for a list of acceptable arguments)
+
+ // COULD BE RE-IMPLEMENTED BY THE RENDERER!
+
+ this.matrix = dojox.gfx.matrix.clone(matrix ? dojox.gfx.matrix.normalize(matrix) : dojox.gfx.matrix.identity);
+ return this._applyTransform(); // self
+ },
+
+ _applyTransform: function(){
+ // summary: physically sets a matrix
+
+ // COULD BE RE-IMPLEMENTED BY THE RENDERER!
+
+ return this; // self
+ },
+
+ // z-index
+
+ moveToFront: function(){
+ // summary: moves a shape to front of its parent's list of shapes
+ var p = this.getParent();
+ if(p){
+ p._moveChildToFront(this);
+ this._moveToFront(); // execute renderer-specific action
+ }
+ return this; // self
+ },
+ moveToBack: function(){
+ // summary: moves a shape to back of its parent's list of shapes
+ var p = this.getParent();
+ if(p){
+ p._moveChildToBack(this);
+ this._moveToBack(); // execute renderer-specific action
+ }
+ return this;
+ },
+ _moveToFront: function(){
+ // summary: renderer-specific hook, see dojox.gfx.shape.Shape.moveToFront()
+
+ // COULD BE RE-IMPLEMENTED BY THE RENDERER!
+ },
+ _moveToBack: function(){
+ // summary: renderer-specific hook, see dojox.gfx.shape.Shape.moveToFront()
+
+ // COULD BE RE-IMPLEMENTED BY THE RENDERER!
+ },
+
+ // apply left & right transformation
+
+ applyRightTransform: function(matrix){
+ // summary: multiplies the existing matrix with an argument on right side
+ // (this.matrix * matrix)
+ // matrix: dojox.gfx.Matrix2D: a matrix or a matrix-like object
+ // (see an argument of dojox.gfx.Matrix2D
+ // constructor for a list of acceptable arguments)
+ return matrix ? this.setTransform([this.matrix, matrix]) : this; // self
+ },
+ applyLeftTransform: function(matrix){
+ // summary: multiplies the existing matrix with an argument on left side
+ // (matrix * this.matrix)
+ // matrix: dojox.gfx.Matrix2D: a matrix or a matrix-like object
+ // (see an argument of dojox.gfx.Matrix2D
+ // constructor for a list of acceptable arguments)
+ return matrix ? this.setTransform([matrix, this.matrix]) : this; // self
+ },
+ applyTransform: function(matrix){
+ // summary: a shortcut for dojox.gfx.Shape.applyRightTransform
+ // matrix: dojox.gfx.Matrix2D: a matrix or a matrix-like object
+ // (see an argument of dojox.gfx.Matrix2D
+ // constructor for a list of acceptable arguments)
+ return matrix ? this.setTransform([this.matrix, matrix]) : this; // self
+ },
+
+ // virtual group methods
+
+ removeShape: function(silently){
+ // summary: removes the shape from its parent's list of shapes
+ // silently: Boolean?: if true, do not redraw a picture yet
+ if(this.parent){
+ this.parent.remove(this, silently);
+ }
+ return this; // self
+ },
+ _setParent: function(parent, matrix){
+ // summary: sets a parent
+ // parent: Object: a parent or null
+ // (see dojox.gfx.Surface,
+ // dojox.gfx.shape.VirtualGroup,
+ // or dojox.gfx.Group)
+ // matrix: dojox.gfx.Matrix2D:
+ // a 2D matrix or a matrix-like object
+ this.parent = parent;
+ return this._updateParentMatrix(matrix); // self
+ },
+ _updateParentMatrix: function(matrix){
+ // summary: updates the parent matrix with new matrix
+ // matrix: dojox.gfx.Matrix2D:
+ // a 2D matrix or a matrix-like object
+ this.parentMatrix = matrix ? dojox.gfx.matrix.clone(matrix) : null;
+ return this._applyTransform(); // self
+ },
+ _getRealMatrix: function(){
+ // summary: returns the cumulative ("real") transformation matrix
+ // by combining the shape's matrix with its parent's matrix
+ var m = this.matrix;
+ var p = this.parent;
+ while(p){
+ if(p.matrix){
+ m = dojox.gfx.matrix.multiply(p.matrix, m);
+ }
+ p = p.parent;
+ }
+ return m; // dojox.gfx.Matrix2D
+ }
+});
+
+dojox.gfx.shape._eventsProcessing = {
+ connect: function(name, object, method){
+ // summary: connects a handler to an event on this shape
+
+ // COULD BE RE-IMPLEMENTED BY THE RENDERER!
+
+ return arguments.length > 2 ? // Object
+ dojo.connect(this.getEventSource(), name, object, method) :
+ dojo.connect(this.getEventSource(), name, object);
+ },
+ disconnect: function(token){
+ // summary: connects a handler by token from an event on this shape
+
+ // COULD BE RE-IMPLEMENTED BY THE RENDERER!
+
+ dojo.disconnect(token);
+ }
+};
+
+dojo.extend(dojox.gfx.Shape, dojox.gfx.shape._eventsProcessing);
+
+dojox.gfx.shape.Container = {
+ // summary: a container of shapes, which can be used
+ // as a foundation for renderer-specific groups, or as a way
+ // to logically group shapes (e.g, to propagate matricies)
+
+ _init: function() {
+ // children: Array: a list of children
+ this.children = [];
+ },
+
+ // group management
+
+ add: function(shape){
+ // summary: adds a shape to the list
+ // shape: dojox.gfx.Shape: a shape
+ var oldParent = shape.getParent();
+ if(oldParent){
+ oldParent.remove(shape, true);
+ }
+ this.children.push(shape);
+ return shape._setParent(this, this._getRealMatrix()); // self
+ },
+ remove: function(shape, silently){
+ // summary: removes a shape from the list
+ // silently: Boolean?: if true, do not redraw a picture yet
+ for(var i = 0; i < this.children.length; ++i){
+ if(this.children[i] == shape){
+ if(silently){
+ // skip for now
+ }else{
+ shape._setParent(null, null);
+ }
+ this.children.splice(i, 1);
+ break;
+ }
+ }
+ return this; // self
+ },
+ clear: function(){
+ // summary: removes all shapes from a group/surface
+ this.children = [];
+ return this; // self
+ },
+
+ // moving child nodes
+
+ _moveChildToFront: function(shape){
+ // summary: moves a shape to front of the list of shapes
+ for(var i = 0; i < this.children.length; ++i){
+ if(this.children[i] == shape){
+ this.children.splice(i, 1);
+ this.children.push(shape);
+ break;
+ }
+ }
+ return this; // self
+ },
+ _moveChildToBack: function(shape){
+ // summary: moves a shape to back of the list of shapes
+ for(var i = 0; i < this.children.length; ++i){
+ if(this.children[i] == shape){
+ this.children.splice(i, 1);
+ this.children.unshift(shape);
+ break;
+ }
+ }
+ return this; // self
+ }
+};
+
+dojo.declare("dojox.gfx.shape.Surface", null, {
+ // summary: a surface object to be used for drawings
+ constructor: function(){
+ // underlying node
+ this.rawNode = null;
+ },
+ getEventSource: function(){
+ // summary: returns a node, which can be used to attach event listeners
+ return this.rawNode; // Node
+ },
+ _getRealMatrix: function(){
+ // summary: always returns the identity matrix
+ return null; // dojox.gfx.Matrix2D
+ }
+});
+
+dojo.extend(dojox.gfx.shape.Surface, dojox.gfx.shape._eventsProcessing);
+
+dojo.declare("dojox.gfx.Point", null, {
+ // summary: a hypothetical 2D point to be used for drawings - {x, y}
+ // description: This object is defined for documentation purposes.
+ // You should use the naked object instead: {x: 1, y: 2}.
+});
+
+dojo.declare("dojox.gfx.Rectangle", null, {
+ // summary: a hypothetical rectangle - {x, y, width, height}
+ // description: This object is defined for documentation purposes.
+ // You should use the naked object instead: {x: 1, y: 2, width: 100, height: 200}.
+});
+
+dojo.declare("dojox.gfx.shape.Rect", dojox.gfx.Shape, {
+ // summary: a generic rectangle
+ constructor: function(rawNode) {
+ // rawNode: Node: a DOM Node
+ this.shape = dojo.clone(dojox.gfx.defaultRect);
+ this.rawNode = rawNode;
+ },
+ getBoundingBox: function(){
+ // summary: returns the bounding box (its shape in this case)
+ return this.shape; // dojox.gfx.Rectangle
+ }
+});
+
+dojo.declare("dojox.gfx.shape.Ellipse", dojox.gfx.Shape, {
+ // summary: a generic ellipse
+ constructor: function(rawNode) {
+ // rawNode: Node: a DOM Node
+ this.shape = dojo.clone(dojox.gfx.defaultEllipse);
+ this.rawNode = rawNode;
+ },
+ getBoundingBox: function(){
+ // summary: returns the bounding box
+ if(!this.bbox){
+ var shape = this.shape;
+ this.bbox = {x: shape.cx - shape.rx, y: shape.cy - shape.ry,
+ width: 2 * shape.rx, height: 2 * shape.ry};
+ }
+ return this.bbox; // dojox.gfx.Rectangle
+ }
+});
+
+dojo.declare("dojox.gfx.shape.Circle", dojox.gfx.Shape, {
+ // summary: a generic circle
+ // (this is a helper object, which is defined for convenience)
+ constructor: function(rawNode) {
+ // rawNode: Node: a DOM Node
+ this.shape = dojo.clone(dojox.gfx.defaultCircle);
+ this.rawNode = rawNode;
+ },
+ getBoundingBox: function(){
+ // summary: returns the bounding box
+ if(!this.bbox){
+ var shape = this.shape;
+ this.bbox = {x: shape.cx - shape.r, y: shape.cy - shape.r,
+ width: 2 * shape.r, height: 2 * shape.r};
+ }
+ return this.bbox; // dojox.gfx.Rectangle
+ }
+});
+
+dojo.declare("dojox.gfx.shape.Line", dojox.gfx.Shape, {
+ // summary: a generic line
+ // (this is a helper object, which is defined for convenience)
+ constructor: function(rawNode) {
+ // rawNode: Node: a DOM Node
+ this.shape = dojo.clone(dojox.gfx.defaultLine);
+ this.rawNode = rawNode;
+ },
+ getBoundingBox: function(){
+ // summary: returns the bounding box
+ if(!this.bbox){
+ var shape = this.shape;
+ this.bbox = {
+ x: Math.min(shape.x1, shape.x2),
+ y: Math.min(shape.y1, shape.y2),
+ width: Math.abs(shape.x2 - shape.x1),
+ height: Math.abs(shape.y2 - shape.y1)
+ };
+ }
+ return this.bbox; // dojox.gfx.Rectangle
+ }
+});
+
+dojo.declare("dojox.gfx.shape.Polyline", dojox.gfx.Shape, {
+ // summary: a generic polyline/polygon
+ // (this is a helper object, which is defined for convenience)
+ constructor: function(rawNode) {
+ // rawNode: Node: a DOM Node
+ this.shape = dojo.clone(dojox.gfx.defaultPolyline);
+ this.rawNode = rawNode;
+ },
+ setShape: function(points, closed){
+ // summary: sets a polyline/polygon shape object
+ // points: Object: a polyline/polygon shape object
+ // closed: Boolean: close the polyline to make a polygon
+ if(points && points instanceof Array){
+ // points: Array: an array of points
+ dojox.gfx.Shape.prototype.setShape.call(this, {points: points});
+ if(closed && this.shape.points.length){
+ this.shape.points.push(this.shape.points[0]);
+ }
+ }else{
+ dojox.gfx.Shape.prototype.setShape.call(this, points);
+ }
+ return this; // self
+ },
+ getBoundingBox: function(){
+ // summary: returns the bounding box
+ if(!this.bbox && this.shape.points.length){
+ var p = this.shape.points;
+ var l = p.length;
+ var t = p[0];
+ var bbox = {l: t.x, t: t.y, r: t.x, b: t.y};
+ for(var i = 1; i < l; ++i){
+ t = p[i];
+ if(bbox.l > t.x) bbox.l = t.x;
+ if(bbox.r < t.x) bbox.r = t.x;
+ if(bbox.t > t.y) bbox.t = t.y;
+ if(bbox.b < t.y) bbox.b = t.y;
+ }
+ this.bbox = {
+ x: bbox.l,
+ y: bbox.t,
+ width: bbox.r - bbox.l,
+ height: bbox.b - bbox.t
+ };
+ }
+ return this.bbox; // dojox.gfx.Rectangle
+ }
+});
+
+dojo.declare("dojox.gfx.shape.Image", dojox.gfx.Shape, {
+ // summary: a generic image
+ // (this is a helper object, which is defined for convenience)
+ constructor: function(rawNode) {
+ // rawNode: Node: a DOM Node
+ this.shape = dojo.clone(dojox.gfx.defaultImage);
+ this.rawNode = rawNode;
+ },
+ getBoundingBox: function(){
+ // summary: returns the bounding box (its shape in this case)
+ return this.shape; // dojox.gfx.Rectangle
+ },
+ setStroke: function(){
+ // summary: ignore setting a stroke style
+ return this; // self
+ },
+ setFill: function(){
+ // summary: ignore setting a fill style
+ return this; // self
+ }
+});
+
+dojo.declare("dojox.gfx.shape.Text", dojox.gfx.Shape, {
+ // summary: a generic text
+ constructor: function(rawNode) {
+ // rawNode: Node: a DOM Node
+ this.fontStyle = null;
+ this.shape = dojo.clone(dojox.gfx.defaultText);
+ this.rawNode = rawNode;
+ },
+ getFont: function(){
+ // summary: returns the current font object or null
+ return this.fontStyle; // Object
+ },
+ setFont: function(newFont){
+ // summary: sets a font for text
+ // newFont: Object: a font object (see dojox.gfx.defaultFont) or a font string
+ this.fontStyle = typeof newFont == "string" ? dojox.gfx.splitFontString(newFont) :
+ dojox.gfx.makeParameters(dojox.gfx.defaultFont, newFont);
+ this._setFont();
+ return this; // self
+ }
+});
+
+dojox.gfx.shape.Creator = {
+ // summary: shape creators
+ createShape: function(shape){
+ // summary: creates a shape object based on its type; it is meant to be used
+ // by group-like objects
+ // shape: Object: a shape descriptor object
+ switch(shape.type){
+ case dojox.gfx.defaultPath.type: return this.createPath(shape);
+ case dojox.gfx.defaultRect.type: return this.createRect(shape);
+ case dojox.gfx.defaultCircle.type: return this.createCircle(shape);
+ case dojox.gfx.defaultEllipse.type: return this.createEllipse(shape);
+ case dojox.gfx.defaultLine.type: return this.createLine(shape);
+ case dojox.gfx.defaultPolyline.type: return this.createPolyline(shape);
+ case dojox.gfx.defaultImage.type: return this.createImage(shape);
+ case dojox.gfx.defaultText.type: return this.createText(shape);
+ case dojox.gfx.defaultTextPath.type: return this.createTextPath(shape);
+ }
+ return null;
+ },
+ createGroup: function(){
+ // summary: creates an SVG group shape
+ return this.createObject(dojox.gfx.Group); // dojox.gfx.Group
+ },
+ createRect: function(rect){
+ // summary: creates an SVG rectangle shape
+ // rect: Object: a path object (see dojox.gfx.defaultRect)
+ return this.createObject(dojox.gfx.Rect, rect); // dojox.gfx.Rect
+ },
+ createEllipse: function(ellipse){
+ // summary: creates an SVG ellipse shape
+ // ellipse: Object: an ellipse object (see dojox.gfx.defaultEllipse)
+ return this.createObject(dojox.gfx.Ellipse, ellipse); // dojox.gfx.Ellipse
+ },
+ createCircle: function(circle){
+ // summary: creates an SVG circle shape
+ // circle: Object: a circle object (see dojox.gfx.defaultCircle)
+ return this.createObject(dojox.gfx.Circle, circle); // dojox.gfx.Circle
+ },
+ createLine: function(line){
+ // summary: creates an SVG line shape
+ // line: Object: a line object (see dojox.gfx.defaultLine)
+ return this.createObject(dojox.gfx.Line, line); // dojox.gfx.Line
+ },
+ createPolyline: function(points){
+ // summary: creates an SVG polyline/polygon shape
+ // points: Object: a points object (see dojox.gfx.defaultPolyline)
+ // or an Array of points
+ return this.createObject(dojox.gfx.Polyline, points); // dojox.gfx.Polyline
+ },
+ createImage: function(image){
+ // summary: creates an SVG image shape
+ // image: Object: an image object (see dojox.gfx.defaultImage)
+ return this.createObject(dojox.gfx.Image, image); // dojox.gfx.Image
+ },
+ createText: function(text){
+ // summary: creates an SVG text shape
+ // text: Object: a text object (see dojox.gfx.defaultText)
+ return this.createObject(dojox.gfx.Text, text); // dojox.gfx.Text
+ },
+ createPath: function(path){
+ // summary: creates an SVG path shape
+ // path: Object: a path object (see dojox.gfx.defaultPath)
+ return this.createObject(dojox.gfx.Path, path); // dojox.gfx.Path
+ },
+ createTextPath: function(text){
+ // summary: creates an SVG text shape
+ // text: Object: a textpath object (see dojox.gfx.defaultTextPath)
+ return this.createObject(dojox.gfx.TextPath, {}).setText(text); // dojox.gfx.TextPath
+ },
+ createObject: function(shapeType, rawShape){
+ // summary: creates an instance of the passed shapeType class
+ // shapeType: Function: a class constructor to create an instance of
+ // rawShape: Object: properties to be passed in to the classes "setShape" method
+
+ // SHOULD BE RE-IMPLEMENTED BY THE RENDERER!
+
+ return null; // dojox.gfx.Shape
+ }
+};
+
+}
diff --git a/includes/js/dojox/gfx/silverlight.js b/includes/js/dojox/gfx/silverlight.js
new file mode 100644
index 0000000..7a4becc
--- /dev/null
+++ b/includes/js/dojox/gfx/silverlight.js
@@ -0,0 +1,693 @@
+if(!dojo._hasResource["dojox.gfx.silverlight"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.silverlight"] = true;
+dojo.provide("dojox.gfx.silverlight");
+
+dojo.require("dojox.gfx._base");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+
+dojo.experimental("dojox.gfx.silverlight");
+
+dojox.gfx.silverlight.dasharray = {
+ solid: "none",
+ shortdash: [4, 1],
+ shortdot: [1, 1],
+ shortdashdot: [4, 1, 1, 1],
+ shortdashdotdot: [4, 1, 1, 1, 1, 1],
+ dot: [1, 3],
+ dash: [4, 3],
+ longdash: [8, 3],
+ dashdot: [4, 3, 1, 3],
+ longdashdot: [8, 3, 1, 3],
+ longdashdotdot: [8, 3, 1, 3, 1, 3]
+};
+
+dojox.gfx.silverlight.fontweight = {
+ normal: 400,
+ bold: 700
+};
+
+dojox.gfx.silverlight.caps = {butt: "Flat", round: "Round", square: "Square"};
+dojox.gfx.silverlight.joins = {bevel: "Bevel", round: "Round"};
+
+dojox.gfx.silverlight.fonts = {
+ serif: "Times New Roman",
+ times: "Times New Roman",
+ "sans-serif": "Arial",
+ helvetica: "Arial",
+ monotone: "Courier New",
+ courier: "Courier New"
+};
+
+dojox.gfx.silverlight.hexColor = function(/*String|Array|dojo.Color*/ color){
+ // summary: converts a color object to a Silverlight hex color string (#aarrggbb)
+ var c = dojox.gfx.normalizeColor(color),
+ t = c.toHex(), a = Math.round(c.a * 255);
+ a = (a < 0 ? 0 : a > 255 ? 255 : a).toString(16);
+ return "#" + (a.length < 2 ? "0" + a : a) + t.slice(1); // String
+};
+
+dojo.extend(dojox.gfx.Shape, {
+ // summary: Silverlight-specific implementation of dojox.gfx.Shape methods
+
+ setFill: function(fill){
+ // summary: sets a fill object (Silverlight)
+ // fill: Object: a fill object
+ // (see dojox.gfx.defaultLinearGradient,
+ // dojox.gfx.defaultRadialGradient,
+ // dojox.gfx.defaultPattern,
+ // or dojo.Color)
+
+ var p = this.rawNode.getHost().content, r = this.rawNode, f;
+ if(!fill){
+ // don't fill
+ this.fillStyle = null;
+ this._setFillAttr(null);
+ return this; // self
+ }
+ if(typeof(fill) == "object" && "type" in fill){
+ // gradient
+ switch(fill.type){
+ case "linear":
+ this.fillStyle = f = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill);
+ var lgb = p.createFromXaml("<LinearGradientBrush/>");
+ lgb.mappingMode = "Absolute";
+ lgb.startPoint = f.x1 + "," + f.y1;
+ lgb.endPoint = f.x2 + "," + f.y2;
+ dojo.forEach(f.colors, function(c){
+ var t = p.createFromXaml("<GradientStop/>");
+ t.offset = c.offset;
+ t.color = dojox.gfx.silverlight.hexColor(c.color);
+ lgb.gradientStops.add(t);
+ });
+ this._setFillAttr(lgb);
+ break;
+ case "radial":
+ this.fillStyle = f = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill);
+ var rgb = p.createFromXaml("<RadialGradientBrush/>"), w = r.width, h = r.height,
+ l = this.rawNode["Canvas.Left"], t = this.rawNode["Canvas.Top"];
+ rgb.center = (f.cx - l) / w + "," + (f.cy - t) / h;
+ rgb.radiusX = f.r / w;
+ rgb.radiusY = f.r / h;
+ dojo.forEach(f.colors, function(c){
+ var t = p.createFromXaml("<GradientStop/>");
+ t.offset = c.offset;
+ t.color = dojox.gfx.silverlight.hexColor(c.color);
+ rgb.gradientStops.add(t);
+ });
+ this._setFillAttr(rgb);
+ break;
+ case "pattern":
+ // don't fill: Silverlight doesn't define TileBrush for some reason
+ this.fillStyle = null;
+ this._setFillAttr(null);
+ break;
+ }
+ return this; // self
+ }
+ // color object
+ this.fillStyle = f = dojox.gfx.normalizeColor(fill);
+ var scb = p.createFromXaml("<SolidColorBrush/>");
+ scb.color = f.toHex();
+ scb.opacity = f.a;
+ this._setFillAttr(scb);
+ return this; // self
+ },
+ _setFillAttr: function(f){
+ this.rawNode.fill = f;
+ },
+
+ setStroke: function(stroke){
+ // summary: sets a stroke object (Silverlight)
+ // stroke: Object: a stroke object
+ // (see dojox.gfx.defaultStroke)
+
+ var p = this.rawNode.getHost().content, r = this.rawNode;
+ if(!stroke){
+ // don't stroke
+ this.strokeStyle = null;
+ r.stroke = null;
+ return this;
+ }
+ // normalize the stroke
+ if(typeof stroke == "string"){
+ stroke = {color: stroke};
+ }
+ var s = this.strokeStyle = dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke);
+ s.color = dojox.gfx.normalizeColor(s.color);
+ // generate attributes
+ if(s){
+ var scb = p.createFromXaml("<SolidColorBrush/>");
+ scb.color = s.color.toHex();
+ scb.opacity = s.color.a;
+ r.stroke = scb;
+ r.strokeThickness = s.width;
+ r.strokeStartLineCap = r.strokeEndLineCap = r.strokeDashCap =
+ dojox.gfx.silverlight.caps[s.cap];
+ if(typeof s.join == "number"){
+ r.strokeLineJoin = "Miter";
+ r.strokeMiterLimit = s.join;
+ }else{
+ r.strokeLineJoin = dojox.gfx.silverlight.joins[s.join];
+ }
+ var da = s.style.toLowerCase();
+ if(da in dojox.gfx.silverlight.dasharray){ da = dojox.gfx.silverlight.dasharray[da]; }
+ if(da instanceof Array){
+ da = dojo.clone(da);
+ /*
+ for(var i = 0; i < da.length; ++i){
+ da[i] *= s.width;
+ }
+ */
+ if(s.cap != "butt"){
+ for(var i = 0; i < da.length; i += 2){
+ //da[i] -= s.width;
+ --da[i]
+ if(da[i] < 1){ da[i] = 1; }
+ }
+ for(var i = 1; i < da.length; i += 2){
+ //da[i] += s.width;
+ ++da[i];
+ }
+ }
+ r.strokeDashArray = da.join(",");
+ }else{
+ r.strokeDashArray = null;
+ }
+ }
+ return this; // self
+ },
+
+ _getParentSurface: function(){
+ var surface = this.parent;
+ for(; surface && !(surface instanceof dojox.gfx.Surface); surface = surface.parent);
+ return surface;
+ },
+
+ _applyTransform: function() {
+ var tm = this.matrix, r = this.rawNode;
+ if(tm){
+ var p = this.rawNode.getHost().content,
+ m = p.createFromXaml("<MatrixTransform/>"),
+ mm = p.createFromXaml("<Matrix/>");
+ mm.m11 = tm.xx;
+ mm.m21 = tm.xy;
+ mm.m12 = tm.yx;
+ mm.m22 = tm.yy;
+ mm.offsetX = tm.dx;
+ mm.offsetY = tm.dy;
+ m.matrix = mm;
+ r.renderTransform = m;
+ }else{
+ r.renderTransform = null;
+ }
+ return this;
+ },
+
+ setRawNode: function(rawNode){
+ // summary:
+ // assigns and clears the underlying node that will represent this
+ // shape. Once set, transforms, gradients, etc, can be applied.
+ // (no fill & stroke by default)
+ rawNode.fill = null;
+ rawNode.stroke = null;
+ this.rawNode = rawNode;
+ },
+
+ // move family
+
+ _moveToFront: function(){
+ // summary: moves a shape to front of its parent's list of shapes (Silverlight)
+ var c = this.parent.rawNode.children, r = this.rawNode;
+ c.remove(r);
+ c.add(r);
+ return this; // self
+ },
+ _moveToBack: function(){
+ // summary: moves a shape to back of its parent's list of shapes (Silverlight)
+ var c = this.parent.rawNode.children, r = this.rawNode;
+ c.remove(r);
+ c.insert(0, r);
+ return this; // self
+ }
+});
+
+dojo.declare("dojox.gfx.Group", dojox.gfx.Shape, {
+ // summary: a group shape (Silverlight), which can be used
+ // to logically group shapes (e.g, to propagate matricies)
+ constructor: function(){
+ dojox.gfx.silverlight.Container._init.call(this);
+ },
+ setRawNode: function(rawNode){
+ // summary: sets a raw Silverlight node to be used by this shape
+ // rawNode: Node: an Silverlight node
+ this.rawNode = rawNode;
+ }
+});
+dojox.gfx.Group.nodeType = "Canvas";
+
+dojo.declare("dojox.gfx.Rect", dojox.gfx.shape.Rect, {
+ // summary: a rectangle shape (Silverlight)
+ setShape: function(newShape){
+ // summary: sets a rectangle shape object (Silverlight)
+ // newShape: Object: a rectangle shape object
+ this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ var r = this.rawNode, n = this.shape;
+ r["Canvas.Left"] = n.x;
+ r["Canvas.Top"] = n.y;
+ r.width = n.width;
+ r.height = n.height;
+ r.radiusX = r.radiusY = n.r;
+ return this; // self
+ }
+});
+dojox.gfx.Rect.nodeType = "Rectangle";
+
+dojo.declare("dojox.gfx.Ellipse", dojox.gfx.shape.Ellipse, {
+ // summary: an ellipse shape (Silverlight)
+ setShape: function(newShape){
+ // summary: sets an ellipse shape object (Silverlight)
+ // newShape: Object: an ellipse shape object
+ this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ var r = this.rawNode, n = this.shape;
+ r["Canvas.Left"] = n.cx - n.rx;
+ r["Canvas.Top"] = n.cy - n.ry;
+ r.width = 2 * n.rx;
+ r.height = 2 * n.ry;
+ return this; // self
+ }
+});
+dojox.gfx.Ellipse.nodeType = "Ellipse";
+
+dojo.declare("dojox.gfx.Circle", dojox.gfx.shape.Circle, {
+ // summary: a circle shape (Silverlight)
+ setShape: function(newShape){
+ // summary: sets a circle shape object (Silverlight)
+ // newShape: Object: a circle shape object
+ this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ var r = this.rawNode, n = this.shape;
+ r["Canvas.Left"] = n.cx - n.r;
+ r["Canvas.Top"] = n.cy - n.r;
+ r.width = r.height = 2 * n.r;
+ return this; // self
+ }
+});
+dojox.gfx.Circle.nodeType = "Ellipse";
+
+dojo.declare("dojox.gfx.Line", dojox.gfx.shape.Line, {
+ // summary: a line shape (Silverlight)
+ setShape: function(newShape){
+ // summary: sets a line shape object (Silverlight)
+ // newShape: Object: a line shape object
+ this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ var r = this.rawNode, n = this.shape;
+ r.x1 = n.x1; r.y1 = n.y1; r.x2 = n.x2; r.y2 = n.y2;
+ return this; // self
+ }
+});
+dojox.gfx.Line.nodeType = "Line";
+
+dojo.declare("dojox.gfx.Polyline", dojox.gfx.shape.Polyline, {
+ // summary: a polyline/polygon shape (Silverlight)
+ setShape: function(points, closed){
+ // summary: sets a polyline/polygon shape object (Silverlight)
+ // points: Object: a polyline/polygon shape object
+ if(points && points instanceof Array){
+ // branch
+ // points: Array: an array of points
+ this.shape = dojox.gfx.makeParameters(this.shape, {points: points});
+ if(closed && this.shape.points.length){
+ this.shape.points.push(this.shape.points[0]);
+ }
+ }else{
+ this.shape = dojox.gfx.makeParameters(this.shape, points);
+ }
+ this.box = null;
+ var p = this.shape.points, rp = [];
+ for(var i = 0; i < p.length; ++i){
+ if(typeof p[i] == "number"){
+ rp.push(p[i], p[++i]);
+ }else{
+ rp.push(p[i].x, p[i].y);
+ }
+ }
+ this.rawNode.points = rp.join(",");
+ return this; // self
+ }
+});
+dojox.gfx.Polyline.nodeType = "Polyline";
+
+dojo.declare("dojox.gfx.Image", dojox.gfx.shape.Image, {
+ // summary: an image (Silverlight)
+ setShape: function(newShape){
+ // summary: sets an image shape object (Silverlight)
+ // newShape: Object: an image shape object
+ this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ var r = this.rawNode, n = this.shape;
+ r["Canvas.Left"] = n.x;
+ r["Canvas.Top"] = n.y;
+ r.width = n.width;
+ r.height = n.height;
+ r.source = n.src;
+ return this; // self
+ },
+ setRawNode: function(rawNode){
+ // summary:
+ // assigns and clears the underlying node that will represent this
+ // shape. Once set, transforms, gradients, etc, can be applied.
+ // (no fill & stroke by default)
+ this.rawNode = rawNode;
+ }
+});
+dojox.gfx.Image.nodeType = "Image";
+
+dojo.declare("dojox.gfx.Text", dojox.gfx.shape.Text, {
+ // summary: an anchored text (Silverlight)
+ setShape: function(newShape){
+ // summary: sets a text shape object (Silverlight)
+ // newShape: Object: a text shape object
+ this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ var r = this.rawNode, s = this.shape;
+ r.text = s.text;
+ r.textDecorations = s.decoration == "underline" ? "Underline" : "None";
+ r["Canvas.Left"] = -10000;
+ r["Canvas.Top"] = -10000;
+ window.setTimeout(dojo.hitch(this, "_delayAlignment"), 0);
+ return this; // self
+ },
+ _delayAlignment: function(){
+ // handle alignment
+ var r = this.rawNode, s = this.shape,
+ w = r.actualWidth, h = r.actualHeight, x = s.x, y = s.y - h * 0.75;
+ switch(s.align){
+ case "middle":
+ x -= w / 2;
+ break;
+ case "end":
+ x -= w;
+ break;
+ }
+ var a = this.matrix ? dojox.gfx.matrix.multiplyPoint(this.matrix, x, y) : {x: x, y: y};
+ r["Canvas.Left"] = a.x;
+ r["Canvas.Top"] = a.y;
+ },
+ setStroke: function(){
+ // summary: ignore setting a stroke style
+ return this; // self
+ },
+ _setFillAttr: function(f){
+ this.rawNode.foreground = f;
+ },
+ setRawNode: function(rawNode){
+ // summary:
+ // assigns and clears the underlying node that will represent this
+ // shape. Once set, transforms, gradients, etc, can be applied.
+ // (no fill & stroke by default)
+ this.rawNode = rawNode;
+ },
+ _applyTransform: function() {
+ var tm = this.matrix, r = this.rawNode;
+ if(tm){
+ // the next line is pure magic :-(
+ tm = dojox.gfx.matrix.normalize([1/100, tm, 100]);
+ var p = this.rawNode.getHost().content,
+ m = p.createFromXaml("<MatrixTransform/>"),
+ mm = p.createFromXaml("<Matrix/>");
+ mm.m11 = tm.xx;
+ mm.m21 = tm.xy;
+ mm.m12 = tm.yx;
+ mm.m22 = tm.yy;
+ mm.offsetX = tm.dx;
+ mm.offsetY = tm.dy;
+ m.matrix = mm;
+ r.renderTransform = m;
+ }else{
+ r.renderTransform = null;
+ }
+ return this;
+ },
+ getTextWidth: function(){
+ // summary: get the text width in pixels
+ return this.rawNode.actualWidth;
+ }
+});
+dojox.gfx.Text.nodeType = "TextBlock";
+
+dojo.declare("dojox.gfx.Path", dojox.gfx.path.Path, {
+ // summary: a path shape (Silverlight)
+ _updateWithSegment: function(segment){
+ // summary: updates the bounding box of path with new segment
+ // segment: Object: a segment
+ dojox.gfx.Path.superclass._updateWithSegment.apply(this, arguments);
+ var p = this.shape.path;
+ if(typeof(p) == "string"){
+ this.rawNode.data = p ? p : null;
+ }
+ },
+ setShape: function(newShape){
+ // summary: forms a path using a shape (Silverlight)
+ // newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
+ dojox.gfx.Path.superclass.setShape.apply(this, arguments);
+ var p = this.shape.path;
+ this.rawNode.data = p ? p : null;
+ return this; // self
+ }
+});
+dojox.gfx.Path.nodeType = "Path";
+
+dojo.declare("dojox.gfx.TextPath", dojox.gfx.path.TextPath, {
+ // summary: a textpath shape (Silverlight)
+ _updateWithSegment: function(segment){
+ // summary: updates the bounding box of path with new segment
+ // segment: Object: a segment
+ },
+ setShape: function(newShape){
+ // summary: forms a path using a shape (Silverlight)
+ // newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
+ },
+ _setText: function(){
+ }
+});
+dojox.gfx.TextPath.nodeType = "text";
+
+dojo.declare("dojox.gfx.Surface", dojox.gfx.shape.Surface, {
+ // summary: a surface object to be used for drawings (Silverlight)
+ constructor: function(){
+ dojox.gfx.silverlight.Container._init.call(this);
+ },
+ setDimensions: function(width, height){
+ // summary: sets the width and height of the rawNode
+ // width: String: width of surface, e.g., "100px"
+ // height: String: height of surface, e.g., "100px"
+ this.width = dojox.gfx.normalizedLength(width); // in pixels
+ this.height = dojox.gfx.normalizedLength(height); // in pixels
+ var p = this.rawNode && this.rawNode.getHost();
+ if(p){
+ p.width = width;
+ p.height = height;
+ }
+ return this; // self
+ },
+ getDimensions: function(){
+ // summary: returns an object with properties "width" and "height"
+ var p = this.rawNode && this.rawNode.getHost();
+ var t = p ? {width: p.content.actualWidth, height: p.content.actualHeight} : null;
+ if(t.width <= 0){ t.width = this.width; }
+ if(t.height <= 0){ t.height = this.height; }
+ return t; // Object
+ }
+});
+
+dojox.gfx.silverlight.surfaces = {};
+
+dojox.gfx.createSurface = function(parentNode, width, height){
+ // summary: creates a surface (Silverlight)
+ // parentNode: Node: a parent node
+ // width: String: width of surface, e.g., "100px"
+ // height: String: height of surface, e.g., "100px"
+
+ var s = new dojox.gfx.Surface();
+ parentNode = dojo.byId(parentNode);
+ // create an empty canvas
+ var t = parentNode.ownerDocument.createElement("script");
+ t.type = "text/xaml";
+ t.id = dojox.gfx._base._getUniqueId();
+ t.text = "<Canvas xmlns='http://schemas.microsoft.com/client/2007' Name='" + dojox.gfx._base._getUniqueId() + "'/>";
+ document.body.appendChild(t);
+ // create a plugin
+ var pluginName = dojox.gfx._base._getUniqueId();
+ Silverlight.createObject(
+ "#" + t.id, // none
+ parentNode,
+ pluginName,
+ { // Plugin properties.
+ width: String(width), // Width of rectangular region of plugin in pixels.
+ height: String(height), // Height of rectangular region of plugin in pixels.
+ inplaceInstallPrompt: "false", // Determines whether to display in-place install prompt if invalid version detected.
+ //background: "white", // Background color of plugin.
+ //isWindowless: "false", // Determines whether to display plugin in Windowless mode.
+ background: "transparent", // Background color of plugin.
+ isWindowless: "true", // Determines whether to display plugin in Windowless mode.
+ framerate: "24", // MaxFrameRate property value.
+ version: "1.0" // Silverlight version.
+ },
+ {},
+ null,
+ null
+ );
+ s.rawNode = dojo.byId(pluginName).content.root;
+ // register the plugin with its parent node
+ dojox.gfx.silverlight.surfaces[s.rawNode.name] = parentNode;
+ s.width = dojox.gfx.normalizedLength(width); // in pixels
+ s.height = dojox.gfx.normalizedLength(height); // in pixels
+ return s; // dojox.gfx.Surface
+};
+
+// Extenders
+
+dojox.gfx.silverlight.Font = {
+ _setFont: function(){
+ // summary: sets a font object (Silverlight)
+ var f = this.fontStyle, r = this.rawNode,
+ fw = dojox.gfx.silverlight.fontweight,
+ fo = dojox.gfx.silverlight.fonts, t = f.family.toLowerCase();
+ r.fontStyle = f.style == "italic" ? "Italic" : "Normal";
+ r.fontWeight = f.weight in fw ? fw[f.weight] : f.weight;
+ r.fontSize = dojox.gfx.normalizedLength(f.size);
+ r.fontFamily = t in fo ? fo[t] : f.family;
+ }
+};
+
+dojox.gfx.silverlight.Container = {
+ _init: function(){
+ dojox.gfx.shape.Container._init.call(this);
+ },
+ add: function(shape){
+ // summary: adds a shape to a group/surface
+ // shape: dojox.gfx.Shape: an VML shape object
+ if(this != shape.getParent()){
+ //dojox.gfx.Group.superclass.add.apply(this, arguments);
+ //this.inherited(arguments);
+ dojox.gfx.shape.Container.add.apply(this, arguments);
+ this.rawNode.children.add(shape.rawNode);
+ }
+ return this; // self
+ },
+ remove: function(shape, silently){
+ // summary: remove a shape from a group/surface
+ // shape: dojox.gfx.Shape: an VML shape object
+ // silently: Boolean?: if true, regenerate a picture
+ if(this == shape.getParent()){
+ var parent = shape.rawNode.getParent();
+ if(parent){
+ parent.children.remove(shape.rawNode);
+ }
+ //dojox.gfx.Group.superclass.remove.apply(this, arguments);
+ //this.inherited(arguments);
+ dojox.gfx.shape.Container.remove.apply(this, arguments);
+ }
+ return this; // self
+ },
+ clear: function(){
+ // summary: removes all shapes from a group/surface
+ this.rawNode.children.clear();
+ //return this.inherited(arguments); // self
+ return dojox.gfx.shape.Container.clear.apply(this, arguments);
+ },
+ _moveChildToFront: dojox.gfx.shape.Container._moveChildToFront,
+ _moveChildToBack: dojox.gfx.shape.Container._moveChildToBack
+};
+
+dojo.mixin(dojox.gfx.shape.Creator, {
+ createObject: function(shapeType, rawShape){
+ // summary: creates an instance of the passed shapeType class
+ // shapeType: Function: a class constructor to create an instance of
+ // rawShape: Object: properties to be passed in to the classes "setShape" method
+ if(!this.rawNode){ return null; }
+ var shape = new shapeType();
+ var node = this.rawNode.getHost().content.createFromXaml("<" + shapeType.nodeType + "/>");
+ shape.setRawNode(node);
+ shape.setShape(rawShape);
+ this.add(shape);
+ return shape; // dojox.gfx.Shape
+ }
+});
+
+dojo.extend(dojox.gfx.Text, dojox.gfx.silverlight.Font);
+//dojo.extend(dojox.gfx.TextPath, dojox.gfx.silverlight.Font);
+
+dojo.extend(dojox.gfx.Group, dojox.gfx.silverlight.Container);
+dojo.extend(dojox.gfx.Group, dojox.gfx.shape.Creator);
+
+dojo.extend(dojox.gfx.Surface, dojox.gfx.silverlight.Container);
+dojo.extend(dojox.gfx.Surface, dojox.gfx.shape.Creator);
+
+(function(){
+ var surfaces = dojox.gfx.silverlight.surfaces;
+ var mouseFix = function(s, a){
+ var ev = {target: s, currentTarget: s,
+ preventDefault: function(){}, stopPropagation: function(){}};
+ if(a){
+ ev.ctrlKey = a.ctrl;
+ ev.shiftKey = a.shift;
+ var p = a.getPosition(null);
+ ev.x = ev.offsetX = ev.layerX = p.x;
+ ev.y = ev.offsetY = ev.layerY = p.y;
+ // calculate clientX and clientY
+ var parent = surfaces[s.getHost().content.root.name];
+ var t = dojo._abs(parent);
+ ev.clientX = t.x + p.x;
+ ev.clientY = t.y + p.y;
+ }
+ return ev;
+ };
+ var keyFix = function(s, a){
+ var ev = {
+ keyCode: a.platformKeyCode,
+ ctrlKey: a.ctrl,
+ shiftKey: a.shift
+ };
+ return ev;
+ };
+ var eventNames = {
+ onclick: {name: "MouseLeftButtonUp", fix: mouseFix},
+ onmouseenter: {name: "MouseEnter", fix: mouseFix},
+ onmouseleave: {name: "MouseLeave", fix: mouseFix},
+ onmousedown: {name: "MouseLeftButtonDown", fix: mouseFix},
+ onmouseup: {name: "MouseLeftButtonUp", fix: mouseFix},
+ onmousemove: {name: "MouseMove", fix: mouseFix},
+ onkeydown: {name: "KeyDown", fix: keyFix},
+ onkeyup: {name: "KeyUp", fix: keyFix}
+ };
+ var eventsProcessing = {
+ connect: function(name, object, method){
+ var token, n = name in eventNames ? eventNames[name] :
+ {name: name, fix: function(){ return {}; }};
+ if(arguments.length > 2){
+ token = this.getEventSource().addEventListener(n.name,
+ function(s, a){ dojo.hitch(object, method)(n.fix(s, a)); });
+ }else{
+ token = this.getEventSource().addEventListener(n.name,
+ function(s, a){ object(n.fix(s, a)); });
+ }
+ return {name: n.name, token: token};
+ },
+ disconnect: function(token){
+ this.getEventSource().removeEventListener(token.name, token.token);
+ }
+ };
+ dojo.extend(dojox.gfx.Shape, eventsProcessing);
+ dojo.extend(dojox.gfx.Surface, eventsProcessing);
+ dojox.gfx.equalSources = function(a, b){
+ return a && b && a.equals(b);
+ }
+
+})();
+
+}
diff --git a/includes/js/dojox/gfx/silverlight_attach.js b/includes/js/dojox/gfx/silverlight_attach.js
new file mode 100644
index 0000000..1f5cd90
--- /dev/null
+++ b/includes/js/dojox/gfx/silverlight_attach.js
@@ -0,0 +1,87 @@
+dojo.require("dojox.gfx.silverlight");
+
+dojo.experimental("dojox.gfx.silverlight_attach");
+
+(function(){
+ dojox.gfx.attachNode = function(node){
+ // summary: creates a shape from a Node
+ // node: Node: an Silverlight node
+ return null; // for now
+ if(!node) return null;
+ var s = null;
+ switch(node.tagName.toLowerCase()){
+ case dojox.gfx.Rect.nodeType:
+ s = new dojox.gfx.Rect(node);
+ break;
+ case dojox.gfx.Ellipse.nodeType:
+ if(node.width == node.height){
+ s = new dojox.gfx.Circle(node);
+ }else{
+ s = new dojox.gfx.Ellipse(node);
+ }
+ break;
+ case dojox.gfx.Polyline.nodeType:
+ s = new dojox.gfx.Polyline(node);
+ break;
+ case dojox.gfx.Path.nodeType:
+ s = new dojox.gfx.Path(node);
+ break;
+ case dojox.gfx.Line.nodeType:
+ s = new dojox.gfx.Line(node);
+ break;
+ case dojox.gfx.Image.nodeType:
+ s = new dojox.gfx.Image(node);
+ break;
+ case dojox.gfx.Text.nodeType:
+ s = new dojox.gfx.Text(node);
+ attachFont(s);
+ break;
+ default:
+ //console.debug("FATAL ERROR! tagName = " + node.tagName);
+ return null;
+ }
+ attachShape(s);
+ if(!(s instanceof dojox.gfx.Image)){
+ attachFill(s);
+ attachStroke(s);
+ }
+ attachTransform(s);
+ return s; // dojox.gfx.Shape
+ };
+
+ dojox.gfx.attachSurface = function(node){
+ // summary: creates a surface from a Node
+ // node: Node: an Silverlight node
+ return null; // dojox.gfx.Surface
+ };
+
+ var attachFill = function(rawNode){
+ // summary: deduces a fill style from a Node.
+ // rawNode: Node: an Silverlight node
+ return null; // Object
+ };
+
+ var attachStroke = function(rawNode){
+ // summary: deduces a stroke style from a Node.
+ // rawNode: Node: an SVG node
+ return null; // Object
+ };
+
+ var attachTransform = function(rawNode){
+ // summary: deduces a transformation matrix from a Node.
+ // rawNode: Node: an Silverlight node
+ return null; // dojox.gfx.matrix.Matrix
+ };
+
+ var attachFont = function(rawNode){
+ // summary: deduces a font style from a Node.
+ // rawNode: Node: an Silverlight node
+ return null; // Object
+ };
+
+ var attachShape = function(rawNode){
+ // summary: builds a shape from a Node.
+ // rawNode: Node: an Silverlight node
+ return null; // dojox.gfx.Shape
+ };
+})();
diff --git a/includes/js/dojox/gfx/svg.js b/includes/js/dojox/gfx/svg.js
new file mode 100644
index 0000000..5f6101c
--- /dev/null
+++ b/includes/js/dojox/gfx/svg.js
@@ -0,0 +1,638 @@
+if(!dojo._hasResource["dojox.gfx.svg"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.svg"] = true;
+dojo.provide("dojox.gfx.svg");
+
+dojo.require("dojox.gfx._base");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+
+dojox.gfx.svg.xmlns = {
+ xlink: "http://www.w3.org/1999/xlink",
+ svg: "http://www.w3.org/2000/svg"
+};
+
+dojox.gfx.svg.getRef = function(name){
+ // summary: returns a DOM Node specified by the name argument or null
+ // name: String: an SVG external reference
+ if(!name || name == "none") return null;
+ if(name.match(/^url\(#.+\)$/)){
+ return dojo.byId(name.slice(5, -1)); // Node
+ }
+ // alternative representation of a reference
+ if(name.match(/^#dojoUnique\d+$/)){
+ // we assume here that a reference was generated by dojox.gfx
+ return dojo.byId(name.slice(1)); // Node
+ }
+ return null; // Node
+};
+
+dojox.gfx.svg.dasharray = {
+ solid: "none",
+ shortdash: [4, 1],
+ shortdot: [1, 1],
+ shortdashdot: [4, 1, 1, 1],
+ shortdashdotdot: [4, 1, 1, 1, 1, 1],
+ dot: [1, 3],
+ dash: [4, 3],
+ longdash: [8, 3],
+ dashdot: [4, 3, 1, 3],
+ longdashdot: [8, 3, 1, 3],
+ longdashdotdot: [8, 3, 1, 3, 1, 3]
+};
+
+dojo.extend(dojox.gfx.Shape, {
+ // summary: SVG-specific implementation of dojox.gfx.Shape methods
+
+ setFill: function(fill){
+ // summary: sets a fill object (SVG)
+ // fill: Object: a fill object
+ // (see dojox.gfx.defaultLinearGradient,
+ // dojox.gfx.defaultRadialGradient,
+ // dojox.gfx.defaultPattern,
+ // or dojo.Color)
+
+ if(!fill){
+ // don't fill
+ this.fillStyle = null;
+ this.rawNode.setAttribute("fill", "none");
+ this.rawNode.setAttribute("fill-opacity", 0);
+ return this;
+ }
+ var f;
+ // FIXME: slightly magical. We're using the outer scope's "f", but setting it later
+ var setter = function(x){
+ // we assume that we're executing in the scope of the node to mutate
+ this.setAttribute(x, f[x].toFixed(8));
+ };
+ if(typeof(fill) == "object" && "type" in fill){
+ // gradient
+ switch(fill.type){
+ case "linear":
+ f = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill);
+ var gradient = this._setFillObject(f, "linearGradient");
+ dojo.forEach(["x1", "y1", "x2", "y2"], setter, gradient);
+ break;
+ case "radial":
+ f = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill);
+ var gradient = this._setFillObject(f, "radialGradient");
+ dojo.forEach(["cx", "cy", "r"], setter, gradient);
+ break;
+ case "pattern":
+ f = dojox.gfx.makeParameters(dojox.gfx.defaultPattern, fill);
+ var pattern = this._setFillObject(f, "pattern");
+ dojo.forEach(["x", "y", "width", "height"], setter, pattern);
+ break;
+ }
+ this.fillStyle = f;
+ return this;
+ }
+ // color object
+ var f = dojox.gfx.normalizeColor(fill);
+ this.fillStyle = f;
+ this.rawNode.setAttribute("fill", f.toCss());
+ this.rawNode.setAttribute("fill-opacity", f.a);
+ this.rawNode.setAttribute("fill-rule", "evenodd");
+ return this; // self
+ },
+
+ setStroke: function(stroke){
+ // summary: sets a stroke object (SVG)
+ // stroke: Object: a stroke object
+ // (see dojox.gfx.defaultStroke)
+
+ if(!stroke){
+ // don't stroke
+ this.strokeStyle = null;
+ this.rawNode.setAttribute("stroke", "none");
+ this.rawNode.setAttribute("stroke-opacity", 0);
+ return this;
+ }
+ // normalize the stroke
+ if(typeof stroke == "string"){
+ stroke = {color: stroke};
+ }
+ var s = this.strokeStyle = dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke);
+ s.color = dojox.gfx.normalizeColor(s.color);
+ // generate attributes
+ var rn = this.rawNode;
+ if(s){
+ rn.setAttribute("stroke", s.color.toCss());
+ rn.setAttribute("stroke-opacity", s.color.a);
+ rn.setAttribute("stroke-width", s.width);
+ rn.setAttribute("stroke-linecap", s.cap);
+ if(typeof s.join == "number"){
+ rn.setAttribute("stroke-linejoin", "miter");
+ rn.setAttribute("stroke-miterlimit", s.join);
+ }else{
+ rn.setAttribute("stroke-linejoin", s.join);
+ }
+ var da = s.style.toLowerCase();
+ if(da in dojox.gfx.svg.dasharray){ da = dojox.gfx.svg.dasharray[da]; }
+ if(da instanceof Array){
+ da = dojo.clone(da);
+ for(var i = 0; i < da.length; ++i){
+ da[i] *= s.width;
+ }
+ if(s.cap != "butt"){
+ for(var i = 0; i < da.length; i += 2){
+ da[i] -= s.width;
+ if(da[i] < 1){ da[i] = 1; }
+ }
+ for(var i = 1; i < da.length; i += 2){
+ da[i] += s.width;
+ }
+ }
+ da = da.join(",");
+ }
+ rn.setAttribute("stroke-dasharray", da);
+ rn.setAttribute("dojoGfxStrokeStyle", s.style);
+ }
+ return this; // self
+ },
+
+ _getParentSurface: function(){
+ var surface = this.parent;
+ for(; surface && !(surface instanceof dojox.gfx.Surface); surface = surface.parent);
+ return surface;
+ },
+
+ _setFillObject: function(f, nodeType){
+ var svgns = dojox.gfx.svg.xmlns.svg;
+ this.fillStyle = f;
+ var surface = this._getParentSurface(),
+ defs = surface.defNode,
+ fill = this.rawNode.getAttribute("fill"),
+ ref = dojox.gfx.svg.getRef(fill);
+ if(ref){
+ fill = ref;
+ if(fill.tagName.toLowerCase() != nodeType.toLowerCase()){
+ var id = fill.id;
+ fill.parentNode.removeChild(fill);
+ fill = document.createElementNS(svgns, nodeType);
+ fill.setAttribute("id", id);
+ defs.appendChild(fill);
+ }else{
+ while(fill.childNodes.length){
+ fill.removeChild(fill.lastChild);
+ }
+ }
+ }else{
+ fill = document.createElementNS(svgns, nodeType);
+ fill.setAttribute("id", dojox.gfx._base._getUniqueId());
+ defs.appendChild(fill);
+ }
+ if(nodeType == "pattern"){
+ if(dojo.isSafari){
+ fill.setAttributeNS(null, "patternUnits", "userSpaceOnUse");
+ }else{
+ fill.setAttribute("patternUnits", "userSpaceOnUse");
+ }
+ var img = document.createElementNS(svgns, "image");
+ img.setAttribute("x", 0);
+ img.setAttribute("y", 0);
+ img.setAttribute("width", f.width .toFixed(8));
+ img.setAttribute("height", f.height.toFixed(8));
+ img.setAttributeNS(dojox.gfx.svg.xmlns.xlink, "href", f.src);
+ fill.appendChild(img);
+ }else{
+ if(dojo.isSafari){
+ fill.setAttributeNS(null, "gradientUnits", "userSpaceOnUse");
+ }else{
+ fill.setAttribute("gradientUnits", "userSpaceOnUse");
+ }
+ for(var i = 0; i < f.colors.length; ++i){
+ var c = f.colors[i], t = document.createElementNS(svgns, "stop"),
+ cc = c.color = dojox.gfx.normalizeColor(c.color);
+ t.setAttribute("offset", c.offset.toFixed(8));
+ t.setAttribute("stop-color", cc.toCss());
+ t.setAttribute("stop-opacity", cc.a);
+ fill.appendChild(t);
+ }
+ }
+ this.rawNode.setAttribute("fill", "url(#" + fill.getAttribute("id") +")");
+ this.rawNode.removeAttribute("fill-opacity");
+ this.rawNode.setAttribute("fill-rule", "evenodd");
+ return fill;
+ },
+
+ _applyTransform: function() {
+ var matrix = this.matrix;
+ if(matrix){
+ var tm = this.matrix;
+ this.rawNode.setAttribute("transform", "matrix(" +
+ tm.xx.toFixed(8) + "," + tm.yx.toFixed(8) + "," +
+ tm.xy.toFixed(8) + "," + tm.yy.toFixed(8) + "," +
+ tm.dx.toFixed(8) + "," + tm.dy.toFixed(8) + ")");
+ }else{
+ this.rawNode.removeAttribute("transform");
+ }
+ return this;
+ },
+
+ setRawNode: function(rawNode){
+ // summary:
+ // assigns and clears the underlying node that will represent this
+ // shape. Once set, transforms, gradients, etc, can be applied.
+ // (no fill & stroke by default)
+ var r = this.rawNode = rawNode;
+ r.setAttribute("fill", "none");
+ r.setAttribute("fill-opacity", 0);
+ r.setAttribute("stroke", "none");
+ r.setAttribute("stroke-opacity", 0);
+ r.setAttribute("stroke-width", 1);
+ r.setAttribute("stroke-linecap", "butt");
+ r.setAttribute("stroke-linejoin", "miter");
+ r.setAttribute("stroke-miterlimit", 4);
+ },
+
+ setShape: function(newShape){
+ // summary: sets a shape object (SVG)
+ // newShape: Object: a shape object
+ // (see dojox.gfx.defaultPath,
+ // dojox.gfx.defaultPolyline,
+ // dojox.gfx.defaultRect,
+ // dojox.gfx.defaultEllipse,
+ // dojox.gfx.defaultCircle,
+ // dojox.gfx.defaultLine,
+ // or dojox.gfx.defaultImage)
+ this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ for(var i in this.shape){
+ if(i != "type"){ this.rawNode.setAttribute(i, this.shape[i]); }
+ }
+ return this; // self
+ },
+
+ // move family
+
+ _moveToFront: function(){
+ // summary: moves a shape to front of its parent's list of shapes (SVG)
+ this.rawNode.parentNode.appendChild(this.rawNode);
+ return this; // self
+ },
+ _moveToBack: function(){
+ // summary: moves a shape to back of its parent's list of shapes (SVG)
+ this.rawNode.parentNode.insertBefore(this.rawNode, this.rawNode.parentNode.firstChild);
+ return this; // self
+ }
+});
+
+dojo.declare("dojox.gfx.Group", dojox.gfx.Shape, {
+ // summary: a group shape (SVG), which can be used
+ // to logically group shapes (e.g, to propagate matricies)
+ constructor: function(){
+ dojox.gfx.svg.Container._init.call(this);
+ },
+ setRawNode: function(rawNode){
+ // summary: sets a raw SVG node to be used by this shape
+ // rawNode: Node: an SVG node
+ this.rawNode = rawNode;
+ }
+});
+dojox.gfx.Group.nodeType = "g";
+
+dojo.declare("dojox.gfx.Rect", dojox.gfx.shape.Rect, {
+ // summary: a rectangle shape (SVG)
+ setShape: function(newShape){
+ // summary: sets a rectangle shape object (SVG)
+ // newShape: Object: a rectangle shape object
+ this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ for(var i in this.shape){
+ if(i != "type" && i != "r"){ this.rawNode.setAttribute(i, this.shape[i]); }
+ }
+ if(this.shape.r){
+ this.rawNode.setAttribute("ry", this.shape.r);
+ this.rawNode.setAttribute("rx", this.shape.r);
+ }
+ return this; // self
+ }
+});
+dojox.gfx.Rect.nodeType = "rect";
+
+dojox.gfx.Ellipse = dojox.gfx.shape.Ellipse;
+dojox.gfx.Ellipse.nodeType = "ellipse";
+
+dojox.gfx.Circle = dojox.gfx.shape.Circle;
+dojox.gfx.Circle.nodeType = "circle";
+
+dojox.gfx.Line = dojox.gfx.shape.Line;
+dojox.gfx.Line.nodeType = "line";
+
+dojo.declare("dojox.gfx.Polyline", dojox.gfx.shape.Polyline, {
+ // summary: a polyline/polygon shape (SVG)
+ setShape: function(points, closed){
+ // summary: sets a polyline/polygon shape object (SVG)
+ // points: Object: a polyline/polygon shape object
+ if(points && points instanceof Array){
+ // branch
+ // points: Array: an array of points
+ this.shape = dojox.gfx.makeParameters(this.shape, { points: points });
+ if(closed && this.shape.points.length){
+ this.shape.points.push(this.shape.points[0]);
+ }
+ }else{
+ this.shape = dojox.gfx.makeParameters(this.shape, points);
+ }
+ this.box = null;
+ var attr = [], p = this.shape.points;
+ for(var i = 0; i < p.length; ++i){
+ if(typeof p[i] == "number"){
+ attr.push(p[i].toFixed(8));
+ }else{
+ attr.push(p[i].x.toFixed(8));
+ attr.push(p[i].y.toFixed(8));
+ }
+ }
+ this.rawNode.setAttribute("points", attr.join(" "));
+ return this; // self
+ }
+});
+dojox.gfx.Polyline.nodeType = "polyline";
+
+dojo.declare("dojox.gfx.Image", dojox.gfx.shape.Image, {
+ // summary: an image (SVG)
+ setShape: function(newShape){
+ // summary: sets an image shape object (SVG)
+ // newShape: Object: an image shape object
+ this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ var rawNode = this.rawNode;
+ for(var i in this.shape){
+ if(i != "type" && i != "src"){ rawNode.setAttribute(i, this.shape[i]); }
+ }
+ rawNode.setAttributeNS(dojox.gfx.svg.xmlns.xlink, "href", this.shape.src);
+ return this; // self
+ }
+});
+dojox.gfx.Image.nodeType = "image";
+
+dojo.declare("dojox.gfx.Text", dojox.gfx.shape.Text, {
+ // summary: an anchored text (SVG)
+ setShape: function(newShape){
+ // summary: sets a text shape object (SVG)
+ // newShape: Object: a text shape object
+ this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ var r = this.rawNode, s = this.shape;
+ r.setAttribute("x", s.x);
+ r.setAttribute("y", s.y);
+ r.setAttribute("text-anchor", s.align);
+ r.setAttribute("text-decoration", s.decoration);
+ r.setAttribute("rotate", s.rotated ? 90 : 0);
+ r.setAttribute("kerning", s.kerning ? "auto" : 0);
+ r.setAttribute("text-rendering", "optimizeLegibility");
+ r.textContent = s.text;
+ return this; // self
+ },
+ getTextWidth: function(){
+ // summary: get the text width in pixels
+ var rawNode = this.rawNode,
+ oldParent = rawNode.parentNode,
+ _measurementNode = rawNode.cloneNode(true);
+ _measurementNode.style.visibility = "hidden";
+
+ // solution to the "orphan issue" in FF
+ var _width = 0, _text = _measurementNode.firstChild.nodeValue;
+ oldParent.appendChild(_measurementNode);
+
+ // solution to the "orphan issue" in Opera
+ // (nodeValue == "" hangs firefox)
+ if(_text!=""){
+ while(!_width){
+ _width = parseInt(_measurementNode.getBBox().width);
+ }
+ }
+ oldParent.removeChild(_measurementNode);
+ return _width;
+ }
+});
+dojox.gfx.Text.nodeType = "text";
+
+dojo.declare("dojox.gfx.Path", dojox.gfx.path.Path, {
+ // summary: a path shape (SVG)
+ _updateWithSegment: function(segment){
+ // summary: updates the bounding box of path with new segment
+ // segment: Object: a segment
+ dojox.gfx.Path.superclass._updateWithSegment.apply(this, arguments);
+ if(typeof(this.shape.path) == "string"){
+ this.rawNode.setAttribute("d", this.shape.path);
+ }
+ },
+ setShape: function(newShape){
+ // summary: forms a path using a shape (SVG)
+ // newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
+ dojox.gfx.Path.superclass.setShape.apply(this, arguments);
+ this.rawNode.setAttribute("d", this.shape.path);
+ return this; // self
+ }
+});
+dojox.gfx.Path.nodeType = "path";
+
+dojo.declare("dojox.gfx.TextPath", dojox.gfx.path.TextPath, {
+ // summary: a textpath shape (SVG)
+ _updateWithSegment: function(segment){
+ // summary: updates the bounding box of path with new segment
+ // segment: Object: a segment
+ dojox.gfx.Path.superclass._updateWithSegment.apply(this, arguments);
+ this._setTextPath();
+ },
+ setShape: function(newShape){
+ // summary: forms a path using a shape (SVG)
+ // newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
+ dojox.gfx.Path.superclass.setShape.apply(this, arguments);
+ this._setTextPath();
+ return this; // self
+ },
+ _setTextPath: function(){
+ if(typeof this.shape.path != "string"){ return; }
+ var r = this.rawNode;
+ if(!r.firstChild){
+ var tp = document.createElementNS(dojox.gfx.svg.xmlns.svg, "textPath"),
+ tx = document.createTextNode("");
+ tp.appendChild(tx);
+ r.appendChild(tp);
+ }
+ var ref = r.firstChild.getAttributeNS(dojox.gfx.svg.xmlns.xlink, "href"),
+ path = ref && dojox.gfx.svg.getRef(ref);
+ if(!path){
+ var surface = this._getParentSurface();
+ if(surface){
+ var defs = surface.defNode;
+ path = document.createElementNS(dojox.gfx.svg.xmlns.svg, "path");
+ var id = dojox.gfx._base._getUniqueId();
+ path.setAttribute("id", id);
+ defs.appendChild(path);
+ r.firstChild.setAttributeNS(dojox.gfx.svg.xmlns.xlink, "href", "#" + id);
+ }
+ }
+ if(path){
+ path.setAttribute("d", this.shape.path);
+ }
+ },
+ _setText: function(){
+ var r = this.rawNode;
+ if(!r.firstChild){
+ var tp = document.createElementNS(dojox.gfx.svg.xmlns.svg, "textPath"),
+ tx = document.createTextNode("");
+ tp.appendChild(tx);
+ r.appendChild(tp);
+ }
+ r = r.firstChild;
+ var t = this.text;
+ r.setAttribute("alignment-baseline", "middle");
+ switch(t.align){
+ case "middle":
+ r.setAttribute("text-anchor", "middle");
+ r.setAttribute("startOffset", "50%");
+ break;
+ case "end":
+ r.setAttribute("text-anchor", "end");
+ r.setAttribute("startOffset", "100%");
+ break;
+ default:
+ r.setAttribute("text-anchor", "start");
+ r.setAttribute("startOffset", "0%");
+ break;
+ }
+ //r.parentNode.setAttribute("alignment-baseline", "central");
+ //r.setAttribute("dominant-baseline", "central");
+ r.setAttribute("baseline-shift", "0.5ex");
+ r.setAttribute("text-decoration", t.decoration);
+ r.setAttribute("rotate", t.rotated ? 90 : 0);
+ r.setAttribute("kerning", t.kerning ? "auto" : 0);
+ r.firstChild.data = t.text;
+ }
+});
+dojox.gfx.TextPath.nodeType = "text";
+
+dojo.declare("dojox.gfx.Surface", dojox.gfx.shape.Surface, {
+ // summary: a surface object to be used for drawings (SVG)
+ constructor: function(){
+ dojox.gfx.svg.Container._init.call(this);
+ },
+ setDimensions: function(width, height){
+ // summary: sets the width and height of the rawNode
+ // width: String: width of surface, e.g., "100px"
+ // height: String: height of surface, e.g., "100px"
+ if(!this.rawNode){ return this; }
+ this.rawNode.setAttribute("width", width);
+ this.rawNode.setAttribute("height", height);
+ return this; // self
+ },
+ getDimensions: function(){
+ // summary: returns an object with properties "width" and "height"
+ return this.rawNode ? {width: this.rawNode.getAttribute("width"), height: this.rawNode.getAttribute("height")} : null; // Object
+ }
+});
+
+dojox.gfx.createSurface = function(parentNode, width, height){
+ // summary: creates a surface (SVG)
+ // parentNode: Node: a parent node
+ // width: String: width of surface, e.g., "100px"
+ // height: String: height of surface, e.g., "100px"
+
+ var s = new dojox.gfx.Surface();
+ s.rawNode = document.createElementNS(dojox.gfx.svg.xmlns.svg, "svg");
+ s.rawNode.setAttribute("width", width);
+ s.rawNode.setAttribute("height", height);
+
+ var node = document.createElementNS(dojox.gfx.svg.xmlns.svg, "defs");
+ s.rawNode.appendChild(node);
+ s.defNode = node;
+
+ dojo.byId(parentNode).appendChild(s.rawNode);
+ return s; // dojox.gfx.Surface
+};
+
+// Extenders
+
+dojox.gfx.svg.Font = {
+ _setFont: function(){
+ // summary: sets a font object (SVG)
+ var f = this.fontStyle;
+ // next line doesn't work in Firefox 2 or Opera 9
+ //this.rawNode.setAttribute("font", dojox.gfx.makeFontString(this.fontStyle));
+ this.rawNode.setAttribute("font-style", f.style);
+ this.rawNode.setAttribute("font-variant", f.variant);
+ this.rawNode.setAttribute("font-weight", f.weight);
+ this.rawNode.setAttribute("font-size", f.size);
+ this.rawNode.setAttribute("font-family", f.family);
+ }
+};
+
+dojox.gfx.svg.Container = {
+ _init: function(){
+ dojox.gfx.shape.Container._init.call(this);
+ },
+ add: function(shape){
+ // summary: adds a shape to a group/surface
+ // shape: dojox.gfx.Shape: an VML shape object
+ if(this != shape.getParent()){
+ this.rawNode.appendChild(shape.rawNode);
+ //dojox.gfx.Group.superclass.add.apply(this, arguments);
+ //this.inherited(arguments);
+ dojox.gfx.shape.Container.add.apply(this, arguments);
+ }
+ return this; // self
+ },
+ remove: function(shape, silently){
+ // summary: remove a shape from a group/surface
+ // shape: dojox.gfx.Shape: an VML shape object
+ // silently: Boolean?: if true, regenerate a picture
+ if(this == shape.getParent()){
+ if(this.rawNode == shape.rawNode.parentNode){
+ this.rawNode.removeChild(shape.rawNode);
+ }
+ //dojox.gfx.Group.superclass.remove.apply(this, arguments);
+ //this.inherited(arguments);
+ dojox.gfx.shape.Container.remove.apply(this, arguments);
+ }
+ return this; // self
+ },
+ clear: function(){
+ // summary: removes all shapes from a group/surface
+ var r = this.rawNode;
+ while(r.lastChild){
+ r.removeChild(r.lastChild);
+ }
+ var d = this.defNode;
+ if(d){
+ while(d.lastChild){
+ d.removeChild(d.lastChild);
+ }
+ r.appendChild(d);
+ }
+ //return this.inherited(arguments); // self
+ return dojox.gfx.shape.Container.clear.apply(this, arguments);
+ },
+ _moveChildToFront: dojox.gfx.shape.Container._moveChildToFront,
+ _moveChildToBack: dojox.gfx.shape.Container._moveChildToBack
+};
+
+dojo.mixin(dojox.gfx.shape.Creator, {
+ // summary: SVG shape creators
+ createObject: function(shapeType, rawShape){
+ // summary: creates an instance of the passed shapeType class
+ // shapeType: Function: a class constructor to create an instance of
+ // rawShape: Object: properties to be passed in to the classes "setShape" method
+ if(!this.rawNode){ return null; }
+ var shape = new shapeType(),
+ node = document.createElementNS(dojox.gfx.svg.xmlns.svg, shapeType.nodeType);
+ shape.setRawNode(node);
+ this.rawNode.appendChild(node);
+ shape.setShape(rawShape);
+ this.add(shape);
+ return shape; // dojox.gfx.Shape
+ }
+});
+
+dojo.extend(dojox.gfx.Text, dojox.gfx.svg.Font);
+dojo.extend(dojox.gfx.TextPath, dojox.gfx.svg.Font);
+
+dojo.extend(dojox.gfx.Group, dojox.gfx.svg.Container);
+dojo.extend(dojox.gfx.Group, dojox.gfx.shape.Creator);
+
+dojo.extend(dojox.gfx.Surface, dojox.gfx.svg.Container);
+dojo.extend(dojox.gfx.Surface, dojox.gfx.shape.Creator);
+
+}
diff --git a/includes/js/dojox/gfx/svg_attach.js b/includes/js/dojox/gfx/svg_attach.js
new file mode 100644
index 0000000..7ec9ed8
--- /dev/null
+++ b/includes/js/dojox/gfx/svg_attach.js
@@ -0,0 +1,224 @@
+dojo.require("dojox.gfx.svg");
+
+dojo.experimental("dojox.gfx.svg_attach");
+
+(function(){
+ dojox.gfx.attachNode = function(node){
+ // summary: creates a shape from a Node
+ // node: Node: an SVG node
+ if(!node) return null;
+ var s = null;
+ switch(node.tagName.toLowerCase()){
+ case dojox.gfx.Rect.nodeType:
+ s = new dojox.gfx.Rect(node);
+ attachRect(s);
+ break;
+ case dojox.gfx.Ellipse.nodeType:
+ s = new dojox.gfx.Ellipse(node);
+ attachShape(s, dojox.gfx.defaultEllipse);
+ break;
+ case dojox.gfx.Polyline.nodeType:
+ s = new dojox.gfx.Polyline(node);
+ attachShape(s, dojox.gfx.defaultPolyline);
+ break;
+ case dojox.gfx.Path.nodeType:
+ s = new dojox.gfx.Path(node);
+ attachShape(s, dojox.gfx.defaultPath);
+ break;
+ case dojox.gfx.Circle.nodeType:
+ s = new dojox.gfx.Circle(node);
+ attachShape(s, dojox.gfx.defaultCircle);
+ break;
+ case dojox.gfx.Line.nodeType:
+ s = new dojox.gfx.Line(node);
+ attachShape(s, dojox.gfx.defaultLine);
+ break;
+ case dojox.gfx.Image.nodeType:
+ s = new dojox.gfx.Image(node);
+ attachShape(s, dojox.gfx.defaultImage);
+ break;
+ case dojox.gfx.Text.nodeType:
+ var t = node.getElementsByTagName("textPath");
+ if(t && t.length){
+ s = new dojox.gfx.TextPath(node);
+ attachShape(s, dojox.gfx.defaultPath);
+ attachTextPath(s);
+ }else{
+ s = new dojox.gfx.Text(node);
+ attachText(s);
+ }
+ attachFont(s);
+ break;
+ default:
+ //console.debug("FATAL ERROR! tagName = " + node.tagName);
+ return null;
+ }
+ if(!(s instanceof dojox.gfx.Image)){
+ attachFill(s);
+ attachStroke(s);
+ }
+ attachTransform(s);
+ return s; // dojox.gfx.Shape
+ };
+
+ dojox.gfx.attachSurface = function(node){
+ // summary: creates a surface from a Node
+ // node: Node: an SVG node
+ var s = new dojox.gfx.Surface();
+ s.rawNode = node;
+ var def_elems = node.getElementsByTagName("defs");
+ if(def_elems.length == 0){
+ return null; // dojox.gfx.Surface
+ }
+ s.defNode = def_elems[0];
+ return s; // dojox.gfx.Surface
+ };
+
+ var attachFill = function(object){
+ // summary: deduces a fill style from a node.
+ // object: dojox.gfx.Shape: an SVG shape
+ var fill = object.rawNode.getAttribute("fill");
+ if(fill == "none"){
+ object.fillStyle = null;
+ return;
+ }
+ var fillStyle = null, gradient = dojox.gfx.svg.getRef(fill);
+ if(ref){
+ switch(gradient.tagName.toLowerCase()){
+ case "lineargradient":
+ fillStyle = _getGradient(dojox.gfx.defaultLinearGradient, gradient);
+ dojo.forEach(["x1", "y1", "x2", "y2"], function(x){
+ fillStyle[x] = gradient.getAttribute(x);
+ });
+ break;
+ case "radialgradient":
+ fillStyle = _getGradient(dojox.gfx.defaultRadialGradient, gradient);
+ dojo.forEach(["cx", "cy", "r"], function(x){
+ fillStyle[x] = gradient.getAttribute(x);
+ });
+ fillStyle.cx = gradient.getAttribute("cx");
+ fillStyle.cy = gradient.getAttribute("cy");
+ fillStyle.r = gradient.getAttribute("r");
+ break;
+ case "pattern":
+ fillStyle = dojo.lang.shallowCopy(dojox.gfx.defaultPattern, true);
+ dojo.forEach(["x", "y", "width", "height"], function(x){
+ fillStyle[x] = gradient.getAttribute(x);
+ });
+ fillStyle.src = gradient.firstChild.getAttributeNS(dojox.gfx.svg.xmlns.xlink, "href");
+ break;
+ }
+ }else{
+ fillStyle = new dojo.Color(fill);
+ var opacity = rawNode.getAttribute("fill-opacity");
+ if(opacity != null){ fillStyle.a = opacity; }
+ }
+ object.fillStyle = fillStyle;
+ };
+
+ var _getGradient = function(defaultGradient, gradient){
+ var fillStyle = dojo.clone(defaultGradient);
+ fillStyle.colors = [];
+ for(var i = 0; i < gradient.childNodes.length; ++i){
+ fillStyle.colors.push({
+ offset: gradient.childNodes[i].getAttribute("offset"),
+ color: new dojo.Color(gradient.childNodes[i].getAttribute("stop-color"))
+ });
+ }
+ return fillStyle;
+ };
+
+ var attachStroke = function(object){
+ // summary: deduces a stroke style from a node.
+ // object: dojox.gfx.Shape: an SVG shape
+ var rawNode = object.rawNode, stroke = rawNode.getAttribute("stroke");
+ if(stroke == null || stroke == "none"){
+ object.strokeStyle = null;
+ return;
+ }
+ var strokeStyle = object.strokeStyle = dojo.clone(dojox.gfx.defaultStroke);
+ var color = new dojo.Color(stroke);
+ if(color){
+ strokeStyle.color = color;
+ strokeStyle.color.a = rawNode.getAttribute("stroke-opacity");
+ strokeStyle.width = rawNode.getAttribute("stroke-width");
+ strokeStyle.cap = rawNode.getAttribute("stroke-linecap");
+ strokeStyle.join = rawNode.getAttribute("stroke-linejoin");
+ if(strokeStyle.join == "miter"){
+ strokeStyle.join = rawNode.getAttribute("stroke-miterlimit");
+ }
+ strokeStyle.style = rawNode.getAttribute("dojoGfxStrokeStyle");
+ }
+ };
+
+ var attachTransform = function(object){
+ // summary: deduces a transformation matrix from a node.
+ // object: dojox.gfx.Shape: an SVG shape
+ var matrix = object.rawNode.getAttribute("transform");
+ if(matrix.match(/^matrix\(.+\)$/)){
+ var t = matrix.slice(7, -1).split(",");
+ object.matrix = dojox.gfx.matrix.normalize({
+ xx: parseFloat(t[0]), xy: parseFloat(t[2]),
+ yx: parseFloat(t[1]), yy: parseFloat(t[3]),
+ dx: parseFloat(t[4]), dy: parseFloat(t[5])
+ });
+ }else{
+ object.matrix = null;
+ }
+ };
+
+ var attachFont = function(object){
+ // summary: deduces a font style from a Node.
+ // object: dojox.gfx.Shape: an SVG shape
+ var fontStyle = object.fontStyle = dojo.clone(dojox.gfx.defaultFont),
+ r = object.rawNode;
+ fontStyle.style = r.getAttribute("font-style");
+ fontStyle.variant = r.getAttribute("font-variant");
+ fontStyle.weight = r.getAttribute("font-weight");
+ fontStyle.size = r.getAttribute("font-size");
+ fontStyle.family = r.getAttribute("font-family");
+ };
+
+ var attachShape = function(object, def){
+ // summary: builds a shape from a node.
+ // object: dojox.gfx.Shape: an SVG shape
+ // def: Object: a default shape template
+ var shape = object.shape = dojo.clone(def), r = object.rawNode;
+ for(var i in shape) {
+ shape[i] = r.getAttribute(i);
+ }
+ };
+
+ var attachRect = function(object){
+ // summary: builds a rectangle shape from a node.
+ // object: dojox.gfx.Shape: an SVG shape
+ attachShape(object, dojox.gfx.defaultRect);
+ object.shape.r = Math.min(object.rawNode.getAttribute("rx"), object.rawNode.getAttribute("ry"));
+ };
+
+ var attachText = function(object){
+ // summary: builds a text shape from a node.
+ // object: dojox.gfx.Shape: an SVG shape
+ var shape = object.shape = dojo.clone(dojox.gfx.defaultText),
+ r = object.rawNode;
+ shape.x = r.getAttribute("x");
+ shape.y = r.getAttribute("y");
+ shape.align = r.getAttribute("text-anchor");
+ shape.decoration = r.getAttribute("text-decoration");
+ shape.rotated = parseFloat(r.getAttribute("rotate")) != 0;
+ shape.kerning = r.getAttribute("kerning") == "auto";
+ shape.text = r.firstChild.nodeValue;
+ };
+
+ var attachTextPath = function(object){
+ // summary: builds a textpath shape from a node.
+ // object: dojox.gfx.Shape: an SVG shape
+ var shape = object.shape = dojo.clone(dojox.gfx.defaultTextPath),
+ r = object.rawNode;
+ shape.align = r.getAttribute("text-anchor");
+ shape.decoration = r.getAttribute("text-decoration");
+ shape.rotated = parseFloat(r.getAttribute("rotate")) != 0;
+ shape.kerning = r.getAttribute("kerning") == "auto";
+ shape.text = r.firstChild.nodeValue;
+ };
+})();
diff --git a/includes/js/dojox/gfx/tests/decompose.js b/includes/js/dojox/gfx/tests/decompose.js
new file mode 100644
index 0000000..b488bdd
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/decompose.js
@@ -0,0 +1,114 @@
+if(!dojo._hasResource["dojox.gfx.tests.decompose"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.tests.decompose"] = true;
+dojo.provide("dojox.gfx.tests.decompose");
+dojo.require("dojox.gfx.decompose");
+
+(function(){
+ var m = dojox.gfx.matrix;
+ var eq = function(t, a, b){ t.t(2 * Math.abs(a - b) / ((a < 1 && b < 1) ? 1 : a + b) < 1e-6); };
+ var eqM = function(t, a, b){
+ eq(t, a.xx, b.xx);
+ eq(t, a.yy, b.yy);
+ eq(t, a.xy, b.xy);
+ eq(t, a.yx, b.yx);
+ eq(t, a.dx, b.dx);
+ eq(t, a.dy, b.dy);
+ };
+ var compose = function(r){
+ return m.normalize([
+ m.translate(r.dx, r.dy),
+ m.rotate(r.angle2),
+ m.scale(r.sx, r.sy),
+ m.rotate(r.angle1)
+ ]);
+ };
+ var reconstruct = function(a){
+ return compose(dojox.gfx.decompose(a));
+ };
+ var compare = function(t, a){
+ var A = m.normalize(a);
+ eqM(t, A, reconstruct(A));
+ };
+ tests.register("dojox.gfx.tests.decompose", [
+ function IdentityTest(t){
+ compare(t, m.identity);
+ },
+ function FlipXTest(t){
+ compare(t, m.flipX);
+ },
+ function FlipYTest(t){
+ compare(t, m.flipY);
+ },
+ function FlipXYTest(t){
+ compare(t, m.flipXY);
+ },
+ function TranslationTest(t){
+ compare(t, m.translate(45, -15));
+ },
+ function RotationTest(t){
+ compare(t, m.rotateg(35));
+ },
+ function SkewXTest(t){
+ compare(t, m.skewXg(35));
+ },
+ function SkewYTest(t){
+ compare(t, m.skewYg(35));
+ },
+ function ReflectTest(t){
+ compare(t, m.reflect(13, 27));
+ },
+ function ProjectTest(t){
+ compare(t, m.project(13, 27));
+ },
+ function ScaleTest1(t){
+ compare(t, m.scale(3));
+ },
+ function ScaleTest2(t){
+ compare(t, m.scale(3, -1));
+ },
+ function ScaleTest3(t){
+ compare(t, m.scale(-3, 1));
+ },
+ function ScaleTest4(t){
+ compare(t, m.scale(-3, -1));
+ },
+ function ScaleRotateTest1(t){
+ compare(t, [m.scale(3), m.rotateAt(35, 13, 27)]);
+ },
+ function ScaleRotateTest2(t){
+ compare(t, [m.scale(3, -1), m.rotateAt(35, 13, 27)]);
+ },
+ function ScaleRotateTest3(t){
+ compare(t, [m.scale(-3, 1), m.rotateAt(35, 13, 27)]);
+ },
+ function ScaleRotateTest4(t){
+ compare(t, [m.scale(-3, -1), m.rotateAt(35, 13, 27)]);
+ },
+ function RotateScaleTest1(t){
+ compare(t, [m.rotateAt(35, 13, 27), m.scale(3)]);
+ },
+ function RotateScaleTest2(t){
+ compare(t, [m.rotateAt(35, 13, 27), m.scale(3, -1)]);
+ },
+ function RotateScaleTest3(t){
+ compare(t, [m.rotateAt(35, 13, 27), m.scale(-3, 1)]);
+ },
+ function RotateScaleTest4(t){
+ compare(t, [m.rotateAt(35, 13, 27), m.scale(-3, -1)]);
+ },
+ function RotateScaleRotateTest1(t){
+ compare(t, [m.rotateAt(35, 13, 27), m.scale(3), m.rotateAt(-15, 163, -287)]);
+ },
+ function RotateScaleRotateTest2(t){
+ compare(t, [m.rotateAt(35, 13, 27), m.scale(3, -1), m.rotateAt(-15, 163, -287)]);
+ },
+ function RotateScaleRotateTest3(t){
+ compare(t, [m.rotateAt(35, 13, 27), m.scale(-3, 1), m.rotateAt(-15, 163, -287)]);
+ },
+ function RotateScaleRotateTest4(t){
+ compare(t, [m.rotateAt(35, 13, 27), m.scale(-3, -1), m.rotateAt(-15, 163, -287)]);
+ }
+ ]);
+})();
+
+}
diff --git a/includes/js/dojox/gfx/tests/matrix.js b/includes/js/dojox/gfx/tests/matrix.js
new file mode 100644
index 0000000..282ec36
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/matrix.js
@@ -0,0 +1,228 @@
+if(!dojo._hasResource["dojox.gfx.tests.matrix"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.tests.matrix"] = true;
+dojo.provide("dojox.gfx.tests.matrix");
+dojo.require("dojox.gfx.matrix");
+
+(function(){
+ var m = dojox.gfx.matrix;
+ var eq = function(t, a, b){ t.t(2 * Math.abs(a - b) / ((a < 1 && b < 1) ? 1 : a + b) < 1e-6); };
+ tests.register("dojox.gfx.tests.matrix", [
+ function IdentityTest(t){
+ var a = new m.Matrix2D();
+ eq(t, a.xx, 1);
+ eq(t, a.yy, 1);
+ eq(t, a.xy, 0);
+ eq(t, a.yx, 0);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ },
+ function Rot30gTest(t){
+ var a = m.rotateg(30);
+ eq(t, a.xx, a.yy);
+ eq(t, a.xy, -a.yx);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ eq(t, a.yx, 0.5);
+ t.t(a.xy < 0);
+ t.t(a.yx > 0);
+ },
+ function Rot45gTest(t){
+ var a = m.rotateg(45);
+ eq(t, a.xx, a.yy);
+ eq(t, a.xy, -a.yx);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ eq(t, a.xx, a.yx);
+ eq(t, a.yy, -a.xy);
+ },
+ function Rot90gTest(t){
+ var a = m.rotateg(90);
+ eq(t, a.xx, a.yy);
+ eq(t, a.xy, -a.yx);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ eq(t, a.xx, 0);
+ eq(t, a.yx, 1);
+ },
+ function CombineIdentitiesTest(t){
+ var a = m.normalize([new m.Matrix2D(), new m.Matrix2D(), new m.Matrix2D()]);
+ eq(t, a.xx, 1);
+ eq(t, a.yy, 1);
+ eq(t, a.xy, 0);
+ eq(t, a.yx, 0);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ },
+ function CombineExclusiveTest(t){
+ var a = m.normalize([m.rotateg(30), m.rotateg(-30)]);
+ eq(t, a.xx, 1);
+ eq(t, a.yy, 1);
+ eq(t, a.xy, 0);
+ eq(t, a.yx, 0);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ },
+ function CombineInvertedTest(t){
+ var a = m.normalize([m.rotateg(30), m.invert(m.rotateg(30))]);
+ eq(t, a.xx, 1);
+ eq(t, a.yy, 1);
+ eq(t, a.xy, 0);
+ eq(t, a.yx, 0);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ },
+ function Rot90gAtTest(t){
+ var a = m.rotategAt(90, 10, 10);
+ eq(t, a.xx, a.yy);
+ eq(t, a.xy, -a.yx);
+ eq(t, a.dx, 20);
+ eq(t, a.dy, 0);
+ eq(t, a.xx, 0);
+ eq(t, a.yx, 1);
+ },
+ function MultPointTest1(t){
+ var b = m.multiplyPoint(m.rotategAt(90, 10, 10), 10, 10);
+ eq(t, b.x, 10);
+ eq(t, b.y, 10);
+ },
+ function MultPointTest2(t){
+ var b = m.multiplyPoint(m.rotategAt(90, 10, 10), {x: 10, y: 5});
+ eq(t, b.x, 15);
+ eq(t, b.y, 10);
+ },
+ function MultPointTest3(t){
+ var b = m.multiplyPoint(m.rotategAt(90, 10, 10), 10, 15);
+ eq(t, b.x, 5);
+ eq(t, b.y, 10);
+ },
+ function ScaleTest1(t){
+ var a = m.normalize([m.scale(2, 1), m.invert(m.rotateg(45))]);
+ eq(t, a.xx, 2 * a.yy);
+ eq(t, a.xy, -2 * a.yx);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ eq(t, a.xx, a.xy);
+ eq(t, a.yy, -a.yx);
+ },
+ function ScaleTest2(t){
+ var a = m.normalize([m.scale(1, 2), m.invert(m.rotateg(45))]);
+ eq(t, 2 * a.xx, a.yy);
+ eq(t, 2 * a.xy, -a.yx);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ eq(t, a.xx, a.xy);
+ eq(t, a.yy, -a.yx);
+ },
+ function ScaleTest3(t){
+ var a = m.normalize([m.rotateg(45), m.scale(2, 1)]);
+ eq(t, a.xx, 2 * a.yy);
+ eq(t, a.yx, -2 * a.xy);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ eq(t, a.xx, a.yx);
+ eq(t, a.yy, -a.xy);
+ },
+ function ScaleTest4(t){
+ var a = m.normalize([m.rotateg(45), m.scale(1, 2)]);
+ eq(t, 2 * a.xx, a.yy);
+ eq(t, 2 * a.yx, -a.xy);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ eq(t, a.xx, a.yx);
+ eq(t, a.yy, -a.xy);
+ },
+ function ScaleTest5(t){
+ var a = m.normalize([m.rotategAt(45, 100, 100), m.scale(2)]);
+ eq(t, a.xx, a.yy);
+ eq(t, a.xy, -a.yx);
+ eq(t, a.xx, a.yx);
+ eq(t, a.yy, -a.xy);
+ eq(t, a.dx, 100);
+ t.t(a.dy < 0);
+ var b = m.normalize([m.scale(2), m.rotategAt(45, 100, 100)]);
+ eq(t, b.xx, b.yy);
+ eq(t, b.xy, -b.yx);
+ eq(t, b.xx, b.yx);
+ eq(t, b.yy, -b.xy);
+ eq(t, b.dx, 200);
+ t.t(b.dy < 0);
+ eq(t, a.xx, b.xx);
+ eq(t, a.xy, b.xy);
+ eq(t, a.yx, b.yx);
+ eq(t, a.yy, b.yy);
+ eq(t, 2 * a.dx, b.dx);
+ eq(t, 2 * a.dy, b.dy);
+ var c = m.normalize([m.rotateg(45), m.scale(2)]);
+ eq(t, c.xx, c.yy);
+ eq(t, c.xy, -c.yx);
+ eq(t, c.xx, c.yx);
+ eq(t, c.yy, -c.xy);
+ eq(t, c.dx, 0);
+ eq(t, c.dy, 0);
+ var d = m.normalize([m.scale(2), m.rotateg(45)]);
+ eq(t, d.xx, d.yy);
+ eq(t, d.xy, -d.yx);
+ eq(t, d.xx, d.yx);
+ eq(t, d.yy, -d.xy);
+ eq(t, d.dx, 0);
+ eq(t, d.dy, 0);
+ eq(t, a.xx, c.xx);
+ eq(t, a.xy, c.xy);
+ eq(t, a.yx, c.yx);
+ eq(t, a.yy, c.yy);
+ eq(t, a.xx, d.xx);
+ eq(t, a.xy, d.xy);
+ eq(t, a.yx, d.yx);
+ eq(t, a.yy, d.yy);
+ },
+ function ScaleTest6(t){
+ var a = m.normalize(6);
+ eq(t, a.xx, 6);
+ eq(t, a.yy, 6);
+ eq(t, a.xy, 0);
+ eq(t, a.yx, 0);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ },
+ function ScaleTest7(t){
+ var a = m.normalize([2, m.scale(2, 1)]);
+ eq(t, a.xx, 4);
+ eq(t, a.yy, 2);
+ eq(t, a.xy, 0);
+ eq(t, a.yx, 0);
+ eq(t, a.dx, 0);
+ eq(t, a.dy, 0);
+ },
+ function TranslateTest(t){
+ var a = m.normalize({dx: 100, dy: 200});
+ eq(t, a.xx, 1);
+ eq(t, a.yy, 1);
+ eq(t, a.xy, 0);
+ eq(t, a.yx, 0);
+ eq(t, a.dx, 100);
+ eq(t, a.dy, 200);
+ },
+ function ReflectTest1(t){
+ var b = m.multiplyPoint(m.reflect(1, 1), 1, 0);
+ eq(t, b.x, 0);
+ eq(t, b.y, 1);
+ },
+ function ReflectTest2(t){
+ var b = m.multiplyPoint(m.reflect(1, 1), 0, 1);
+ eq(t, b.x, 1);
+ eq(t, b.y, 0);
+ },
+ function ProjectTest1(t){
+ var b = m.multiplyPoint(m.project(1, 1), 1, 0);
+ eq(t, b.x, 0.5);
+ eq(t, b.y, 0.5);
+ },
+ function ProjectTest2(t){
+ var b = m.multiplyPoint(m.project(1, 1), 0, 1);
+ eq(t, b.x, 0.5);
+ eq(t, b.y, 0.5);
+ }
+ ]);
+})();
+
+}
diff --git a/includes/js/dojox/gfx/tests/module.js b/includes/js/dojox/gfx/tests/module.js
new file mode 100644
index 0000000..0790b6b
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/module.js
@@ -0,0 +1,13 @@
+if(!dojo._hasResource["dojox.gfx.tests.module"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.tests.module"] = true;
+dojo.provide("dojox.gfx.tests.module");
+
+try{
+ dojo.require("dojox.gfx.tests.matrix");
+ dojo.require("dojox.gfx.tests.decompose");
+}catch(e){
+ doh.debug(e);
+}
+
+
+}
diff --git a/includes/js/dojox/gfx/tests/runTests.html b/includes/js/dojox/gfx/tests/runTests.html
new file mode 100644
index 0000000..4e13179
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <title>Dojox Unit Test Runner</title>
+ <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dojox.gfx.tests.module"></HEAD>
+ <BODY>
+ Redirecting to D.O.H runner.
+ </BODY>
+</HTML>
diff --git a/includes/js/dojox/gfx/tests/test_arc.html b/includes/js/dojox/gfx/tests/test_arc.html
new file mode 100644
index 0000000..f7fc589
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_arc.html
@@ -0,0 +1,71 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Testing arc</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../_base.js"></script>
+<script type="text/javascript" src="../shape.js"></script>
+<script type="text/javascript" src="../path.js"></script>
+<script type="text/javascript" src="../arc.js"></script>
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../canvas.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+makeShapes = function(){
+ var surface = dojox.gfx.createSurface("test", 500, 500);
+
+ var m = dojox.gfx.matrix;
+ var g1 = surface.createGroup();
+ var g2 = g1.createGroup();
+
+ var rx = 100, ry = 60, xRotg = -30;
+ var startPoint = m.multiplyPoint(m.rotateg(xRotg), {x: -rx, y: 0 });
+ var endPoint = m.multiplyPoint(m.rotateg(xRotg), {x: 0, y: -ry});
+
+ var re1 = g1.createPath()
+ .moveTo(startPoint)
+ .arcTo(rx, ry, xRotg, true, false, endPoint)
+ .setStroke({color: "red", width: 3})
+ ;
+ var ge1 = g1.createPath()
+ .moveTo(re1.getLastPosition())
+ .arcTo(rx, ry, xRotg, false, false, startPoint)
+ .setStroke({color: "black"})
+ ;
+ var re2 = g2.createPath()
+ .moveTo(startPoint)
+ .arcTo(rx, ry, xRotg, false, true, endPoint)
+ .setStroke({color: "green", width: 3})
+ ;
+ var ge2 = g2.createPath()
+ .moveTo(re2.getLastPosition())
+ .arcTo(rx, ry, xRotg, true, true, startPoint)
+ .setStroke({color: "black"})
+ ;
+
+ g1.setTransform({dx: 200, dy: 200});
+ g2.setTransform({dx: 10, dy: 10});
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+<h1>Testing arc</h1>
+<!--<p><button onclick="makeShapes();">Go</button></p>-->
+<div id="test" style="width: 500px; height: 500px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_bezier.html b/includes/js/dojox/gfx/tests/test_bezier.html
new file mode 100644
index 0000000..bcee2d0
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_bezier.html
@@ -0,0 +1,85 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Approximation of an arc with bezier</title>
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../_base.js"></script>
+<script type="text/javascript" src="../shape.js"></script>
+<script type="text/javascript" src="../path.js"></script>
+<script type="text/javascript" src="../arc.js"></script>
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../canvas.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+makeShapes = function(){
+ var surface = dojox.gfx.createSurface("test", 500, 300);
+ var g = surface.createGroup();
+
+ // create a reference ellipse
+ var rx = 200;
+ var ry = 100;
+ var startAngle = -30;
+ var arcAngle = -90;
+ var axisAngle = -30;
+ var e = g.createEllipse({rx: rx, ry: ry}).setStroke({});
+
+ // calculate a bezier
+ var alpha = dojox.gfx.matrix._degToRad(arcAngle) / 2; // half of our angle
+ var cosa = Math.cos(alpha);
+ var sina = Math.sin(alpha);
+ // start point
+ var p1 = {x: cosa, y: sina};
+ // 1st control point
+ var p2 = {x: cosa + (4 / 3) * (1 - cosa), y: sina - (4 / 3) * cosa * (1 - cosa) / sina};
+ // 2nd control point (symmetric to the 1st one)
+ var p3 = {x: p2.x, y: -p2.y};
+ // end point (symmetric to the start point)
+ var p4 = {x: p1.x, y: -p1.y};
+
+ // rotate and scale poins as appropriate
+ var s = dojox.gfx.matrix.normalize([dojox.gfx.matrix.scale(e.shape.rx, e.shape.ry), dojox.gfx.matrix.rotateg(startAngle + arcAngle / 2)]);
+ p1 = dojox.gfx.matrix.multiplyPoint(s, p1);
+ p2 = dojox.gfx.matrix.multiplyPoint(s, p2);
+ p3 = dojox.gfx.matrix.multiplyPoint(s, p3);
+ p4 = dojox.gfx.matrix.multiplyPoint(s, p4);
+ // draw control trapezoid
+ var t = g.createPath().setStroke({color: "blue"});
+ t.moveTo(p1.x, p1.y);
+ t.lineTo(p2.x, p2.y);
+ t.lineTo(p3.x, p3.y);
+ t.lineTo(p4.x, p4.y);
+ t.lineTo(p1.x, p1.y);
+ t.moveTo((p1.x + p4.x) / 2, (p1.y + p4.y) / 2);
+ t.lineTo((p2.x + p3.x) / 2, (p2.y + p3.y) / 2);
+ t.moveTo((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
+ t.lineTo((p3.x + p4.x) / 2, (p3.y + p4.y) / 2);
+ // draw a bezier
+ var b = g.createPath().setStroke({color: "red"});
+ b.moveTo(p1.x, p1.y);
+ b.curveTo(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
+ // move everything in a middle
+ g.setTransform([dojox.gfx.matrix.translate(250, 150), dojox.gfx.matrix.rotateg(axisAngle)]);
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+<h1>Approximation of an arc with bezier</h1>
+<!--<p><button onclick="makeShapes();">Make</button></p>-->
+<div id="test" style="width: 500px; height: 300px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_decompose.html b/includes/js/dojox/gfx/tests/test_decompose.html
new file mode 100644
index 0000000..6291cc2
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_decompose.html
@@ -0,0 +1,54 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Testing decompose</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../matrix.js"></script>
+<script type="text/javascript" src="../decompose.js"></script>
+<script type="text/javascript">
+dojo.require("dojox.gfx.decompose");
+
+var m = dojox.gfx.matrix;
+
+var eq = function(a, b){
+ return Math.abs((a - b) / (a + b)) < 1e-6;
+};
+
+var calc = function(){
+ var matrix1 = eval("(m.normalize([" + dojo.byId("input").value + "]))");
+ dojo.byId("matrix1").value = dojo.toJson(matrix1, true);
+ var result = dojox.gfx.decompose(matrix1);
+ dojo.byId("result").innerHTML = "Result: " + dojo.toJson(result);
+ var matrix2 = m.normalize([
+ m.translate(result.dx, result.dy),
+ m.rotate(result.angle2),
+ m.scale(result.sx, result.sy),
+ m.rotate(result.angle1)
+ ]);
+ dojo.byId("matrix2").value = dojo.toJson(matrix2, true);
+};
+
+</script>
+</head>
+<body>
+ <h1>Testing decompose</h1>
+ <p>
+ <span style="font-size: 8pt;">Example: m.rotategAt(30, 100, 100), m.scaleAt(2, 3, 5, 5), m.rotate(45)</span><br />
+ <input id="input" type="text" size="50" maxlength="200" /><button onclick="calc();">Calc</button>
+ </p>
+ <p id="result">Result:</p>
+ <p>
+ <span style="font-size: 8pt;">Original matrix</span><br />
+ <textarea id="matrix1" cols="50" rows="8" readonly="readonly"></textarea>
+ </p>
+ <p>
+ <span style="font-size: 8pt;">Decomposed matrix</span><br />
+ <textarea id="matrix2" cols="50" rows="8" readonly="readonly"></textarea>
+ </p>
+ <p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_fill.html b/includes/js/dojox/gfx/tests/test_fill.html
new file mode 100644
index 0000000..84827ea
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_fill.html
@@ -0,0 +1,47 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Testing fill rule</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<!--<script type="text/javascript" src="../_base.js"></script>-->
+<!--<script type="text/javascript" src="../shape.js"></script>-->
+<!--<script type="text/javascript" src="../path.js"></script>-->
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+makeShapes = function(){
+ var surface = dojox.gfx.createSurface("test", 500, 500);
+ var path = surface.createPath("");
+ // form concentric circles
+ var center = {x: 250, y: 250};
+ for(var r = 200; r > 0; r -= 30){
+ // make two 180 degree arcs to form a circle
+ var start = {x: center.x, y: center.y - r};
+ var end = {x: center.x, y: center.y + r};
+ path.moveTo(start).arcTo(r, r, 0, true, true, end).arcTo(r, r, 0, true, true, start).closePath();
+ }
+ // set visual attributes
+ path.setFill("red").setStroke("black");
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+ <h1>Testing fill rule</h1>
+<div id="test" style="width: 500px; height: 500px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_fx.html b/includes/js/dojox/gfx/tests/test_fx.html
new file mode 100644
index 0000000..c7b5b81
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_fx.html
@@ -0,0 +1,113 @@
+<!doctype html>
+<html>
+<head>
+<title>Testing animation</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<!--
+<script type="text/javascript" src="../_base.js"></script>
+<script type="text/javascript" src="../shape.js"></script>
+<script type="text/javascript" src="../path.js"></script>
+<script type="text/javascript" src="../arc.js"></script>
+<script type="text/javascript" src="../fx.js"></script>
+-->
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../canvas.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.fx");
+dojo.require("dojo.colors");
+
+var rect, text;
+
+var makeShapes = function(){
+ var surface = dojox.gfx.createSurface("test", 500, 500);
+ rect = surface.createRect({x: 100, y: 100, width: 300, height: 300})
+ .setFill("yellow").setStroke({
+ color: "green",
+ width: 5,
+ join: "round"
+ });
+ text = surface.createText({x: 250, y: 250, text: "Hello!", align: "middle"})
+ .setFill("black").setFont({family: "serif", size: "10pt"});
+};
+
+dojo.addOnLoad(makeShapes);
+
+var animateStroke = function(){
+ var anim = dojox.gfx.fx.animateStroke({
+ duration: 5000,
+ shape: rect,
+ color: {start: "green", end: "red"},
+ width: {start: 5, end: 15},
+ join: {values: ["miter", "bevel", "round"]}
+ });
+ dojo.byId("stroke").disabled = "disabled";
+ dojo.connect(anim, "onEnd", function(){ dojo.byId("stroke").disabled = ""; });
+ anim.play();
+};
+
+var animateFill = function(){
+ var anim = dojox.gfx.fx.animateFill({
+ duration: 5000,
+ shape: rect,
+ color: {start: "yellow", end: "blue"}
+ });
+ dojo.byId("fill").disabled = "disabled";
+ dojo.connect(anim, "onEnd", function(){ dojo.byId("fill").disabled = ""; });
+ anim.play();
+};
+
+var animateFont = function(){
+ var anim = dojox.gfx.fx.animateFont({
+ duration: 5000,
+ shape: text,
+ variant: {values: ["normal", "small-caps"]},
+ size: {start: 10, end: 50, unit: "pt"}
+ });
+ dojo.byId("font").disabled = "disabled";
+ dojo.connect(anim, "onEnd", function(){ dojo.byId("font").disabled = ""; });
+ anim.play();
+};
+
+var animateTransform = function(){
+ var anim = dojox.gfx.fx.animateTransform({
+ duration: 5000,
+ shape: text,
+ transform: [
+ {name: "rotategAt", start: [0, 250, 250], end: [360, 350, 350]},
+ {name: "translate", start: [0, 0], end: [100, 100]}
+ ]
+ });
+ dojo.byId("transform").disabled = "disabled";
+ dojo.connect(anim, "onEnd", function(){ dojo.byId("transform").disabled = ""; });
+ anim.play();
+};
+</script>
+</head>
+<body>
+<h1>Testing animation</h1>
+<p>
+ <button id="stroke" onclick="animateStroke();">Stroke</button>
+ &nbsp;
+ <button id="fill" onclick="animateFill();">Fill</button>
+ &nbsp;
+ <button id="font" onclick="animateFont();">Font</button>
+ &nbsp;
+ <button id="transform" onclick="animateTransform();">Transform</button>
+</p>
+<div id="test" style="width: 500px; height: 500px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_gfx.html b/includes/js/dojox/gfx/tests/test_gfx.html
new file mode 100644
index 0000000..6d2bef3
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_gfx.html
@@ -0,0 +1,489 @@
+<html>
+<head>
+<title>Dojo Unified 2D Graphics</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, gfxRenderer: 'svg,silverlight,vml'"></script>
+<!--<script type="text/javascript" src="../_base.js"></script>-->
+<!--<script type="text/javascript" src="../path.js"></script>-->
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+
+dojo.require("dojox.gfx");
+
+var gTestContainer = null;
+var gTests = {};
+
+function isEqual(foo, bar, prefix)
+{
+ var flag = true;
+ if( foo != bar ) {
+ console.debug(prefix+":"+foo + "!=" + bar + " try dig into it" );
+ if( foo instanceof Array ) {
+ for( var i = 0; i< foo.length; i++ ) {
+ flag = isEqual(foo[i], bar[i], prefix+"["+i+"]") && flag;
+ }
+ flag = false;
+ } else {
+ for(var x in foo) {
+ if(bar[x] != undefined ) {
+ flag = isEqual(foo[x], bar[x], prefix+"."+x) && flag;
+ } else {
+ console.debug(prefix+":"+ x + " is undefined in bar" );
+ flag = false;
+ }
+ }
+ }
+ }
+ return flag;
+}
+
+
+function getTestSurface(testName, testDescription, width, height)
+{
+ width = width ? width : 300;
+ height = height ? height : 300;
+
+ // Create a DOM node for the surface
+ var testRow = document.createElement('tr');
+ var testCell = document.createElement('td');
+ var testHolder = document.createElement('div');
+ testHolder.id = testName + '_holder';
+ testHolder.style.width = width;
+ testHolder.style.height = height;
+
+ testCell.appendChild(testHolder);
+ testRow.appendChild(testCell);
+ gTestContainer.appendChild(testRow);
+
+ var descRow = document.createElement('tr');
+ var desc = document.createElement('td');
+ desc.innerHTML = testDescription;
+ descRow.appendChild(desc);
+ gTestContainer.appendChild(descRow);
+
+ return dojox.gfx.createSurface(testHolder, width, height);
+}
+
+function addTest(testName, fn)
+{
+ gTests[testName] = fn;
+}
+
+function runTest_nodebug(testName)
+{
+ try {
+ var t = gTests[testName];
+ if (!t) {
+ return 'no test named ' + t;
+ }
+ t(testName);
+ return null; // the success condition
+ } catch (e) {
+ return e.message;
+ }
+}
+
+function runTest_debug(testName)
+{
+ var t = gTests[testName];
+ if (!t) {
+ return 'no test named ' + t;
+ }
+ t(testName);
+ return null; // the success condition
+}
+
+var runTest = djConfig.isDebug ? runTest_debug : runTest_nodebug;
+
+dojo.addOnLoad(function()
+{
+ gTestContainer = dojo.byId('testcontainer');
+ var rect = { x: 0, y: 0, width: 100, height: 100 };
+
+ addTest('rect', function(testName){
+ var surface = getTestSurface(testName, 'translucent rect with rounded stroke');
+ var red_rect = surface.createRect(rect);
+ red_rect.setFill([255, 0, 0, 0.5]);
+ red_rect.setStroke({color: "blue", width: 10, join: "round" });
+ red_rect.setTransform({dx: 100, dy: 100});
+ //dojo.connect(red_rect.getNode(), "onclick", function(){ alert("red"); });
+ red_rect.connect("onclick", function(){ alert("red"); });
+ });
+
+ addTest('straight_rect', function(testName){
+ var surface = getTestSurface(testName, 'translucent rect with no stroke');
+ var blue_rect = surface.createRect(rect).setFill([0, 255, 0, 0.5]).setTransform({ dx: 100, dy: 100 });
+ //dojo.connect( blue_rect.getNode(), "onclick", function(){ blue_rect.setShape({width: blue_rect.getShape().width + 20}); });
+ blue_rect.connect("onclick", function(){ blue_rect.setShape({width: blue_rect.getShape().width + 20}); });
+ });
+
+ addTest('rotated_rect', function(testName){
+ var surface = getTestSurface(testName, '30g CCW blue translucent rounded rect');
+ console.debug('rotated_rect');
+ // anonymous 30 degree CCW rotated green rectangle
+ surface.createRect({r: 20})
+ .setFill([0, 0, 255, 0.5])
+ // rotate it around its center and move to (100, 100)
+ .setTransform([dojox.gfx.matrix.translate(100, 100), dojox.gfx.matrix.rotategAt(-30, 0, 0)])
+ ;
+ });
+
+ addTest('skew_rect', function(testName){
+ var surface = getTestSurface(testName, 'skewed rects' );
+ // anonymous red rectangle
+ surface.createRect(rect).setFill(new dojo.Color([255, 0, 0, 0.5]))
+ // skew it around LB point -30d, rotate it around LB point 30d, and move it to (100, 100)
+ .setTransform([dojox.gfx.matrix.translate(100, 100), dojox.gfx.matrix.rotategAt(-30, 0, 100), dojox.gfx.matrix.skewXgAt(30, 0, 100)]);
+ // anonymous blue rectangle
+ surface.createRect(rect).setFill(new dojo.Color([0, 0, 255, 0.5]))
+ // skew it around LB point -30d, and move it to (100, 100)
+ .setTransform([dojox.gfx.matrix.translate(100, 100), dojox.gfx.matrix.skewXgAt(30, 0, 100)]);
+ // anonymous yellow rectangle
+ surface.createRect(rect).setFill(new dojo.Color([255, 255, 0, 0.25]))
+ // move it to (100, 100)
+ .setTransform(dojox.gfx.matrix.translate(100, 100));
+ });
+
+ addTest('matrix_rect', function(testName){
+ var surface = getTestSurface(testName, 'all matrix operations, check debug output for more details');
+
+ var group = surface.createGroup();
+
+ var blue_rect = group.createRect(rect).setFill([0, 0, 255, 0.5]).applyTransform(dojox.gfx.matrix.identity);
+ console.debug( "blue_rect: rect with identity" );
+
+ group.createRect(rect).setFill([0, 255, 0, 0.5]).applyTransform(dojox.gfx.matrix.translate(30, 40));
+ console.debug( "lime_rect: translate(30,40) " );
+
+ group.createRect(rect).setFill([255, 0, 0, 0.5]).applyTransform(dojox.gfx.matrix.rotateg(-30));
+ console.debug( "red_rect: rotate 30 degree counterclockwise " );
+
+ group.createRect(rect).setFill([0, 255, 255, 0.5])
+ .applyTransform(dojox.gfx.matrix.scale({x:1.5, y:0.5}))
+ .applyTransform(dojox.gfx.matrix.translate(-40, 220))
+ ;
+ console.debug( "lightblue_rect: scale(1.5, 0.5)" );
+
+ group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([255, 0, 255, 0.5]).applyTransform(dojox.gfx.matrix.flipX);
+ console.debug( "pink_rect: flipX" );
+
+ group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([255, 255, 0, 0.5]).applyTransform(dojox.gfx.matrix.flipY);
+ console.debug( "yellow_rect: flipY" );
+
+ group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([128, 0, 128, 0.5]).applyTransform(dojox.gfx.matrix.flipXY);
+ console.debug( "purple_rect: flipXY" );
+
+ group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([255, 128, 0, 0.5]).applyTransform(dojox.gfx.matrix.skewXg(-15));
+ console.debug( "purple_rect: skewXg 15 degree" );
+
+ group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([0, 0, 0, 0.5]).applyTransform(dojox.gfx.matrix.skewYg(-50));
+ console.debug( "black_rect: skewXg 50 degree" );
+
+ // move
+ group
+ .setTransform({ xx: 1.5, yy: 0.5, dx: 100, dy: 100 })
+ .applyTransform(dojox.gfx.matrix.rotateg(-30))
+ ;
+ });
+
+ addTest('attach', function(testName){
+ var surface = getTestSurface(testName, 'Attach to existed shape');
+ var red_rect = surface.createRect(rect)
+ .setShape({ width: 75 })
+ .setFill([255, 0, 0, 0.5])
+ .setStroke({ color: "blue", width: 1 })
+ .setTransform({ dx: 50, dy: 50, xx: 1, xy: 0.5, yx: 0.7, yy: 1.1 })
+ ;
+
+ console.debug("attaching !");
+ // now attach it!
+ var ar = dojox.gfx.attachNode(red_rect.rawNode);
+ console.assert( ar.rawNode == red_rect.rawNode );
+
+ // FIXME: more generic method to compare two dictionary?
+ console.debug("attach shape: ");
+ isEqual(ar.shape, red_rect.shape, "rect.shape");
+ console.debug("attach matrix: ");
+ isEqual(ar.matrix, red_rect.matrix, "rect.matrix");
+ console.debug("attach strokeStyle: ");
+ isEqual(ar.strokeStyle, red_rect.strokeStyle, "rect.strokeStyle");
+ console.debug("attach fillStyle: ");
+ isEqual(ar.fillStyle, red_rect.fillStyle, "rect.fillStyle");
+ });
+
+ // test circle
+ addTest('circle', function(testName){
+ var surface = getTestSurface(testName, 'translucent green circle');
+ var circle = { cx: 130, cy: 130, r: 50 };
+ surface.createCircle(circle).setFill([0, 255, 0, 0.5]).setTransform({ dx: 20, dy: 20 });
+ });
+
+ // test line
+ addTest('line', function(testName){
+ var surface = getTestSurface(testName, 'straight red line');
+ var line = { x1: 20, y1: 20, x2: 100, y2: 120 };
+ surface.createLine(line).setFill([255, 0, 0, 0.5]).setStroke({color: "red", width: 1}).setTransform({ dx:70, dy: 100 });
+ });
+
+ // test ellipse
+ addTest('ellipse', function(testName){
+ var surface = getTestSurface(testName, 'translucent cyan ellipse');
+ var ellipse = { cx: 50, cy: 80, rx: 50, ry: 80 };
+ surface.createEllipse(ellipse).setFill([0, 255, 255, 0.5]).setTransform({ dx: 30, dy: 70 });
+ });
+
+ // test polyline
+ addTest('polyline', function(testName){
+ var surface = getTestSurface(testName, 'unfilled open polyline');
+ var points = [ {x: 10, y: 20}, {x: 40, y: 70}, {x: 120, y: 50}, {x: 90, y: 90} ];
+ surface.createPolyline(points).setFill(null).setStroke({ color: "blue", width: 1 }).setTransform({ dx: 15, dy: 0 });
+ });
+
+ // test polygon
+ addTest('polygon', function(testName){
+ var surface = getTestSurface(testName, 'filled polygon');
+ var points2 = [{x: 100, y: 0}, {x: 200, y: 40}, {x: 180, y: 150}, {x: 60, y: 170}, {x: 20, y: 100}];
+ surface.createPolyline(points2).setFill([0, 128, 255, 0.6]).setTransform({dx:30, dy: 20});
+ });
+
+ // test path: lineTo, moveTo, closePath
+ addTest('lineTo', function(testName){
+ var surface = getTestSurface(testName, 'lineTo, moveTo, closePath');
+ surface.createPath()
+ .moveTo(10, 20).lineTo(80, 150)
+ .setAbsoluteMode(false).lineTo(40, 0)
+ .setAbsoluteMode(true).lineTo(180, 100)
+ .setAbsoluteMode(false).lineTo(0, -30).lineTo(-30, -50)
+ .closePath()
+ .setStroke({ color: "red", width: 1 })
+ .setFill(null)
+ .setTransform({ dx: 10, dy: 18 })
+ ;
+ });
+
+ addTest('setPath', function(testName){
+ var surface = getTestSurface(testName, 'setPath example with lineTo moveTo');
+ surface.createPath()
+ .moveTo(10, 20).lineTo(80, 150)
+ .setAbsoluteMode(false).lineTo(40,0)
+ .setAbsoluteMode(true).lineTo(180, 100)
+ .setAbsoluteMode(false).lineTo(0, -30).lineTo(-30, -50)
+ .curveTo(10, -80, -150, -10, -90, -10)
+ .closePath()
+ .setStroke({ color: "red", width: 1 })
+ .setFill(null)
+ .setTransform({ dx: 10, dy: 58 })
+ ;
+
+ surface.createPath({ path: "M10,20 L80,150 l40,0 L180,100 l0,-30 l-30,-50 c10,-80 -150,-10 -90,-10 z" })
+ .setFill(null)
+ .setStroke({ color: "blue", width: 1 })
+ .setTransform({ dx: 50, dy: 78 })
+ ;
+ });
+
+ // test arcTo
+ addTest('arcTo', function(testName){
+ var surface = getTestSurface(testName, 'arcTo: from 0 to 360 degree, w/ 30 degree of x axis rotation, rendered with different color');
+
+ var m = dojox.gfx.matrix;
+ var g1 = surface.createGroup();
+ var g2 = g1.createGroup();
+
+ var rx = 100, ry = 60, xRotg = 30;
+ var startPoint = m.multiplyPoint(m.rotateg(xRotg), {x: -rx, y: 0 });
+ var endPoint = m.multiplyPoint(m.rotateg(xRotg), {x: 0, y: -ry});
+
+ var re1 = g1.createPath()
+ .moveTo(startPoint)
+ .arcTo(rx, ry, xRotg, true, false, endPoint)
+ .setStroke({color: "red"})
+ ;
+ var ge1 = g1.createPath()
+ .moveTo(re1.getLastPosition())
+ .arcTo(rx, ry, xRotg, false, false, startPoint)
+ .setStroke({color: "blue"})
+ ;
+ var re2 = g2.createPath()
+ .moveTo(startPoint)
+ .arcTo(rx, ry, xRotg, false, true, endPoint)
+ .setStroke({color: "red"})
+ ;
+ var ge2 = g2.createPath()
+ .moveTo(re2.getLastPosition())
+ .arcTo(rx, ry, xRotg, true, true, startPoint)
+ .setStroke({color: "blue"})
+ ;
+
+ g1.setTransform({dx: 150, dy: 150});
+ g2.setTransform({dx: 10, dy: 10});
+ });
+
+ // test path: curveTo, smoothCurveTo
+ addTest('curveTo', function(testName) {
+ var surface = getTestSurface(testName, 'curveTo, smoothCurveTo');
+ surface.createPath()
+ .moveTo(10, 20).curveTo(50, 50, 50, 100, 150, 100).smoothCurveTo(300, 300, 200, 200)
+ .setStroke({ color: "green", width: 1 }).setFill(null).setTransform({ dx: 10, dy: 30 })
+ ;
+ });
+
+ // test path: curveTo, smoothCurveTo with relative.
+ addTest('curveTo2', function(testName) {
+ var surface = getTestSurface(testName, 'curveTo, smoothCurveTo with relative coordination');
+ surface.createPath()
+ .moveTo(10, 20).curveTo(50, 50, 50, 100, 150, 100)
+ .setAbsoluteMode(false).smoothCurveTo(150, 200, 50, 100)
+ .setAbsoluteMode(true).smoothCurveTo(50, 100, 10, 230)
+ .setStroke({ color: "green", width: 1 }).setFill(null).setTransform({ dx: 10, dy: 30 })
+ ;
+ });
+
+ // test path: curveTo, smoothCurveTo with relative.
+ addTest('qCurveTo', function(testName) {
+ var surface = getTestSurface(testName, 'qCurveTo, qSmoothCurveTo' );
+ surface.createPath()
+ .moveTo(10, 15).qCurveTo(50, 50, 100, 100).qSmoothCurveTo(150, 20)
+ .setStroke({ color: "green", width: 1 }).setFill(null).setTransform({ dx: 10, dy: 30 })
+ ;
+ });
+
+ addTest('qCurveTo2', function(testName) {
+ var surface = getTestSurface(testName, 'qCurveTo, qSmoothCurveTo with relative' );
+ surface.createPath()
+ .moveTo(10, 20).qCurveTo(50, 50, 100, 100)
+ .setAbsoluteMode(false).qSmoothCurveTo(50, -80)
+ .setAbsoluteMode(true).qSmoothCurveTo(200, 80)
+ .setStroke({ color: "green", width: 1 }).setFill(null).setTransform({ dx: 10, dy: 30 })
+ ;
+ });
+
+ // test defines, linearGradient
+ addTest('linearGradient', function(testName) {
+ var surface = getTestSurface(testName, 'linear gradient fill');
+ // this is an example to split the linearGradient from setFill:
+ var lg = {
+ type: "linear",
+ x1: 0, y1: 0, x2: 75, y2: 50,
+ colors: [
+ { offset: 0, color: "#F60" },
+ { offset: 1, color: "#FF6" }
+ ]
+ };
+ surface.createRect(rect).setFill(lg).setTransform({ dx: 40, dy: 100 });
+ });
+
+ // TODO: test radialGradient
+ addTest('radialGradient', function(testName) {
+ var surface = getTestSurface(testName, 'radial gradient fill');
+ // this is a total inline implementation compared with previous one.
+ var rg = {
+ type: "radial",
+ cx: 100, cy: 100, r: 100,
+ colors: [
+ { offset: 0, color: "red" },
+ { offset: 0.5, color: "green" },
+ { offset: 1, color: "blue" }
+ ]
+ };
+
+ surface.createCircle({cx: 100, cy: 100, r: 100})
+ .setStroke({})
+ .setFill(rg)
+ .setTransform({dx: 40, dy: 30})
+ ;
+// surface.createRect(rect)
+// .setShape({width: 200})
+// .setStroke({})
+// .setFill(rg)
+// .setTransform({dx: 40, dy: 30})
+// ;
+ });
+
+ addTest('attach_gradient', function(testName) {
+ var surface = getTestSurface(testName, 'attach gradient fill');
+ // this is an example to split the linearGradient from setFill:
+ var lg = {
+ type: "linear",
+ x1: 0, y1: 0, x2: 75, y2: 50,
+ colors: [
+ { offset: 0, color: "#F60" },
+ { offset: 0.5, color: "#FAF" },
+ { offset: 1, color: "#FF6" }
+ ]
+ };
+
+ var lgr = surface.createRect(rect).setFill(lg).setTransform({ dx: 40, dy: 100 });
+
+ var ar = dojox.gfx.attachNode(lgr.rawNode);
+ // FIXME: more generic method to compare two dictionary?
+ console.debug("attach_gradient!");
+
+ console.debug("attach shape: ");
+ isEqual(lgr.shape, ar.shape, "rect.shape");
+ console.debug("attach matrix: ");
+ isEqual(lgr.matrix, ar.matrix, "rect.matrix");
+ console.debug("attach strokeStyle: ");
+ isEqual(lgr.strokeStyle, ar.strokeStyle, "rect.strokeStyle");
+ console.debug("attach fillStyle: ");
+ isEqual(lgr.fillStyle.gradient, ar.fillStyle.gradient, "rect.fillStyle.gradient");
+ //isEqual(lgr.fillStyle.id, ar.fillStyle.id, "rect.fillStyle.id");
+ });
+
+ var gTestsToRun = [
+ 'rect',
+ 'straight_rect',
+ 'rotated_rect',
+ 'skew_rect',
+ 'matrix_rect',
+ //'attach',
+ //'attach_gradient',
+ 'circle',
+ 'arcTo',
+ 'line',
+ 'ellipse',
+ 'polyline',
+ 'polygon',
+ 'lineTo',
+ 'setPath',
+ 'curveTo',
+ 'curveTo2',
+ 'qCurveTo',
+ 'qCurveTo2',
+ 'linearGradient',
+ 'radialGradient'
+ ];
+
+ for (var i = 0; i < gTestsToRun.length; ++i) {
+ var testName = gTestsToRun[i];
+ var err = runTest(testName);
+ if (err) {
+ getTestSurface(testName, testName + ' FAILED (' + err + ')');
+ }
+ }
+
+}); // end onload
+</script>
+<style>
+ td { border: 1px solid black; text-align: left; vertical-align: top; }
+ v:group { text-align: left; }
+</style>
+ </head>
+ <body>
+ <h1>dojox.gfx tests</h1>
+ <table>
+ <tbody id="testcontainer">
+ </tbody>
+ </table>
+ </body>
+ </html>
diff --git a/includes/js/dojox/gfx/tests/test_gradient.html b/includes/js/dojox/gfx/tests/test_gradient.html
new file mode 100644
index 0000000..cd4e772
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_gradient.html
@@ -0,0 +1,70 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Dojo Unified 2D Graphics</title>
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+dojo.require("dojo.colors"); // pull in CSS3 color names
+
+makeShapes = function(){
+ var SIDE = 10;
+ var fillObj = {
+ colors: [
+ { offset: 0, color: [255, 255, 0, 0] },
+ { offset: 0.5, color: "orange" },
+ { offset: 1, color: [255, 255, 0, 0] }
+ ]
+ };
+ var surface = dojox.gfx.createSurface(dojo.byId("grad"), 300, 300);
+ // create a background
+ for(var i = 0; i < 300; i += SIDE){
+ for(var j = 0; j < 300; j += SIDE){
+ surface.
+ createRect({x: j, y: i, width: 10, height: 10}).
+ setFill((Math.floor(i / SIDE) + Math.floor(j / SIDE)) % 2 ? "lightgrey" : "white");
+ }
+ }
+ // create a rect
+ surface.createRect({
+ width: 300,
+ height: 100
+ }).setFill(dojo.mixin({
+ type: "linear",
+ x1: 0, y1: 0,
+ x2: 300, y2: 0
+ }, fillObj));
+ // create a circle
+ surface.createEllipse({
+ cx: 150,
+ cy: 200,
+ rx: 100,
+ ry: 100
+ }).setFill(dojo.mixin({
+ type: "radial",
+ cx: 150,
+ cy: 200
+ }, fillObj));
+};
+dojo.addOnLoad(makeShapes);
+</script>
+<style type="text/css">
+#grad { width: 300px; height: 300px; }
+</style>
+</head>
+<body>
+<h1>dojox.gfx Alpha gradient test</h1>
+<div id="grad"></div>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_group.html b/includes/js/dojox/gfx/tests/test_group.html
new file mode 100644
index 0000000..fe11b37
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_group.html
@@ -0,0 +1,73 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Dojo Unified 2D Graphics</title>
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<!--<script type="text/javascript" src="../matrix.js"></script>-->
+<!--<script type="text/javascript" src="../util.js"></script>-->
+<!--<script type="text/javascript" src="../shape.js"></script>-->
+<!--<script type="text/javascript" src="../path.js"></script>-->
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+var surface = null;
+var g1 = null;
+var g2 = null;
+var r1 = null;
+
+makeShapes = function(){
+ surface = dojox.gfx.createSurface(document.getElementById("test"), 500, 500);
+ // make a checkerboard
+ for(var i = 0; i < 500; i += 100){
+ for(var j = 0; j < 500; j += 100){
+ if(i % 200 == j % 200) {
+ surface.createRect({ x: i, y: j }).setFill([255, 0, 0, 0.1]);
+ }
+ }
+ }
+ // create groups and shapes
+ g1 = surface.createGroup();
+ g2 = surface.createGroup();
+ r1 = surface.createRect({x: 200, y: 200}).setFill("green").setStroke({});
+ g1.setTransform({dy: -100});
+ //g2.setTransform(dojox.gfx.matrix.rotateAt(-45, 250, 250));
+ g2.setTransform({dx: 100, dy: -100});
+};
+
+switchRect = function(){
+ var radio = document.getElementsByName("switch");
+ if(radio[0].checked){
+ surface.add(r1);
+ }else if(radio[1].checked){
+ g1.add(r1);
+ }else if(radio[2].checked){
+ g2.add(r1);
+ }
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+<h1>dojox.gfx Group tests</h1>
+<p>
+<input type="radio" name="switch" id="r1_s" checked="checked" onclick="switchRect()" /><label for="r1_s">Rectangle belongs to the surface</label><br />
+<input type="radio" name="switch" id="r1_g1" onclick="switchRect()" /><label for="r1_g1">Rectangle belongs to the group #1</label><br />
+<input type="radio" name="switch" id="r1_g2" onclick="switchRect()" /><label for="r1_g2">Rectangle belongs to the group #2</label>
+</p>
+<div id="test"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_image1.html b/includes/js/dojox/gfx/tests/test_image1.html
new file mode 100644
index 0000000..41b168e
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_image1.html
@@ -0,0 +1,74 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Testing image</title>
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+var image = null;
+var grid_size = 500;
+var grid_step = 50;
+
+makeShapes = function(){
+ var surface = dojox.gfx.createSurface("test", 800, 600);
+ for(var i = 0; i <= grid_size; i += grid_step){
+ surface.createLine({x1: 0, x2: grid_size, y1: i, y2: i}).setStroke("black");
+ surface.createLine({y1: 0, y2: grid_size, x1: i, x2: i}).setStroke("black");
+ }
+ image = surface.createImage({width: 157, height: 53, src: "http://archive.dojotoolkit.org/nightly/checkout/util/resources/dojotoolkit.org/mini-dtk/images/logo.png"});
+ //dojo.connect(image.getEventSource(), "onclick", function(){ alert("You didn't expect a download, did you?"); });
+ image.connect("onclick", function(){ alert("You didn't expect a download, did you?"); });
+};
+
+transformImage = function(){
+ var radio = document.getElementsByName("switch");
+ if(radio[0].checked){
+ image.setTransform({});
+ }else if(radio[1].checked){
+ image.setTransform(dojox.gfx.matrix.translate(100,100));
+ }else if(radio[2].checked){
+ image.setTransform([dojox.gfx.matrix.translate(100,0), dojox.gfx.matrix.rotateg(45)]);
+ }else if(radio[3].checked){
+ image.setTransform([dojox.gfx.matrix.translate(70,90), dojox.gfx.matrix.scale({x:1.5, y:0.5})]);
+ }else if(radio[4].checked){
+ image.setTransform([dojox.gfx.matrix.rotateg(15), dojox.gfx.matrix.skewXg(-30)]);
+ }
+ var cb = document.getElementById("r2");
+ if(cb.checked && !image.getShape().x){
+ image.setShape({x: 100, y: 50});
+ }else if(!cb.checked && image.getShape().x){
+ image.setShape({x: 0, y: 0});
+ }
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+<h1>dojox.gfx Image tests</h1>
+<p>Note: Silverlight doesn't allow downloading images when run from a file system. This demo should be run from a server.</p>
+<p>
+<input type="radio" name="switch" id="r1_reset" checked onclick="transformImage()" /><label for="r1_reset">Reset Image</label><br />
+<input type="radio" name="switch" id="r1_move" onclick="transformImage()" /><label for="r1_move">Move Image</label><br />
+<input type="radio" name="switch" id="r1_rotate" onclick="transformImage()" /><label for="r1_rotate">Rotate Image</label><br />
+<input type="radio" name="switch" id="r1_scale" onclick="transformImage()" /><label for="r1_scale">Scale Image</label><br />
+<input type="radio" name="switch" id="r1_skew" onclick="transformImage()" /><label for="r1_skew">Skew Image</label><br />
+</p>
+<p><input type="checkbox" id="r2" onclick="transformImage()" /><label for="r2">Offset image by (100, 50)</label></p>
+<div id="test"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_image2.html b/includes/js/dojox/gfx/tests/test_image2.html
new file mode 100644
index 0000000..25f71c0
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_image2.html
@@ -0,0 +1,50 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Testing image</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+var grid_size = 500, grid_step = 50;
+var main = null, g = null, image = null, rect = null;
+
+makeShapes = function(){
+ var s = dojox.gfx.createSurface("test", 800, 600);
+ for(var i = 0; i <= grid_size; i += grid_step){
+ s.createLine({x1: 0, x2: grid_size, y1: i, y2: i}).setStroke("black");
+ s.createLine({y1: 0, y2: grid_size, x1: i, x2: i}).setStroke("black");
+ }
+
+ main = s.createGroup();
+ //rect = main.createRect({x: 0, y: 0, width: 100, height: 100}).setStroke("black").setFill(new dojo.Color([255, 0, 255, 0.5]));
+ image = main.createImage({width: 157, height: 53, src: "http://archive.dojotoolkit.org/nightly/checkout/util/resources/dojotoolkit.org/mini-dtk/images/logo.png"});
+ // comment out the next string to see the problem
+ rect = main.createRect({x: 0, y: 0, width: 100, height: 100}).setStroke("black").setFill(new dojo.Color([255, 0, 255, 0.5]));
+ //g = main.createGroup();
+ //g.createRect({x: 0, y: 0, width: 100, height: 100}).setStroke("black").setFill(new dojo.Color([255, 255, 0, 0.5]));
+};
+
+trans = function(){
+ var x = 1;
+ main.setTransform([dojox.gfx.matrix.rotategAt(45, 200, 200), {dx: 200, dy: 200}]);
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+<p>Testing image:<br /><button onclick="trans();">Trans</button></p>
+<p>Note: Silverlight doesn't allow downloading images when run from a file system. This demo should be run from a server.</p>
+<div id="test"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_linearGradient.html b/includes/js/dojox/gfx/tests/test_linearGradient.html
new file mode 100644
index 0000000..f18021a
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_linearGradient.html
@@ -0,0 +1,80 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Dojo Unified 2D Graphics</title>
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/_base/Color.js"></script>
+<script type="text/javascript" src="../_base.js"></script>
+<script type="text/javascript" src="../shape.js"></script>
+<script type="text/javascript" src="../path.js"></script>
+<script type="text/javascript" src="../arc.js"></script>
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../canvas.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+dojo.require("dojo.colors");
+
+makeShapes = function(){
+ var lg1 = {
+ type: "linear",
+ x1: 0, y1: 0,
+ x2: 300, y2: 0,
+ colors: [
+ { offset: 0, color: [0, 0, 0, 0] },
+ { offset: 0.1, color: "#000000" },
+ { offset: 0.2, color: "red" },
+ { offset: 0.3, color: "rgb(0,255,0)" },
+ { offset: 0.4, color: "blue" },
+ { offset: 0.5, color: "#ff0" },
+ { offset: 0.6, color: [128] },
+ { offset: 0.7, color: [128, 128, 64] },
+ { offset: 1, color: [0, 255, 0, 0] }
+ ]
+ };
+ var lg2 = {
+ type: "linear",
+ x1: 0, y1: 0,
+ x2: 300, y2: 0,
+ colors: [
+ { offset: 0.2, color: "red" },
+ { offset: 0.3, color: "yellow" }
+ ]
+ };
+ var surface = dojox.gfx.createSurface(dojo.byId("grad"), 300, 300);
+ var group = surface.createGroup();
+ var rect1 = surface.createRect({
+ width: 300,
+ height: 100
+ });
+ rect1.setFill(lg1);
+ var rect2 = surface.createRect({
+ y: 150,
+ width: 300,
+ height: 100
+ });
+ rect2.setFill(lg2);
+ group.add(rect1);
+ group.add(rect2);
+};
+dojo.addOnLoad(makeShapes);
+</script>
+<style>
+v:group { text-align: left; }
+#grad { width: 300px; height: 300px; }
+</style>
+</head>
+<body>
+<h1>dojox.gfx Linear Gradient test</h1>
+<div id="grad"></div>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_linestyle.html b/includes/js/dojox/gfx/tests/test_linestyle.html
new file mode 100644
index 0000000..c4a422b
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_linestyle.html
@@ -0,0 +1,45 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Dojo Unified 2D Graphics</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<!--<script type="text/javascript" src="../_base.js"></script>-->
+<!--<script type="text/javascript" src="../shape.js"></script>-->
+<!--<script type="text/javascript" src="../path.js"></script>-->
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+makeShapes = function(){
+ var surface = dojox.gfx.createSurface(document.getElementById("test"), 500, 500);
+ var styles = ["none", "Solid", "ShortDash", "ShortDot", "ShortDashDot", "ShortDashDotDot",
+ "Dot", "Dash", "LongDash", "DashDot", "LongDashDot", "LongDashDotDot"];
+ var font = "normal normal normal 10pt Arial"; // CSS font style
+ var y_offset = dojox.gfx.normalizedLength("4pt");
+ for(var i = 0; i < styles.length; ++i){
+ var y = 20 + i * 20;
+ surface.createText({x: 140, y: y + y_offset, text: styles[i], align: "end"}).setFont(font).setFill("black");
+ surface.createLine({x1: 150, y1: y, x2: 490, y2: y}).setStroke({style: styles[i], width: 3, cap: "round"});
+ }
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+ <h1>dojox.gfx: Line style test</h1>
+<div id="test"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_pattern.html b/includes/js/dojox/gfx/tests/test_pattern.html
new file mode 100644
index 0000000..04d5c3d
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_pattern.html
@@ -0,0 +1,44 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Testing pattern</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<!--<script type="text/javascript" src="../matrix.js"></script>-->
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<!--<script type="text/javascript" src="../canvas.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+makeShapes = function(){
+ var pattern = {
+ type: "pattern",
+ x: 0, y: 0, width: 333, height: 80,
+ src: "http://dojotoolkit.org/files/downloadButton.gif"
+ };
+ var ellipse = {cx: 400, cy: 200, rx: 350, ry: 150};
+ var surface = dojox.gfx.createSurface("test", 800, 600);
+ surface.createEllipse(ellipse)
+ .setStroke({color: "blue", width: 1 })
+ .setFill(pattern);
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+ <h1>dojox.gfx Pattern test</h1>
+<div id="test"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_poly.html b/includes/js/dojox/gfx/tests/test_poly.html
new file mode 100644
index 0000000..7db70f1
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_poly.html
@@ -0,0 +1,53 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Testing polyline and line transforms</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../_base.js"></script>
+<script type="text/javascript" src="../shape.js"></script>
+<script type="text/javascript" src="../path.js"></script>
+<script type="text/javascript" src="../arc.js"></script>
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../canvas.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+makeShapes = function(){
+ var surface = dojox.gfx.createSurface("test", 500, 500);
+ var line = surface.createLine({x1: 250, y1: 50, x2: 250, y2: 250})
+ .setStroke({color: "blue"})
+ ;
+ var poly = surface.createPolyline([{x: 250, y: 250}, {x: 300, y: 300}, {x: 250, y: 350}, {x: 200, y: 300}, {x: 250, y: 250}])
+ .setStroke({color: "blue"})
+ ;
+ var rotate = dojox.gfx.matrix.rotategAt(5, 250, 250);
+ //var rotate = dojox.gfx.matrix.rotategAt(0.4, 250, 250);
+
+ window.setInterval(function() {
+ line.applyTransform(rotate);
+ poly.applyTransform(rotate);
+ },
+ 100
+ );
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+<h1>dojox.gfx Polyline test</h1>
+<div id="test" style="width: 500px; height: 500px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_resize.html b/includes/js/dojox/gfx/tests/test_resize.html
new file mode 100644
index 0000000..3870ab0
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_resize.html
@@ -0,0 +1,61 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Testing surface resizing</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../_base.js"></script>
+<script type="text/javascript" src="../shape.js"></script>
+<script type="text/javascript" src="../path.js"></script>
+<script type="text/javascript" src="../arc.js"></script>
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../canvas.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+var surface;
+
+makeShapes = function(){
+ surface = dojox.gfx.createSurface("test", 500, 500);
+ surface.createRect({width: 300, height: 300}).setFill([255, 0, 0, 0.3]).setStroke("red");
+ surface.createRect({x: 200, y: 200, width: 300, height: 300}).setFill([0, 0, 255, 0.3]).setStroke("green");
+};
+
+getDim = function(){
+ var t = surface.getDimensions();
+ alert("dimensions: " + t.width + " by " + t.height);
+};
+
+make500x500 = function(){ surface.setDimensions(500, 500); };
+make400x400 = function(){ surface.setDimensions(400, 400); };
+make300x300 = function(){ surface.setDimensions(300, 300); };
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+<h1>Testing surface resizing</h1>
+<!--<p><button onclick="makeShapes();">Go</button></p>-->
+<p>
+ <button onclick="getDim();">getDimensions</button>
+ &nbsp;
+ <button onclick="make300x300();">Make 300x300</button>
+ &nbsp;
+ <button onclick="make400x400();">Make 400x400</button>
+ &nbsp;
+ <button onclick="make500x500();">Make 500x500</button>
+</p>
+<div id="test" style="width: 500px; height: 500px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_setPath.html b/includes/js/dojox/gfx/tests/test_setPath.html
new file mode 100644
index 0000000..c8d7749
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_setPath.html
@@ -0,0 +1,76 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Testing setPath and curves</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<!--<script type="text/javascript" src="../path.js"></script>-->
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+makeShapes = function(){
+ var surface = dojox.gfx.createSurface("test", 500, 500);
+ // relative path with cubic beziers
+ surface
+ .createPath("m100 100 100 0 0 100c0 50-50 50-100 0s-50-100 0-100z")
+ .setStroke({color: "blue"})
+ .setFill("#ddd")
+ .setTransform({dx: -50, dy: -50})
+ ;
+ // absolute path with cubic bezier
+ surface
+ .createPath("M100 100 200 100 200 200C200 250 150 250 100 200S50 100 100 100z")
+ .setStroke({color: "blue"})
+ .setFill("#ddd")
+ .setTransform({dx: 100, dy: -50})
+ ;
+ // relative path with horizontal and vertical lines, and cubic beziers
+ surface
+ .createPath("m100 100h100v100c0 50-50 50-100 0s-50-100 0-100z")
+ .setStroke({color: "blue"})
+ .setFill("#ddd")
+ .setTransform({dx: 250, dy: -50})
+ ;
+ // relative path with quadratic beziers
+ surface
+ .createPath("m100 100 100 0 0 100q0 50-75-25t-25-75z")
+ .setStroke({color: "blue"})
+ .setFill("#ddd")
+ .setTransform({dx: -50, dy: 150})
+ ;
+ // absolute path with quadratic bezier
+ surface
+ .createPath("M100 100 200 100 200 200Q200 250 125 175T100 100z")
+ .setStroke({color: "blue"})
+ .setFill("#ddd")
+ .setTransform({dx: 100, dy: 150})
+ ;
+ // relative path with horizontal and vertical lines, and quadratic beziers
+ surface
+ .createPath("m100 100h100v100q0 50-75-25t-25-75z")
+ .setStroke({color: "blue"})
+ .setFill("#ddd")
+ .setTransform({dx: 250, dy: 150})
+ ;
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+ <h1>dojox.gfx setPath and curve test</h1>
+<div id="test" style="width: 500px; height: 500px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_tbbox.html b/includes/js/dojox/gfx/tests/test_tbbox.html
new file mode 100644
index 0000000..1fb1275
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_tbbox.html
@@ -0,0 +1,117 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Dojo Unified 2D Graphics</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../_base.js"></script>
+<script type="text/javascript" src="../shape.js"></script>
+<script type="text/javascript" src="../path.js"></script>
+<script type="text/javascript" src="../arc.js"></script>
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../canvas.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+makeShapes = function(){
+ var surface = dojox.gfx.createSurface(document.getElementById("test"), 500, 500);
+ var g1 = surface.createGroup();
+ // make a checkerboard
+ for(var i = 0; i < 500; i += 100){
+ for(var j = 0; j < 500; j += 100){
+ if(i % 200 == j % 200) {
+ surface.createRect({ x: i, y: j }).setFill([255, 0, 0, 0.1]);
+ }
+ }
+ }
+ var r1 = g1.createRect({ x: 200, y: 200 })
+ .setFill("green")
+ .setStroke({})
+ //.setTransform(dojox.gfx.matrix.rotategAt(45, 250, 250))
+ ;
+ var r2 = surface.createRect().setStroke({})
+ .setFill({ type: "linear", to: { x: 50, y: 100 },
+ colors: [{ offset: 0, color: "green" }, { offset: 0.5, color: "red" }, { offset: 1, color: "blue" }] })
+ .setTransform({dx: 100, dy: 100})
+ ;
+ var r3 = surface.createRect().setStroke({})
+ .setFill({ type: "linear" })
+ //.setTransform(dojox.gfx.matrix.rotategAt(-45, 250, 250))
+ ;
+ var r4 = g1.createRect({})
+ .setFill("blue")
+ //.setStroke({})
+ //.setTransform(dojox.gfx.matrix.rotategAt(-45, 350, 250))
+ .setTransform([dojox.gfx.matrix.rotategAt(-30, 350, 250), { dx: 300, dy: 200 }])
+ ;
+ var p1 = g1.createPath()
+ .setStroke({})
+ .moveTo( 300, 100 )
+ .lineTo( 400, 200 )
+ .lineTo( 400, 300 )
+ .lineTo( 300, 400 )
+ .curveTo( 400, 300, 400, 200, 300, 100 )
+ //.setTransform(dojox.gfx.matrix.rotategAt(-45, 250, 250))
+ .setTransform({})
+ ;
+ var p2 = g1.createPath(p1.getShape())
+ .setStroke({ color: "red", width: 2 })
+ //.moveTo( 300, 100 )
+ //.lineTo( 400, 200 )
+ //.lineTo( 400, 300 )
+ //.lineTo( 300, 400 )
+ //.curveTo( 400, 300, 400, 200, 300, 100 )
+ //.setTransform(dojox.gfx.matrix.rotategAt(180, 250, 250))
+ .setTransform({ dx: 100 })
+ ;
+ var p3 = g1.createPath()
+ .setStroke({ color: "blue", width: 2 })
+ .moveTo( 300, 100 )
+ .setAbsoluteMode(false)
+ .lineTo ( 100, 100 )
+ .lineTo ( 0, 100 )
+ .lineTo ( -100, 100 )
+ .curveTo( 100, -100, 100, -200, 0, -300 )
+ //.setTransform(dojox.gfx.matrix.rotategAt(135, 250, 250))
+ .setTransform(dojox.gfx.matrix.rotategAt(180, 250, 250))
+ ;
+ //g1.setTransform({ dx: 100 });
+ g1.moveToFront();
+ g1.setTransform(dojox.gfx.matrix.rotategAt(-15, 250, 250));
+ //g1.setTransform([dojox.gfx.matrix.rotategAt(-45, 250, 250), dojox.gfx.matrix.scaleAt(0.5, 250, 250)]);
+ //g1.setTransform([dojox.gfx.matrix.scaleAt(2, 1, 250, 250), dojox.gfx.matrix.rotategAt(-45, 250, 250)]);
+ var a = p1.getTransformedBoundingBox();
+ a.push(a[0]);
+ surface.createPolyline(a).setStroke("green");
+ a = p2.getTransformedBoundingBox();
+ a.push(a[0]);
+ surface.createPolyline(a).setStroke("green");
+ a = p3.getTransformedBoundingBox();
+ a.push(a[0]);
+ surface.createPolyline(a).setStroke("green");
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+<!--
+<style>
+v:group { text-align: left; }
+</style>
+-->
+</head>
+<body>
+ <h1>dojox.gfx Transformation test</h1>
+<div id="test"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_text.html b/includes/js/dojox/gfx/tests/test_text.html
new file mode 100644
index 0000000..446156f
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_text.html
@@ -0,0 +1,88 @@
+<html>
+<head>
+<title>Testing text</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<!--
+<script type="text/javascript" src="../common.js"></script>
+<script type="text/javascript" src="../shape.js"></script>
+-->
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+var ROTATION = 30;
+
+var surface = null, t1, t2, t3, t4, t5;
+
+var placeAnchor = function(surface, x, y){
+ surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y}).setStroke("blue");
+ surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2}).setStroke("blue");
+};
+
+var makeText = function(surface, text, font, fill, stroke){
+ var t = surface.createText(text);
+ if(font) t.setFont(font);
+ if(fill) t.setFill(fill);
+ if(stroke) t.setStroke(stroke);
+ placeAnchor(surface, text.x, text.y);
+ return t;
+};
+
+makeShapes = function(){
+ surface = dojox.gfx.createSurface("test", 500, 500);
+ var m = dojox.gfx.matrix;
+ surface.createLine({x1: 250, y1: 0, x2: 250, y2: 500}).setStroke("green");
+ t1 = makeText(surface, {x: 250, y: 50, text: "Start", align: "start"},
+ {family: "Times", size: "36pt", weight: "bold"}, "black", "red")
+ .setTransform(m.rotategAt(ROTATION, 250, 50))
+ ;
+ t2 = makeText(surface, {x: 250, y: 100, text: "Middle", align: "middle"},
+ {family: "Symbol", size: "24pt"}, "red", "black")
+ .setTransform(m.rotategAt(ROTATION, 250, 100))
+ ;
+ t3 = makeText(surface, {x: 250, y: 150, text: "End", align: "end"},
+ {family: "Helvetica", style: "italic", size: "18pt", rotated: true}, "#FF8000")
+ .setTransform(m.rotategAt(ROTATION, 250, 150))
+ ;
+ t4 = makeText(surface, {x: 250, y: 200, text: "Define Shuffle Tiff", align: "middle", kerning: true},
+ {family: "serif", size: "36pt"}, "black")
+ .setTransform(m.rotategAt(0, 250, 200))
+ ;
+ t5 = makeText(surface, {x: 250, y: 250, text: "Define Shuffle Tiff", align: "middle", kerning: false},
+ {family: "serif", size: "36pt"}, "black")
+ .setTransform(m.rotategAt(0, 250, 250))
+ ;
+};
+
+getSizes = function(){
+ var t = [];
+ dojo.forEach(["t1", "t2", "t3", "t4", "t5"], function(name){
+ var node = eval("(" + name + ")");
+ t.push(node.getShape().text + " = " + node.getTextWidth());
+ });
+ dojo.byId("sizes").innerHTML = t.join("<br/>");
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+ <h1>dojox.gfx Text test</h1>
+<div id="test" style="width: 500px; height: 500px;"></div>
+<div><button onclick="surface.clear();">Clear</button>&nbsp;<button onclick="getSizes();">Get sizes</button></div>
+<p id="sizes">&nbsp;</p>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_textpath.html b/includes/js/dojox/gfx/tests/test_textpath.html
new file mode 100644
index 0000000..201b0b5
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_textpath.html
@@ -0,0 +1,76 @@
+<html>
+<head>
+<title>Testing textpath</title>
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<!--
+<script type="text/javascript" src="../common.js"></script>
+<script type="text/javascript" src="../shape.js"></script>
+<script type="text/javascript" src="../path.js"></script>
+-->
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+var CPD = 30;
+
+var surface = null;
+
+var makeText = function(surface, text, font, fill, stroke){
+ var t = surface.createText(text);
+ if(font) t.setFont(font);
+ if(fill) t.setFill(fill);
+ if(stroke) t.setStroke(stroke);
+ placeAnchor(surface, text.x, text.y);
+ return t;
+};
+
+makeShapes = function(){
+ surface = dojox.gfx.createSurface("test", 500, 500);
+ var p = surface.createPath({})
+ .setStroke("green")
+ .moveTo(0, 100)
+ .setAbsoluteMode(false)
+ .curveTo(CPD, 0, 100 - CPD, 300, 100, 300)
+ .curveTo(CPD, 0, 100 - CPD, -300, 100, -300)
+ .curveTo(CPD, 0, 100 - CPD, 300, 100, 300)
+ .curveTo(CPD, 0, 100 - CPD, -300, 100, -300)
+ .curveTo(CPD, 0, 100 - CPD, 300, 100, 300)
+ ;
+ console.debug(p);
+ var t = surface.createTextPath({
+ text: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Praesent erat. " +
+ "In malesuada ultricies velit. Vestibulum tempor odio vitae diam. " +
+ "Morbi arcu lectus, laoreet eget, nonummy at, elementum a, quam."
+ , align: "middle"
+ //, rotated: true
+ })
+ //.setShape(p.shape)
+ .moveTo(0, 100)
+ .setAbsoluteMode(false)
+ .curveTo(CPD, 0, 100 - CPD, 300, 100, 300)
+ .curveTo(CPD, 0, 100 - CPD, -300, 100, -300)
+ .curveTo(CPD, 0, 100 - CPD, 300, 100, 300)
+ .curveTo(CPD, 0, 100 - CPD, -300, 100, -300)
+ .curveTo(CPD, 0, 100 - CPD, 300, 100, 300)
+ .setFont({family: "times", size: "12pt"})
+ .setFill("blue")
+ ;
+ console.debug(t);
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+ <h1>dojox.gfx Text on a Path test</h1>
+<div id="test" style="width: 500px; height: 500px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/tests/test_transform.html b/includes/js/dojox/gfx/tests/test_transform.html
new file mode 100644
index 0000000..abc50d5
--- /dev/null
+++ b/includes/js/dojox/gfx/tests/test_transform.html
@@ -0,0 +1,98 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Dojo Unified 2D Graphics</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ @import "../../../dojo/resources/dojo.css";
+ @import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<!--
+The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
+<script type="text/javascript" src="Silverlight.js"></script>
+-->
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<!--<script type="text/javascript" src="../vml.js"></script>-->
+<!--<script type="text/javascript" src="../svg.js"></script>-->
+<!--<script type="text/javascript" src="../silverlight.js"></script>-->
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+
+makeShapes = function(){
+ var surface = dojox.gfx.createSurface(document.getElementById("test"), 500, 500);
+ var g1 = surface.createGroup();
+ // make a checkerboard
+ for(var i = 0; i < 500; i += 100){
+ for(var j = 0; j < 500; j += 100){
+ if(i % 200 == j % 200) {
+ surface.createRect({x: i, y: j}).setFill([255, 0, 0, 0.1]);
+ }
+ }
+ }
+ var r1 = g1.createShape({type: "rect", x: 200, y: 200})
+ .setFill("green")
+ .setStroke({})
+ //.setTransform(dojox.gfx.matrix.rotategAt(-45, 250, 250))
+ ;
+ var r2 = surface.createShape({type: "rect"}).setStroke({})
+ .setFill({type: "linear", to: {x: 50, y: 100},
+ colors: [{offset: 0, color: "green"}, {offset: 0.5, color: "red"}, {offset: 1, color: "blue"}] })
+ .setTransform({dx: 100, dy: 100})
+ ;
+ var r3 = surface.createRect().setStroke({})
+ .setFill({ type: "linear" })
+ //.setTransform(dojox.gfx.matrix.rotategAt(-45, 250, 250))
+ ;
+ var r4 = g1.createShape({type: "rect"})
+ .setFill("blue")
+ //.setStroke({})
+ //.setTransform(dojox.gfx.matrix.rotategAt(-45, 350, 250))
+ .setTransform([dojox.gfx.matrix.rotategAt(-30, 350, 250), { dx: 300, dy: 200 }])
+ ;
+ var p1 = g1.createShape({type: "path"})
+ .setStroke({})
+ .moveTo(300, 100)
+ .lineTo(400, 200)
+ .lineTo(400, 300)
+ .lineTo(300, 400)
+ .curveTo(400, 300, 400, 200, 300, 100)
+ //.setTransform(dojox.gfx.matrix.rotategAt(-45, 250, 250))
+ .setTransform({})
+ ;
+ var p2 = g1.createShape(p1.getShape())
+ .setStroke({color: "red", width: 2})
+ //.moveTo( 300, 100 )
+ //.lineTo( 400, 200 )
+ //.lineTo( 400, 300 )
+ //.lineTo( 300, 400 )
+ //.curveTo( 400, 300, 400, 200, 300, 100 )
+ //.setTransform(dojox.gfx.matrix.rotategAt(180, 250, 250))
+ .setTransform({dx: 100})
+ ;
+ var p3 = g1.createShape({type: "path"})
+ .setStroke({color: "blue", width: 2})
+ .moveTo(300, 100)
+ .setAbsoluteMode(false)
+ .lineTo ( 100, 100)
+ .lineTo ( 0, 100)
+ .lineTo (-100, 100)
+ .curveTo( 100, -100, 100, -200, 0, -300)
+ //.setTransform(dojox.gfx.matrix.rotategAt(135, 250, 250))
+ .setTransform(dojox.gfx.matrix.rotategAt(180, 250, 250))
+ ;
+ //g1.setTransform({dx: 100});
+ g1.moveToFront();
+ g1.setTransform(dojox.gfx.matrix.rotategAt(-15, 250, 250));
+ //g1.setTransform([dojox.gfx.matrix.rotategAt(-45, 250, 250), dojox.gfx.matrix.scaleAt(0.5, 250, 250)]);
+ //g1.setTransform([dojox.gfx.matrix.scaleAt(2, 1, 250, 250), dojox.gfx.matrix.rotategAt(-45, 250, 250)]);
+};
+
+dojo.addOnLoad(makeShapes);
+
+</script>
+</head>
+<body>
+<h1>dojox.gfx Transform test</h1>
+<div id="test"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/includes/js/dojox/gfx/utils.js b/includes/js/dojox/gfx/utils.js
new file mode 100644
index 0000000..7ee4d9d
--- /dev/null
+++ b/includes/js/dojox/gfx/utils.js
@@ -0,0 +1,87 @@
+if(!dojo._hasResource["dojox.gfx.utils"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.utils"] = true;
+dojo.provide("dojox.gfx.utils");
+
+dojo.require("dojox.gfx");
+
+dojox.gfx.utils.serialize = function(
+ /* dojox.gfx.Surface || dojox.gfx.Shape */ object
+){
+ var t = {}, v, isSurface = object instanceof dojox.gfx.Surface;
+ if(isSurface || object instanceof dojox.gfx.Group){
+ t.children = [];
+ for(var i = 0; i < object.children.length; ++i){
+ t.children.push(dojox.gfx.utils.serialize(object.children[i]));
+ }
+ if(isSurface){
+ return t.children; // Array
+ }
+ }else{
+ t.shape = object.getShape();
+ }
+ if(object.getTransform){
+ v = object.getTransform();
+ if(v){ t.transform = v; }
+ }
+ if(object.getStroke){
+ v = object.getStroke();
+ if(v){ t.stroke = v; }
+ }
+ if(object.getFill){
+ v = object.getFill();
+ if(v){ t.fill = v; }
+ }
+ if(object.getFont){
+ v = object.getFont();
+ if(v){ t.font = v; }
+ }
+ return t; // Object
+};
+
+dojox.gfx.utils.toJson = function(
+ /* dojox.gfx.Surface || dojox.gfx.Shape */ object,
+ /* Boolean? */ prettyPrint
+){
+ return dojo.toJson(dojox.gfx.utils.serialize(object), prettyPrint); // String
+};
+
+dojox.gfx.utils.deserialize = function(
+ /* dojox.gfx.Surface || dojox.gfx.Shape */ parent,
+ /* dojox.gfx.Shape || Array */ object
+){
+ if(object instanceof Array){
+ var t = [];
+ for(var i = 0; i < object.length; ++i){
+ t.push(dojox.gfx.utils.deserialize(parent, object[i]));
+ }
+ return t; // Array
+ }
+ var shape = ("shape" in object) ? parent.createShape(object.shape) : parent.createGroup();
+ if("transform" in object){
+ shape.setTransform(object.transform);
+ }
+ if("stroke" in object){
+ shape.setStroke(object.stroke);
+ }
+ if("fill" in object){
+ shape.setFill(object.fill);
+ }
+ if("font" in object){
+ shape.setFont(object.font);
+ }
+ if("children" in object){
+ for(var i = 0; i < object.children.length; ++i){
+ dojox.gfx.utils.deserialize(shape, object.children[i]);
+ }
+ }
+ return shape; // dojox.gfx.Shape
+};
+
+dojox.gfx.utils.fromJson = function(
+ /* dojox.gfx.Surface || dojox.gfx.Shape */ parent,
+ /* String */ json
+){
+ return dojox.gfx.utils.deserialize(parent, dojo.fromJson(json)); // Array || dojox.gfx.Shape
+};
+
+}
diff --git a/includes/js/dojox/gfx/vml.js b/includes/js/dojox/gfx/vml.js
new file mode 100644
index 0000000..44f01db
--- /dev/null
+++ b/includes/js/dojox/gfx/vml.js
@@ -0,0 +1,1165 @@
+if(!dojo._hasResource["dojox.gfx.vml"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.gfx.vml"] = true;
+dojo.provide("dojox.gfx.vml");
+
+dojo.require("dojox.gfx._base");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojo.require("dojox.gfx.arc");
+
+// dojox.gfx.vml.xmlns: String: a VML's namespace
+dojox.gfx.vml.xmlns = "urn:schemas-microsoft-com:vml";
+
+// dojox.gfx.vml.text_alignment: Object: mapping from SVG alignment to VML alignment
+dojox.gfx.vml.text_alignment = {start: "left", middle: "center", end: "right"};
+
+dojox.gfx.vml._parseFloat = function(str) {
+ // summary: a helper function to parse VML-specific floating-point values
+ // str: String: a representation of a floating-point number
+ return str.match(/^\d+f$/i) ? parseInt(str) / 65536 : parseFloat(str); // Number
+};
+
+dojox.gfx.vml._bool = {"t": 1, "true": 1};
+
+dojo.extend(dojox.gfx.Shape, {
+ // summary: VML-specific implementation of dojox.gfx.Shape methods
+
+ setFill: function(fill){
+ // summary: sets a fill object (VML)
+ // fill: Object: a fill object
+ // (see dojox.gfx.defaultLinearGradient,
+ // dojox.gfx.defaultRadialGradient,
+ // dojox.gfx.defaultPattern,
+ // or dojo.Color)
+
+ if(!fill){
+ // don't fill
+ this.fillStyle = null;
+ this.rawNode.filled = "f";
+ return this;
+ }
+ if(typeof fill == "object" && "type" in fill){
+ // gradient
+ var i, f, fo, a, s;
+ switch(fill.type){
+ case "linear":
+ var matrix = this._getRealMatrix(), m = dojox.gfx.matrix;
+ s = [];
+ f = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill);
+ a = f.colors;
+ this.fillStyle = f;
+ dojo.forEach(a, function(v, i, a){
+ a[i].color = dojox.gfx.normalizeColor(v.color);
+ });
+ if(a[0].offset > 0){
+ s.push("0 " + a[0].color.toHex());
+ }
+ for(i = 0; i < a.length; ++i){
+ s.push(a[i].offset.toFixed(8) + " " + a[i].color.toHex());
+ }
+ i = a.length - 1;
+ if(a[i].offset < 1){
+ s.push("1 " + a[i].color.toHex());
+ }
+ fo = this.rawNode.fill;
+ fo.colors.value = s.join(";");
+ fo.method = "sigma";
+ fo.type = "gradient";
+ var fc1 = matrix ? m.multiplyPoint(matrix, f.x1, f.y1) : {x: f.x1, y: f.y1},
+ fc2 = matrix ? m.multiplyPoint(matrix, f.x2, f.y2) : {x: f.x2, y: f.y2};
+ fo.angle = (m._radToDeg(Math.atan2(fc2.x - fc1.x, fc2.y - fc1.y)) + 180) % 360;
+ fo.on = true;
+ break;
+ case "radial":
+ f = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill);
+ this.fillStyle = f;
+ var l = parseFloat(this.rawNode.style.left),
+ t = parseFloat(this.rawNode.style.top),
+ w = parseFloat(this.rawNode.style.width),
+ h = parseFloat(this.rawNode.style.height),
+ c = isNaN(w) ? 1 : 2 * f.r / w;
+ a = [];
+ // add a color at the offset 0 (1 in VML coordinates)
+ if(f.colors[0].offset > 0){
+ a.push({offset: 1, color: dojox.gfx.normalizeColor(f.colors[0].color)});
+ }
+ // massage colors
+ dojo.forEach(f.colors, function(v, i){
+ a.push({offset: 1 - v.offset * c, color: dojox.gfx.normalizeColor(v.color)});
+ });
+ i = a.length - 1;
+ while(i >= 0 && a[i].offset < 0){ --i; }
+ if(i < a.length - 1){
+ // correct excessive colors
+ var q = a[i], p = a[i + 1];
+ p.color = dojo.blendColors(q.color, p.color, q.offset / (q.offset - p.offset));
+ p.offset = 0;
+ while(a.length - i > 2) a.pop();
+ }
+ // set colors
+ i = a.length - 1, s = [];
+ if(a[i].offset > 0){
+ s.push("0 " + a[i].color.toHex());
+ }
+ for(; i >= 0; --i){
+ s.push(a[i].offset.toFixed(8) + " " + a[i].color.toHex());
+ }
+ fo = this.rawNode.fill;
+ fo.colors.value = s.join(";");
+ fo.method = "sigma";
+ fo.type = "gradientradial";
+ if(isNaN(w) || isNaN(h) || isNaN(l) || isNaN(t)){
+ fo.focusposition = "0.5 0.5";
+ }else{
+ fo.focusposition = ((f.cx - l) / w).toFixed(8) + " " + ((f.cy - t) / h).toFixed(8);
+ }
+ fo.focussize = "0 0";
+ fo.on = true;
+ break;
+ case "pattern":
+ f = dojox.gfx.makeParameters(dojox.gfx.defaultPattern, fill);
+ this.fillStyle = f;
+ fo = this.rawNode.fill;
+ fo.type = "tile";
+ fo.src = f.src;
+ if(f.width && f.height){
+ // in points
+ fo.size.x = dojox.gfx.px2pt(f.width);
+ fo.size.y = dojox.gfx.px2pt(f.height);
+ }
+ fo.alignShape = "f";
+ fo.position.x = 0;
+ fo.position.y = 0;
+ fo.origin.x = f.width ? f.x / f.width : 0;
+ fo.origin.y = f.height ? f.y / f.height : 0;
+ fo.on = true;
+ break;
+ }
+ this.rawNode.fill.opacity = 1;
+ return this;
+ }
+ // color object
+ this.fillStyle = dojox.gfx.normalizeColor(fill);
+ this.rawNode.fill.method = "any";
+ this.rawNode.fill.type = "solid";
+ this.rawNode.fillcolor = this.fillStyle.toHex();
+ this.rawNode.fill.opacity = this.fillStyle.a;
+ this.rawNode.filled = true;
+ return this; // self
+ },
+
+ setStroke: function(stroke){
+ // summary: sets a stroke object (VML)
+ // stroke: Object: a stroke object
+ // (see dojox.gfx.defaultStroke)
+
+ if(!stroke){
+ // don't stroke
+ this.strokeStyle = null;
+ this.rawNode.stroked = "f";
+ return this;
+ }
+ // normalize the stroke
+ if(typeof stroke == "string"){
+ stroke = {color: stroke};
+ }
+ var s = this.strokeStyle = dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke);
+ s.color = dojox.gfx.normalizeColor(s.color);
+ // generate attributes
+ var rn = this.rawNode;
+ rn.stroked = true;
+ rn.strokecolor = s.color.toCss();
+ rn.strokeweight = s.width + "px"; // TODO: should we assume that the width is always in pixels?
+ if(rn.stroke) {
+ rn.stroke.opacity = s.color.a;
+ rn.stroke.endcap = this._translate(this._capMap, s.cap);
+ if(typeof s.join == "number") {
+ rn.stroke.joinstyle = "miter";
+ rn.stroke.miterlimit = s.join;
+ }else{
+ rn.stroke.joinstyle = s.join;
+ // rn.stroke.miterlimit = s.width;
+ }
+ rn.stroke.dashstyle = s.style == "none" ? "Solid" : s.style;
+ }
+ return this; // self
+ },
+
+ _capMap: { butt: 'flat' },
+ _capMapReversed: { flat: 'butt' },
+
+ _translate: function(dict, value) {
+ return (value in dict) ? dict[value] : value;
+ },
+
+ _applyTransform: function() {
+ if(this.fillStyle && this.fillStyle.type == "linear"){
+ this.setFill(this.fillStyle);
+ }
+ var matrix = this._getRealMatrix();
+ if(!matrix) return this;
+ var skew = this.rawNode.skew;
+ if(typeof skew == "undefined"){
+ for(var i = 0; i < this.rawNode.childNodes.length; ++i){
+ if(this.rawNode.childNodes[i].tagName == "skew"){
+ skew = this.rawNode.childNodes[i];
+ break;
+ }
+ }
+ }
+ if(skew){
+ skew.on = "f";
+ var mt = matrix.xx.toFixed(8) + " " + matrix.xy.toFixed(8) + " " +
+ matrix.yx.toFixed(8) + " " + matrix.yy.toFixed(8) + " 0 0",
+ offset = Math.floor(matrix.dx).toFixed() + "px " + Math.floor(matrix.dy).toFixed() + "px",
+ s = this.rawNode.style,
+ l = parseFloat(s.left),
+ t = parseFloat(s.top),
+ w = parseFloat(s.width),
+ h = parseFloat(s.height);
+ if(isNaN(l)) l = 0;
+ if(isNaN(t)) t = 0;
+ if(isNaN(w)) w = 1;
+ if(isNaN(h)) h = 1;
+ var origin = (-l / w - 0.5).toFixed(8) + " " + (-t / h - 0.5).toFixed(8);
+ skew.matrix = mt;
+ skew.origin = origin;
+ skew.offset = offset;
+ skew.on = true;
+ }
+ return this;
+ },
+
+ setRawNode: function(rawNode){
+ // summary:
+ // assigns and clears the underlying node that will represent this
+ // shape. Once set, transforms, gradients, etc, can be applied.
+ // (no fill & stroke by default)
+ rawNode.stroked = "f";
+ rawNode.filled = "f";
+ this.rawNode = rawNode;
+ },
+
+ // move family
+
+ _moveToFront: function(){
+ // summary: moves a shape to front of its parent's list of shapes (VML)
+ this.rawNode.parentNode.appendChild(this.rawNode);
+ return this;
+ },
+ _moveToBack: function(){
+ // summary: moves a shape to back of its parent's list of shapes (VML)
+ var r = this.rawNode, p = r.parentNode, n = p.firstChild;
+ p.insertBefore(r, n);
+ if(n.tagName == "rect"){
+ // surface has a background rectangle, which position should be preserved
+ n.swapNode(r);
+ }
+ return this;
+ },
+
+ _getRealMatrix: function(){
+ // summary: returns the cumulative ("real") transformation matrix
+ // by combining the shape's matrix with its parent's matrix
+ return this.parentMatrix ? new dojox.gfx.Matrix2D([this.parentMatrix, this.matrix]) : this.matrix; // dojox.gfx.Matrix2D
+ }
+});
+
+dojo.declare("dojox.gfx.Group", dojox.gfx.Shape, {
+ // summary: a group shape (VML), which can be used
+ // to logically group shapes (e.g, to propagate matricies)
+ constructor: function(){
+ dojox.gfx.vml.Container._init.call(this);
+ },
+ // apply transformation
+ _applyTransform: function(){
+ // summary: applies a transformation matrix to a group
+ var matrix = this._getRealMatrix();
+ for(var i = 0; i < this.children.length; ++i){
+ this.children[i]._updateParentMatrix(matrix);
+ }
+ return this; // self
+ }
+});
+dojox.gfx.Group.nodeType = "group";
+
+dojo.declare("dojox.gfx.Rect", dojox.gfx.shape.Rect, {
+ // summary: a rectangle shape (VML)
+ setShape: function(newShape){
+ // summary: sets a rectangle shape object (VML)
+ // newShape: Object: a rectangle shape object
+ var shape = this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ var style = this.rawNode.style;
+ style.left = shape.x.toFixed();
+ style.top = shape.y.toFixed();
+ style.width = (typeof shape.width == "string" && shape.width.indexOf("%") >= 0) ? shape.width : shape.width.toFixed();
+ style.height = (typeof shape.width == "string" && shape.height.indexOf("%") >= 0) ? shape.height : shape.height.toFixed();
+ var r = Math.min(1, (shape.r / Math.min(parseFloat(shape.width), parseFloat(shape.height)))).toFixed(8);
+ // a workaround for the VML's arcsize bug: cannot read arcsize of an instantiated node
+ var parent = this.rawNode.parentNode, before = null;
+ if(parent){
+ if(parent.lastChild != this.rawNode){
+ for(var i = 0; i < parent.childNodes.length; ++i){
+ if(parent.childNodes[i] == this.rawNode){
+ before = parent.childNodes[i+1];
+ break;
+ }
+ }
+ }
+ parent.removeChild(this.rawNode);
+ }
+ this.rawNode.arcsize = r;
+ if(parent){
+ if(before){
+ parent.insertBefore(this.rawNode, before);
+ }else{
+ parent.appendChild(this.rawNode);
+ }
+ }
+ // set all necessary styles, which are lost by VML (yes, it's a VML's bug)
+ return this.setTransform(this.matrix).setFill(this.fillStyle).setStroke(this.strokeStyle); // self
+ }
+});
+dojox.gfx.Rect.nodeType = "roundrect"; // use a roundrect so the stroke join type is respected
+
+dojo.declare("dojox.gfx.Ellipse", dojox.gfx.shape.Ellipse, {
+ // summary: an ellipse shape (VML)
+ setShape: function(newShape){
+ // summary: sets an ellipse shape object (VML)
+ // newShape: Object: an ellipse shape object
+ var shape = this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ var style = this.rawNode.style;
+ style.left = (shape.cx - shape.rx).toFixed();
+ style.top = (shape.cy - shape.ry).toFixed();
+ style.width = (shape.rx * 2).toFixed();
+ style.height = (shape.ry * 2).toFixed();
+ return this.setTransform(this.matrix); // self
+ }
+});
+dojox.gfx.Ellipse.nodeType = "oval";
+
+dojo.declare("dojox.gfx.Circle", dojox.gfx.shape.Circle, {
+ // summary: a circle shape (VML)
+ setShape: function(newShape){
+ // summary: sets a circle shape object (VML)
+ // newShape: Object: a circle shape object
+ var shape = this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ var style = this.rawNode.style;
+ style.left = (shape.cx - shape.r).toFixed();
+ style.top = (shape.cy - shape.r).toFixed();
+ style.width = (shape.r * 2).toFixed();
+ style.height = (shape.r * 2).toFixed();
+ return this; // self
+ }
+});
+dojox.gfx.Circle.nodeType = "oval";
+
+dojo.declare("dojox.gfx.Line", dojox.gfx.shape.Line, {
+ // summary: a line shape (VML)
+ constructor: function(rawNode){
+ if(rawNode) rawNode.setAttribute("dojoGfxType", "line");
+ },
+ setShape: function(newShape){
+ // summary: sets a line shape object (VML)
+ // newShape: Object: a line shape object
+ var shape = this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ this.rawNode.path.v = "m" + shape.x1.toFixed() + " " + shape.y1.toFixed() +
+ "l" + shape.x2.toFixed() + " " + shape.y2.toFixed() + "e";
+ return this.setTransform(this.matrix); // self
+ }
+});
+dojox.gfx.Line.nodeType = "shape";
+
+dojo.declare("dojox.gfx.Polyline", dojox.gfx.shape.Polyline, {
+ // summary: a polyline/polygon shape (VML)
+ constructor: function(rawNode){
+ if(rawNode) rawNode.setAttribute("dojoGfxType", "polyline");
+ },
+ setShape: function(points, closed){
+ // summary: sets a polyline/polygon shape object (VML)
+ // points: Object: a polyline/polygon shape object
+ // closed: Boolean?: if true, close the polyline explicitely
+ if(points && points instanceof Array){
+ // branch
+ // points: Array: an array of points
+ this.shape = dojox.gfx.makeParameters(this.shape, { points: points });
+ if(closed && this.shape.points.length) this.shape.points.push(this.shape.points[0]);
+ }else{
+ this.shape = dojox.gfx.makeParameters(this.shape, points);
+ }
+ this.bbox = null;
+ var attr = [], p = this.shape.points;
+ if(p.length > 0){
+ attr.push("m");
+ var k = 1;
+ if(typeof p[0] == "number"){
+ attr.push(p[0].toFixed());
+ attr.push(p[1].toFixed());
+ k = 2;
+ }else{
+ attr.push(p[0].x.toFixed());
+ attr.push(p[0].y.toFixed());
+ }
+ if(p.length > k){
+ attr.push("l");
+ for(var i = k; i < p.length; ++i){
+ if(typeof p[i] == "number"){
+ attr.push(p[i].toFixed());
+ }else{
+ attr.push(p[i].x.toFixed());
+ attr.push(p[i].y.toFixed());
+ }
+ }
+ }
+ }
+ attr.push("e");
+ this.rawNode.path.v = attr.join(" ");
+ return this.setTransform(this.matrix); // self
+ }
+});
+dojox.gfx.Polyline.nodeType = "shape";
+
+dojo.declare("dojox.gfx.Image", dojox.gfx.shape.Image, {
+ // summary: an image (VML)
+ constructor: function(rawNode){
+ if(rawNode) rawNode.setAttribute("dojoGfxType", "image");
+ },
+ getEventSource: function() {
+ // summary: returns a Node, which is used as
+ // a source of events for this shape
+ return this.rawNode ? this.rawNode.firstChild : null; // Node
+ },
+ setShape: function(newShape){
+ // summary: sets an image shape object (VML)
+ // newShape: Object: an image shape object
+ var shape = this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ this.rawNode.firstChild.src = shape.src;
+ return this.setTransform(this.matrix); // self
+ },
+ _setDimensions: function(s, w, h){
+ if(w || h){
+ s.width = w + "px";
+ s.height = h + "px";
+ }
+ },
+ _resetImage: function(){
+ var s = this.rawNode.firstChild.style,
+ shape = this.shape;
+ s.left = "0px";
+ s.top = "0px";
+ this._setDimensions(s, shape.width, shape.height);
+ },
+ _applyTransform: function() {
+ var matrix = this._getRealMatrix(),
+ img = this.rawNode.firstChild,
+ s = img.style,
+ shape = this.shape;
+ if(matrix){
+ matrix = dojox.gfx.matrix.multiply(matrix, {dx: shape.x, dy: shape.y});
+ }else{
+ matrix = dojox.gfx.matrix.normalize({dx: shape.x, dy: shape.y});
+ }
+ if(matrix.xy == 0 && matrix.yx == 0 && matrix.xx > 0 && matrix.yy > 0){
+ // special case to avoid filters
+ this.rawNode.style.filter = "";
+ s.left = Math.floor(matrix.dx) + "px";
+ s.top = Math.floor(matrix.dy) + "px";
+ this._setDimensions(s, Math.floor(matrix.xx * shape.width), Math.floor(matrix.yy * shape.height));
+ }else{
+ this._resetImage();
+ var f = this.rawNode.filters["DXImageTransform.Microsoft.Matrix"];
+ if(f){
+ f.M11 = matrix.xx;
+ f.M12 = matrix.xy;
+ f.M21 = matrix.yx;
+ f.M22 = matrix.yy;
+ f.Dx = matrix.dx;
+ f.Dy = matrix.dy;
+ }else{
+ this.rawNode.style.filter = "progid:DXImageTransform.Microsoft.Matrix(M11=" + matrix.xx +
+ ", M12=" + matrix.xy + ", M21=" + matrix.yx + ", M22=" + matrix.yy +
+ ", Dx=" + matrix.dx + ", Dy=" + matrix.dy + ")";
+ }
+ }
+ return this;
+ }
+});
+dojox.gfx.Image.nodeType = "div";
+
+dojo.declare("dojox.gfx.Text", dojox.gfx.shape.Text, {
+ // summary: an anchored text (VML)
+ constructor: function(rawNode){
+ if(rawNode){rawNode.setAttribute("dojoGfxType", "text");}
+ this.fontStyle = null;
+ },
+ _alignment: {start: "left", middle: "center", end: "right"},
+ setShape: function(newShape){
+ // summary: sets a text shape object (VML)
+ // newShape: Object: a text shape object
+ this.shape = dojox.gfx.makeParameters(this.shape, newShape);
+ this.bbox = null;
+ var r = this.rawNode, s = this.shape, x = s.x, y = s.y.toFixed();
+ switch(s.align){
+ case "middle":
+ x -= 5;
+ break;
+ case "end":
+ x -= 10;
+ break;
+ }
+ this.rawNode.path.v = "m" + x.toFixed() + "," + y +
+ "l" + (x + 10).toFixed() + "," + y + "e";
+ // find path and text path
+ var p = null, t = null, c = r.childNodes;
+ for(var i = 0; i < c.length; ++i){
+ var tag = c[i].tagName;
+ if(tag == "path"){
+ p = c[i];
+ if(t) break;
+ }else if(tag == "textpath"){
+ t = c[i];
+ if(p) break;
+ }
+ }
+ if(!p){
+ p = this.rawNode.ownerDocument.createElement("v:path");
+ r.appendChild(p);
+ }
+ if(!t){
+ t = this.rawNode.ownerDocument.createElement("v:textpath");
+ r.appendChild(t);
+ }
+ p.textPathOk = true;
+ t.on = true;
+ var a = dojox.gfx.vml.text_alignment[s.align];
+ t.style["v-text-align"] = a ? a : "left";
+ t.style["text-decoration"] = s.decoration;
+ t.style["v-rotate-letters"] = s.rotated;
+ t.style["v-text-kern"] = s.kerning;
+ t.string = s.text;
+ return this.setTransform(this.matrix); // self
+ },
+ _setFont: function(){
+ // summary: sets a font object (VML)
+ var f = this.fontStyle, c = this.rawNode.childNodes;
+ for(var i = 0; i < c.length; ++i){
+ if(c[i].tagName == "textpath"){
+ c[i].style.font = dojox.gfx.makeFontString(f);
+ break;
+ }
+ }
+ this.setTransform(this.matrix);
+ },
+ _getRealMatrix: function(){
+ // summary: returns the cumulative ("real") transformation matrix
+ // by combining the shape's matrix with its parent's matrix;
+ // it makes a correction for a font size
+ var matrix = dojox.gfx.Shape.prototype._getRealMatrix.call(this);
+ // It appears that text is always aligned vertically at a middle of x-height (???).
+ // It is impossible to obtain these metrics from VML => I try to approximate it with
+ // more-or-less util value of 0.7 * FontSize, which is typical for European fonts.
+ if(matrix){
+ matrix = dojox.gfx.matrix.multiply(matrix,
+ {dy: -dojox.gfx.normalizedLength(this.fontStyle ? this.fontStyle.size : "10pt") * 0.35});
+ }
+ return matrix; // dojox.gfx.Matrix2D
+ },
+ getTextWidth: function(){
+ // summary: get the text width, in px
+ var rawNode = this.rawNode, _display = rawNode.style.display;
+ rawNode.style.display = "inline";
+ var _width = dojox.gfx.pt2px(parseFloat(rawNode.currentStyle.width));
+ rawNode.style.display = _display;
+ return _width;
+ }
+});
+dojox.gfx.Text.nodeType = "shape";
+
+dojox.gfx.path._calcArc = function(alpha){
+ // return a start point, 1st and 2nd control points, and an end point
+ var cosa = Math.cos(alpha), sina = Math.sin(alpha),
+ p2 = {x: cosa + (4 / 3) * (1 - cosa), y: sina - (4 / 3) * cosa * (1 - cosa) / sina};
+ return {
+ s: {x: cosa, y: -sina},
+ c1: {x: p2.x, y: -p2.y},
+ c2: p2,
+ e: {x: cosa, y: sina}
+ };
+};
+
+dojo.declare("dojox.gfx.Path", dojox.gfx.path.Path, {
+ // summary: a path shape (VML)
+ constructor: function(rawNode){
+ if(rawNode && !rawNode.getAttribute("dojoGfxType")){
+ rawNode.setAttribute("dojoGfxType", "path");
+ }
+ this.vmlPath = "";
+ this.lastControl = {};
+ },
+ _updateWithSegment: function(segment){
+ // summary: updates the bounding box of path with new segment
+ // segment: Object: a segment
+ var last = dojo.clone(this.last);
+ dojox.gfx.Path.superclass._updateWithSegment.apply(this, arguments);
+ // add a VML path segment
+ var path = this[this.renderers[segment.action]](segment, last);
+ if(typeof this.vmlPath == "string"){
+ this.vmlPath += path.join("");
+ this.rawNode.path.v = this.vmlPath + " r0,0 e";
+ }else{
+ this.vmlPath = this.vmlPath.concat(path);
+ }
+ },
+ setShape: function(newShape){
+ // summary: forms a path using a shape (VML)
+ // newShape: Object: an VML path string or a path object (see dojox.gfx.defaultPath)
+ this.vmlPath = [];
+ this.lastControl = {};
+ dojox.gfx.Path.superclass.setShape.apply(this, arguments);
+ this.vmlPath = this.vmlPath.join("");
+ this.rawNode.path.v = this.vmlPath + " r0,0 e";
+ return this;
+ },
+ _pathVmlToSvgMap: {m: "M", l: "L", t: "m", r: "l", c: "C", v: "c", qb: "Q", x: "z", e: ""},
+ // VML-specific segment renderers
+ renderers: {
+ M: "_moveToA", m: "_moveToR",
+ L: "_lineToA", l: "_lineToR",
+ H: "_hLineToA", h: "_hLineToR",
+ V: "_vLineToA", v: "_vLineToR",
+ C: "_curveToA", c: "_curveToR",
+ S: "_smoothCurveToA", s: "_smoothCurveToR",
+ Q: "_qCurveToA", q: "_qCurveToR",
+ T: "_qSmoothCurveToA", t: "_qSmoothCurveToR",
+ A: "_arcTo", a: "_arcTo",
+ Z: "_closePath", z: "_closePath"
+ },
+ _addArgs: function(path, args, from, upto){
+ if(typeof upto == "undefined"){
+ upto = args.length;
+ }
+ if(typeof from == "undefined"){
+ from = 0;
+ }
+ for(var i = from; i < upto; ++i){
+ path.push(" ");
+ path.push(args[i].toFixed());
+ }
+ },
+ _addArgsAdjusted: function(path, last, args, from, upto){
+ if(typeof upto == "undefined"){
+ upto = args.length;
+ }
+ if(typeof from == "undefined"){
+ from = 0;
+ }
+ for(var i = from; i < upto; i += 2){
+ path.push(" ");
+ path.push((last.x + args[i]).toFixed());
+ path.push(" ");
+ path.push((last.y + args[i + 1]).toFixed());
+ }
+ },
+ _moveToA: function(segment){
+ var p = [" m"], n = segment.args, l = n.length;
+ if(l == 2){
+ this._addArgs(p, n);
+ }else{
+ this._addArgs(p, n, 0, 2);
+ p.push(" l");
+ this._addArgs(p, n, 2);
+ }
+ this.lastControl = {};
+ return p;
+ },
+ _moveToR: function(segment, last){
+ var p = ["x" in last ? " t" : " m"], n = segment.args, l = n.length;
+ if(l == 2){
+ this._addArgs(p, n);
+ }else{
+ this._addArgs(p, n, 0, 2);
+ p.push(" r");
+ this._addArgs(p, n, 2);
+ }
+ this.lastControl = {};
+ return p;
+ },
+ _lineToA: function(segment){
+ var p = [" l"];
+ this._addArgs(p, segment.args);
+ this.lastControl = {};
+ return p;
+ },
+ _lineToR: function(segment){
+ var p = [" r"];
+ this._addArgs(p, segment.args);
+ this.lastControl = {};
+ return p;
+ },
+ _hLineToA: function(segment, last){
+ var p = [" l"], n = segment.args, l = n.length, y = " " + last.y.toFixed();
+ for(var i = 0; i < l; ++i){
+ p.push(" ");
+ p.push(n[i].toFixed());
+ p.push(y);
+ }
+ this.lastControl = {};
+ return p;
+ },
+ _hLineToR: function(segment){
+ var p = [" r"], n = segment.args, l = n.length;
+ for(var i = 0; i < l; ++i){
+ p.push(" ");
+ p.push(n[i].toFixed());
+ p.push(" 0");
+ }
+ this.lastControl = {};
+ return p;
+ },
+ _vLineToA: function(segment, last){
+ var p = [" l"], n = segment.args, l = n.length, x = " " + last.x.toFixed();
+ for(var i = 0; i < l; ++i){
+ p.push(x);
+ p.push(" ");
+ p.push(n[i].toFixed());
+ }
+ this.lastControl = {};
+ return p;
+ },
+ _vLineToR: function(segment){
+ var p = [" r"], n = segment.args, l = n.length;
+ for(var i = 0; i < l; ++i){
+ p.push(" 0 ");
+ p.push(n[i].toFixed());
+ }
+ this.lastControl = {};
+ return p;
+ },
+ _curveToA: function(segment){
+ var p = [], n = segment.args, l = n.length;
+ for(var i = 0; i < l; i += 6){
+ p.push(" c");
+ this._addArgs(p, n, i, i + 6);
+ }
+ this.lastControl = {x: n[l - 4], y: n[l - 3], type: "C"};
+ return p;
+ },
+ _curveToR: function(segment, last){
+ var p = [], n = segment.args, l = n.length;
+ for(var i = 0; i < l; i += 6){
+ p.push(" v");
+ this._addArgs(p, n, i, i + 6);
+ this.lastControl = {x: last.x + n[i + 2], y: last.y + n[i + 3]};
+ last.x += n[i + 4];
+ last.y += n[i + 5];
+ }
+ this.lastControl.type = "C";
+ return p;
+ },
+ _smoothCurveToA: function(segment, last){
+ var p = [], n = segment.args, l = n.length;
+ for(var i = 0; i < l; i += 4){
+ p.push(" c");
+ if(this.lastControl.type == "C"){
+ this._addArgs(p, [
+ 2 * last.x - this.lastControl.x,
+ 2 * last.y - this.lastControl.y
+ ]);
+ }else{
+ this._addArgs(p, [last.x, last.y]);
+ }
+ this._addArgs(p, n, i, i + 4);
+ }
+ this.lastControl = {x: n[l - 4], y: n[l - 3], type: "C"};
+ return p;
+ },
+ _smoothCurveToR: function(segment, last){
+ var p = [], n = segment.args, l = n.length;
+ for(var i = 0; i < l; i += 4){
+ p.push(" v");
+ if(this.lastControl.type == "C"){
+ this._addArgs(p, [
+ last.x - this.lastControl.x,
+ last.y - this.lastControl.y
+ ]);
+ }else{
+ this._addArgs(p, [0, 0]);
+ }
+ this._addArgs(p, n, i, i + 4);
+ this.lastControl = {x: last.x + n[i], y: last.y + n[i + 1]};
+ last.x += n[i + 2];
+ last.y += n[i + 3];
+ }
+ this.lastControl.type = "C";
+ return p;
+ },
+ _qCurveToA: function(segment){
+ var p = [], n = segment.args, l = n.length;
+ for(var i = 0; i < l; i += 4){
+ p.push(" qb");
+ this._addArgs(p, n, i, i + 4);
+ }
+ this.lastControl = {x: n[l - 4], y: n[l - 3], type: "Q"};
+ return p;
+ },
+ _qCurveToR: function(segment, last){
+ var p = [], n = segment.args, l = n.length;
+ for(var i = 0; i < l; i += 4){
+ p.push(" qb");
+ this._addArgsAdjusted(p, last, n, i, i + 4);
+ this.lastControl = {x: last.x + n[i], y: last.y + n[i + 1]};
+ last.x += n[i + 2];
+ last.y += n[i + 3];
+ }
+ this.lastControl.type = "Q";
+ return p;
+ },
+ _qSmoothCurveToA: function(segment, last){
+ var p = [], n = segment.args, l = n.length;
+ for(var i = 0; i < l; i += 2){
+ p.push(" qb");
+ if(this.lastControl.type == "Q"){
+ this._addArgs(p, [
+ this.lastControl.x = 2 * last.x - this.lastControl.x,
+ this.lastControl.y = 2 * last.y - this.lastControl.y
+ ]);
+ }else{
+ this._addArgs(p, [
+ this.lastControl.x = last.x,
+ this.lastControl.y = last.y
+ ]);
+ }
+ this._addArgs(p, n, i, i + 2);
+ }
+ this.lastControl.type = "Q";
+ return p;
+ },
+ _qSmoothCurveToR: function(segment, last){
+ var p = [], n = segment.args, l = n.length;
+ for(var i = 0; i < l; i += 2){
+ p.push(" qb");
+ if(this.lastControl.type == "Q"){
+ this._addArgs(p, [
+ this.lastControl.x = 2 * last.x - this.lastControl.x,
+ this.lastControl.y = 2 * last.y - this.lastControl.y
+ ]);
+ }else{
+ this._addArgs(p, [
+ this.lastControl.x = last.x,
+ this.lastControl.y = last.y
+ ]);
+ }
+ this._addArgsAdjusted(p, last, n, i, i + 2);
+ }
+ this.lastControl.type = "Q";
+ return p;
+ },
+ _arcTo: function(segment, last){
+ var p = [], n = segment.args, l = n.length, relative = segment.action == "a";
+ for(var i = 0; i < l; i += 7){
+ var x1 = n[i + 5], y1 = n[i + 6];
+ if(relative){
+ x1 += last.x;
+ y1 += last.y;
+ }
+ var result = dojox.gfx.arc.arcAsBezier(
+ last, n[i], n[i + 1], n[i + 2],
+ n[i + 3] ? 1 : 0, n[i + 4] ? 1 : 0,
+ x1, y1
+ );
+ for(var j = 0; j < result.length; ++j){
+ p.push(" c");
+ this._addArgs(p, result[j]);
+ }
+ last = {x: x1, y: y1};
+ }
+ this.lastControl = {};
+ return p;
+ },
+ _closePath: function(){
+ this.lastControl = {};
+ return ["x"];
+ }
+});
+dojox.gfx.Path.nodeType = "shape";
+
+dojo.declare("dojox.gfx.TextPath", dojox.gfx.Path, {
+ // summary: a textpath shape (VML)
+ constructor: function(rawNode){
+ if(rawNode){rawNode.setAttribute("dojoGfxType", "textpath");}
+ this.fontStyle = null;
+ if(!("text" in this)){
+ this.text = dojo.clone(dojox.gfx.defaultTextPath);
+ }
+ if(!("fontStyle" in this)){
+ this.fontStyle = dojo.clone(dojox.gfx.defaultFont);
+ }
+ },
+ setText: function(newText){
+ // summary: sets a text to be drawn along the path
+ this.text = dojox.gfx.makeParameters(this.text,
+ typeof newText == "string" ? {text: newText} : newText);
+ this._setText();
+ return this; // self
+ },
+ setFont: function(newFont){
+ // summary: sets a font for text
+ this.fontStyle = typeof newFont == "string" ?
+ dojox.gfx.splitFontString(newFont) :
+ dojox.gfx.makeParameters(dojox.gfx.defaultFont, newFont);
+ this._setFont();
+ return this; // self
+ },
+
+ _setText: function(){
+ // summary: sets a text shape object (VML)
+ this.bbox = null;
+ var r = this.rawNode, s = this.text,
+ // find path and text path
+ p = null, t = null, c = r.childNodes;
+ for(var i = 0; i < c.length; ++i){
+ var tag = c[i].tagName;
+ if(tag == "path"){
+ p = c[i];
+ if(t) break;
+ }else if(tag == "textpath"){
+ t = c[i];
+ if(p) break;
+ }
+ }
+ if(!p){
+ p = this.rawNode.ownerDocument.createElement("v:path");
+ r.appendChild(p);
+ }
+ if(!t){
+ t = this.rawNode.ownerDocument.createElement("v:textpath");
+ r.appendChild(t);
+ }
+ p.textPathOk = true;
+ t.on = true;
+ var a = dojox.gfx.vml.text_alignment[s.align];
+ t.style["v-text-align"] = a ? a : "left";
+ t.style["text-decoration"] = s.decoration;
+ t.style["v-rotate-letters"] = s.rotated;
+ t.style["v-text-kern"] = s.kerning;
+ t.string = s.text;
+ },
+ _setFont: function(){
+ // summary: sets a font object (VML)
+ var f = this.fontStyle, c = this.rawNode.childNodes;
+ for(var i = 0; i < c.length; ++i){
+ if(c[i].tagName == "textpath"){
+ c[i].style.font = dojox.gfx.makeFontString(f);
+ break;
+ }
+ }
+ }
+});
+dojox.gfx.TextPath.nodeType = "shape";
+
+dojo.declare("dojox.gfx.Surface", dojox.gfx.shape.Surface, {
+ // summary: a surface object to be used for drawings (VML)
+ constructor: function(){
+ dojox.gfx.vml.Container._init.call(this);
+ },
+ setDimensions: function(width, height){
+ // summary: sets the width and height of the rawNode
+ // width: String: width of surface, e.g., "100px"
+ // height: String: height of surface, e.g., "100px"
+ this.width = dojox.gfx.normalizedLength(width); // in pixels
+ this.height = dojox.gfx.normalizedLength(height); // in pixels
+ if(!this.rawNode) return this;
+ var cs = this.clipNode.style,
+ r = this.rawNode, rs = r.style,
+ bs = this.bgNode.style;
+ cs.width = width;
+ cs.height = height;
+ cs.clip = "rect(0 " + width + " " + height + " 0)";
+ rs.width = width;
+ rs.height = height;
+ r.coordsize = width + " " + height;
+ bs.width = width;
+ bs.height = height;
+ return this; // self
+ },
+ getDimensions: function(){
+ // summary: returns an object with properties "width" and "height"
+ var t = this.rawNode ? {
+ width: dojox.gfx.normalizedLength(this.rawNode.style.width),
+ height: dojox.gfx.normalizedLength(this.rawNode.style.height)} : null;
+ if(t.width <= 0){ t.width = this.width; }
+ if(t.height <= 0){ t.height = this.height; }
+ return t; // Object
+ }
+});
+
+dojox.gfx.createSurface = function(parentNode, width, height){
+ // summary: creates a surface (VML)
+ // parentNode: Node: a parent node
+ // width: String: width of surface, e.g., "100px"
+ // height: String: height of surface, e.g., "100px"
+
+ if(!width){ width = "100%"; }
+ if(!height){ height = "100%"; }
+ var s = new dojox.gfx.Surface(), p = dojo.byId(parentNode),
+ c = s.clipNode = p.ownerDocument.createElement("div"),
+ r = s.rawNode = p.ownerDocument.createElement("v:group"),
+ cs = c.style, rs = r.style;
+
+ p.style.width = width;
+ p.style.height = height;
+
+ cs.position = "absolute";
+ cs.width = width;
+ cs.height = height;
+ cs.clip = "rect(0 " + width + " " + height + " 0)";
+ rs.position = "absolute";
+ rs.width = width;
+ rs.height = height;
+ r.coordsize = (width == "100%" ? width : parseFloat(width)) + " " +
+ (height == "100%" ? height : parseFloat(height));
+ r.coordorigin = "0 0";
+
+ // create a background rectangle, which is required to show all other shapes
+ var b = s.bgNode = r.ownerDocument.createElement("v:rect"), bs = b.style;
+ bs.left = bs.top = 0;
+ bs.width = rs.width;
+ bs.height = rs.height;
+ b.filled = b.stroked = "f";
+
+ r.appendChild(b);
+ c.appendChild(r);
+ p.appendChild(c);
+
+ s.width = dojox.gfx.normalizedLength(width); // in pixels
+ s.height = dojox.gfx.normalizedLength(height); // in pixels
+
+ return s; // dojox.gfx.Surface
+};
+
+// Extenders
+
+dojox.gfx.vml.Container = {
+ _init: function(){
+ dojox.gfx.shape.Container._init.call(this);
+ },
+ add: function(shape){
+ // summary: adds a shape to a group/surface
+ // shape: dojox.gfx.Shape: an VML shape object
+ if(this != shape.getParent()){
+ this.rawNode.appendChild(shape.rawNode);
+ //dojox.gfx.Group.superclass.add.apply(this, arguments);
+ //this.inherited(arguments);
+ dojox.gfx.shape.Container.add.apply(this, arguments);
+ }
+ return this; // self
+ },
+ remove: function(shape, silently){
+ // summary: remove a shape from a group/surface
+ // shape: dojox.gfx.Shape: an VML shape object
+ // silently: Boolean?: if true, regenerate a picture
+ if(this == shape.getParent()){
+ if(this.rawNode == shape.rawNode.parentNode){
+ this.rawNode.removeChild(shape.rawNode);
+ }
+ //dojox.gfx.Group.superclass.remove.apply(this, arguments);
+ //this.inherited(arguments);
+ dojox.gfx.shape.Container.remove.apply(this, arguments);
+ }
+ return this; // self
+ },
+ clear: function(){
+ // summary: removes all shapes from a group/surface
+ var r = this.rawNode;
+ while(r.firstChild != r.lastChild){
+ if(r.firstChild != this.bgNode){
+ r.removeChild(r.firstChild);
+ }
+ if(r.lastChild != this.bgNode){
+ r.removeChild(r.lastChild);
+ }
+ }
+ //return this.inherited(arguments); // self
+ return dojox.gfx.shape.Container.clear.apply(this, arguments);
+ },
+ _moveChildToFront: dojox.gfx.shape.Container._moveChildToFront,
+ _moveChildToBack: dojox.gfx.shape.Container._moveChildToBack
+};
+
+dojo.mixin(dojox.gfx.shape.Creator, {
+ // summary: VML shape creators
+ createGroup: function(){
+ // summary: creates a VML group shape
+ var g = this.createObject(dojox.gfx.Group, null); // dojox.gfx.Group
+ // create a background rectangle, which is required to show all other shapes
+ var r = g.rawNode.ownerDocument.createElement("v:rect");
+ r.style.left = r.style.top = 0;
+ r.style.width = g.rawNode.style.width;
+ r.style.height = g.rawNode.style.height;
+ r.filled = r.stroked = "f";
+ g.rawNode.appendChild(r);
+ g.bgNode = r;
+ return g; // dojox.gfx.Group
+ },
+ createImage: function(image){
+ // summary: creates a VML image shape
+ // image: Object: an image object (see dojox.gfx.defaultImage)
+ if(!this.rawNode) return null;
+ var shape = new dojox.gfx.Image(), node = this.rawNode.ownerDocument.createElement('div');
+ node.style.position = "absolute";
+ node.style.width = this.rawNode.style.width;
+ node.style.height = this.rawNode.style.height;
+ //node.style.filter = "progid:DXImageTransform.Microsoft.Matrix(M11=1, M12=0, M21=0, M22=1, Dx=0, Dy=0)";
+ var img = this.rawNode.ownerDocument.createElement('img');
+ img.style.position = "relative";
+ node.appendChild(img);
+ shape.setRawNode(node);
+ this.rawNode.appendChild(node);
+ shape.setShape(image);
+ this.add(shape);
+ return shape; // dojox.gfx.Image
+ },
+ createObject: function(shapeType, rawShape) {
+ // summary: creates an instance of the passed shapeType class
+ // shapeType: Function: a class constructor to create an instance of
+ // rawShape: Object: properties to be passed in to the classes "setShape" method
+ // overrideSize: Boolean: set the size explicitly, if true
+ if(!this.rawNode) return null;
+ var shape = new shapeType(),
+ node = this.rawNode.ownerDocument.createElement('v:' + shapeType.nodeType);
+ shape.setRawNode(node);
+ this.rawNode.appendChild(node);
+ switch(shapeType){
+ case dojox.gfx.Group:
+ case dojox.gfx.Line:
+ case dojox.gfx.Polyline:
+ case dojox.gfx.Text:
+ case dojox.gfx.Path:
+ case dojox.gfx.TextPath:
+ this._overrideSize(node);
+ }
+ shape.setShape(rawShape);
+ this.add(shape);
+ return shape; // dojox.gfx.Shape
+ },
+ _overrideSize: function(node){
+ var p = this;
+ while(p && !(p instanceof dojox.gfx.Surface)){ p = p.parent; }
+ node.style.width = p.width;
+ node.style.height = p.height;
+ node.coordsize = p.width + " " + p.height;
+ }
+});
+
+dojo.extend(dojox.gfx.Group, dojox.gfx.vml.Container);
+dojo.extend(dojox.gfx.Group, dojox.gfx.shape.Creator);
+
+dojo.extend(dojox.gfx.Surface, dojox.gfx.vml.Container);
+dojo.extend(dojox.gfx.Surface, dojox.gfx.shape.Creator);
+
+}
diff --git a/includes/js/dojox/gfx/vml_attach.js b/includes/js/dojox/gfx/vml_attach.js
new file mode 100644
index 0000000..b54d31b
--- /dev/null
+++ b/includes/js/dojox/gfx/vml_attach.js
@@ -0,0 +1,362 @@
+dojo.require("dojox.gfx.vml");
+
+dojo.experimental("dojox.gfx.vml_attach");
+
+(function(){
+ dojox.gfx.attachNode = function(node){
+ // summary: creates a shape from a Node
+ // node: Node: an VML node
+ if(!node) return null;
+ var s = null;
+ switch(node.tagName.toLowerCase()){
+ case dojox.gfx.Rect.nodeType:
+ s = new dojox.gfx.Rect(node);
+ attachRect(s);
+ break;
+ case dojox.gfx.Ellipse.nodeType:
+ if(node.style.width == node.style.height){
+ s = new dojox.gfx.Circle(node);
+ attachCircle(s);
+ }else{
+ s = new dojox.gfx.Ellipse(node);
+ attachEllipse(s);
+ }
+ break;
+ case dojox.gfx.Path.nodeType:
+ switch(node.getAttribute("dojoGfxType")){
+ case "line":
+ s = new dojox.gfx.Line(node);
+ attachLine(s);
+ break;
+ case "polyline":
+ s = new dojox.gfx.Polyline(node);
+ attachPolyline(s);
+ break;
+ case "path":
+ s = new dojox.gfx.Path(node);
+ attachPath(s);
+ break;
+ case "text":
+ s = new dojox.gfx.Text(node);
+ attachText(s);
+ attachFont(s);
+ attachTextTransform(s);
+ break;
+ case "textpath":
+ s = new dojox.gfx.TextPath(node);
+ attachPath(s);
+ attachText(s);
+ attachFont(s);
+ break;
+ }
+ break;
+ case dojox.gfx.Image.nodeType:
+ switch(node.getAttribute("dojoGfxType")){
+ case "image":
+ s = new dojox.gfx.Image(node);
+ attachImage(s);
+ attachImageTransform(s);
+ break;
+ }
+ break;
+ default:
+ //console.debug("FATAL ERROR! tagName = " + node.tagName);
+ return null;
+ }
+ if(!(s instanceof dojox.gfx.Image)){
+ attachFill(s);
+ attachStroke(s);
+ if(!(s instanceof dojox.gfx.Text)){
+ attachTransform(s);
+ }
+ }
+ return s; // dojox.gfx.Shape
+ };
+
+ dojox.gfx.attachSurface = function(node){
+ // summary: creates a surface from a Node
+ // node: Node: an VML node
+ var s = new dojox.gfx.Surface();
+ s.clipNode = node;
+ var r = s.rawNode = node.firstChild;
+ var b = r.firstChild;
+ if(!b || b.tagName != "rect"){
+ return null; // dojox.gfx.Surface
+ }
+ s.bgNode = r;
+ return s; // dojox.gfx.Surface
+ };
+
+ var attachFill = function(object){
+ // summary: deduces a fill style from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ var fillStyle = null, r = object.rawNode, fo = r.fill;
+ if(fo.on && fo.type == "gradient"){
+ var fillStyle = dojo.clone(dojox.gfx.defaultLinearGradient),
+ rad = dojox.gfx.matrix._degToRad(fo.angle);
+ fillStyle.x2 = Math.cos(rad);
+ fillStyle.y2 = Math.sin(rad);
+ fillStyle.colors = [];
+ var stops = fo.colors.value.split(";");
+ for(var i = 0; i < stops.length; ++i){
+ var t = stops[i].match(/\S+/g);
+ if(!t || t.length != 2){ continue; }
+ fillStyle.colors.push({offset: dojox.gfx.vml._parseFloat(t[0]), color: new dojo.Color(t[1])});
+ }
+ }else if(fo.on && fo.type == "gradientradial"){
+ var fillStyle = dojo.clone(dojox.gfx.defaultRadialGradient),
+ w = parseFloat(r.style.width), h = parseFloat(r.style.height);
+ fillStyle.cx = isNaN(w) ? 0 : fo.focusposition.x * w;
+ fillStyle.cy = isNaN(h) ? 0 : fo.focusposition.y * h;
+ fillStyle.r = isNaN(w) ? 1 : w / 2;
+ fillStyle.colors = [];
+ var stops = fo.colors.value.split(";");
+ for(var i = stops.length - 1; i >= 0; --i){
+ var t = stops[i].match(/\S+/g);
+ if(!t || t.length != 2){ continue; }
+ fillStyle.colors.push({offset: dojox.gfx.vml._parseFloat(t[0]), color: new dojo.Color(t[1])});
+ }
+ }else if(fo.on && fo.type == "tile"){
+ var fillStyle = dojo.clone(dojox.gfx.defaultPattern);
+ fillStyle.width = dojox.gfx.pt2px(fo.size.x); // from pt
+ fillStyle.height = dojox.gfx.pt2px(fo.size.y); // from pt
+ fillStyle.x = fo.origin.x * fillStyle.width;
+ fillStyle.y = fo.origin.y * fillStyle.height;
+ fillStyle.src = fo.src;
+ }else if(fo.on && r.fillcolor){
+ // a color object !
+ fillStyle = new dojo.Color(r.fillcolor+"");
+ fillStyle.a = fo.opacity;
+ }
+ object.fillStyle = fillStyle;
+ };
+
+ var attachStroke = function(object) {
+ // summary: deduces a stroke style from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ var r = object.rawNode;
+ if(!r.stroked){
+ object.strokeStyle = null;
+ return;
+ }
+ var strokeStyle = object.strokeStyle = dojo.clone(dojox.gfx.defaultStroke),
+ rs = r.stroke;
+ strokeStyle.color = new dojo.Color(r.strokecolor.value);
+ strokeStyle.width = dojox.gfx.normalizedLength(r.strokeweight+"");
+ strokeStyle.color.a = rs.opacity;
+ strokeStyle.cap = this._translate(this._capMapReversed, rs.endcap);
+ strokeStyle.join = rs.joinstyle == "miter" ? rs.miterlimit : rs.joinstyle;
+ strokeStyle.style = rs.dashstyle;
+ };
+
+ var attachTransform = function(object) {
+ // summary: deduces a transformation matrix from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ var s = rawNode.skew, sm = s.matrix, so = s.offset;
+ object.matrix = dojox.gfx.matrix.normalize({
+ xx: sm.xtox,
+ xy: sm.ytox,
+ yx: sm.xtoy,
+ yy: sm.ytoy,
+ dx: dojox.gfx.pt2px(so.x),
+ dy: dojox.gfx.pt2px(so.y)
+ });
+ };
+
+ var attachGroup = function(object){
+ // summary: reconstructs all group shape parameters from a node (VML).
+ // object: dojox.gfx.Shape: an VML shape
+ // attach the background
+ object.bgNode = object.rawNode.firstChild; // TODO: check it first
+ };
+
+ var attachRect = function(object){
+ // summary: builds a rectangle shape from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ // a workaround for the VML's arcsize bug: cannot read arcsize of an instantiated node
+ var r = object.rawNode, arcsize = r.outerHTML.match(/arcsize = \"(\d*\.?\d+[%f]?)\"/)[1],
+ style = r.style, width = parseFloat(style.width), height = parseFloat(style.height);
+ arcsize = (arcsize.indexOf("%") >= 0) ? parseFloat(arcsize) / 100 : dojox.gfx.vml._parseFloat(arcsize);
+ // make an object
+ object.shape = dojox.gfx.makeParameters(dojox.gfx.defaultRect, {
+ x: parseInt(style.left),
+ y: parseInt(style.top),
+ width: width,
+ height: height,
+ r: Math.min(width, height) * arcsize
+ });
+ };
+
+ var attachEllipse = function(object){
+ // summary: builds an ellipse shape from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ var style = object.rawNode.style,
+ rx = parseInt(style.width ) / 2,
+ ry = parseInt(style.height) / 2;
+ object.shape = dojox.gfx.makeParameters(dojox.gfx.defaultEllipse, {
+ cx: parseInt(style.left) + rx,
+ cy: parseInt(style.top ) + ry,
+ rx: rx,
+ ry: ry
+ });
+ };
+
+ var attachCircle = function(object){
+ // summary: builds a circle shape from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ var style = object.rawNode.style, r = parseInt(style.width) / 2;
+ object.shape = dojox.gfx.makeParameters(dojox.gfx.defaultCircle, {
+ cx: parseInt(style.left) + r,
+ cy: parseInt(style.top) + r,
+ r: r
+ });
+ };
+
+ var attachLine = function(object){
+ // summary: builds a line shape from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ var shape = object.shape = dojo.clone(dojox.gfx.defaultLine),
+ p = object.rawNode.path.v.match(dojox.gfx.pathVmlRegExp);
+ do{
+ if(p.length < 7 || p[0] != "m" || p[3] != "l" || p[6] != "e"){ break; }
+ shape.x1 = parseInt(p[1]);
+ shape.y1 = parseInt(p[2]);
+ shape.x2 = parseInt(p[4]);
+ shape.y2 = parseInt(p[5]);
+ }while(false);
+ };
+
+ var attachPolyline = function(object){
+ // summary: builds a polyline/polygon shape from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ var shape = object.shape = dojo.clone(dojox.gfx.defaultPolyline),
+ p = object.rawNode.path.v.match(dojox.gfx.pathVmlRegExp);
+ do{
+ if(p.length < 3 || p[0] != "m"){ break; }
+ var x = parseInt(p[0]), y = parseInt(p[1]);
+ if(isNaN(x) || isNaN(y)){ break; }
+ shape.points.push({x: x, y: y});
+ if(p.length < 6 || p[3] != "l"){ break; }
+ for(var i = 4; i < p.length; i += 2){
+ x = parseInt(p[i]);
+ y = parseInt(p[i + 1]);
+ if(isNaN(x) || isNaN(y)){ break; }
+ shape.points.push({x: x, y: y});
+ }
+ }while(false);
+ };
+
+ var attachImage = function(object){
+ // summary: builds an image shape from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ object.shape = dojo.clone(dojox.gfx.defaultImage);
+ object.shape.src = object.rawNode.firstChild.src;
+ };
+
+ var attachImageTransform = function(object) {
+ // summary: deduces a transformation matrix from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ var m = object.rawNode.filters["DXImageTransform.Microsoft.Matrix"];
+ object.matrix = dojox.gfx.matrix.normalize({
+ xx: m.M11,
+ xy: m.M12,
+ yx: m.M21,
+ yy: m.M22,
+ dx: m.Dx,
+ dy: m.Dy
+ });
+ };
+
+ var attachText = function(object){
+ // summary: builds a text shape from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ var shape = object.shape = dojo.clone(dojox.gfx.defaultText),
+ r = object.rawNode, p = r.path.v.match(dojox.gfx.pathVmlRegExp);
+ do{
+ if(!p || p.length != 7){ break; }
+ var c = r.childNodes, i = 0;
+ for(; i < c.length && c[i].tagName != "textpath"; ++i);
+ if(i >= c.length){ break; }
+ var s = c[i].style;
+ shape.text = c[i].string;
+ switch(s["v-text-align"]){
+ case "left":
+ shape.x = parseInt(p[1]);
+ shape.align = "start";
+ break;
+ case "center":
+ shape.x = (parseInt(p[1]) + parseInt(p[4])) / 2;
+ shape.align = "middle";
+ break;
+ case "right":
+ shape.x = parseInt(p[4]);
+ shape.align = "end";
+ break;
+ }
+ shape.y = parseInt(p[2]);
+ shape.decoration = s["text-decoration"];
+ shape.rotated = s["v-rotate-letters"].toLowerCase() in dojox.gfx.vml._bool;
+ shape.kerning = s["v-text-kern"].toLowerCase() in dojox.gfx.vml._bool;
+ return;
+ }while(false);
+ object.shape = null;
+ };
+
+ var attachFont = function(object){
+ // summary: deduces a font style from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ var fontStyle = object.fontStyle = dojo.clone(dojox.gfx.defaultFont),
+ c = object.rawNode.childNodes, i = 0;
+ for(; i < c.length && c[i].tagName == "textpath"; ++i);
+ if(i >= c.length){
+ object.fontStyle = null;
+ return;
+ }
+ var s = c[i].style;
+ fontStyle.style = s.fontstyle;
+ fontStyle.variant = s.fontvariant;
+ fontStyle.weight = s.fontweight;
+ fontStyle.size = s.fontsize;
+ fontStyle.family = s.fontfamily;
+ };
+
+ var attachTextTransform = function(object) {
+ // summary: deduces a transformation matrix from a node.
+ // object: dojox.gfx.Shape: an VML shape
+ attachTransform(object);
+ var matrix = object.matrix, fs = object.fontStyle;
+ // see comments in _getRealMatrix()
+ if(matrix && fs){
+ object.matrix = dojox.gfx.matrix.multiply(matrix, {dy: dojox.gfx.normalizedLength(fs.size) * 0.35});
+ }
+ };
+
+ var attachPath = function(object){
+ // summary: builds a path shape from a Node.
+ // object: dojox.gfx.Shape: an VML shape
+ var shape = object.shape = dojo.clone(dojox.gfx.defaultPath),
+ p = rawNode.path.v.match(dojox.gfx.pathVmlRegExp),
+ t = [], skip = false, map = dojox.gfx.Path._pathVmlToSvgMap;
+ for(var i = 0; i < p.length; ++p){
+ var s = p[i];
+ if(s in map) {
+ skip = false;
+ t.push(map[s]);
+ } else if(!skip){
+ var n = parseInt(s);
+ if(isNaN(n)){
+ skip = true;
+ }else{
+ t.push(n);
+ }
+ }
+ }
+ var l = t.length;
+ if(l >= 4 && t[l - 1] == "" && t[l - 2] == 0 && t[l - 3] == 0 && t[l - 4] == "l"){
+ t.splice(l - 4, 4);
+ }
+ if(l){
+ shape.path = t.join(" ");
+ }
+ };
+})();