diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..194f75d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: node_js +node_js: + - "node" + +sudo: true + +before_script: + - npm install -g grunt-cli + - npm install + - grunt + - cd test + +script: phantomjs test.js + +notifications: + slack: snapsvg:1zY6dZQuE1vhnug8pLSbbYMv diff --git a/CONTRIBUTING b/CONTRIBUTING index c02401a..2f40a15 100644 --- a/CONTRIBUTING +++ b/CONTRIBUTING @@ -1,3 +1,3 @@ Contributions to this code are covered by the Adobe contributors -license agreeent. Developers must sign and submit the Adobe CLA in -order to contribute to this project. \ No newline at end of file +license agreement. Developers must sign and submit the Adobe CLA in +order to contribute to this project. diff --git a/Gruntfile.js b/Gruntfile.js index 415c624..783186d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,7 +1,31 @@ module.exports = function(grunt) { - var pkg = grunt.file.readJSON("package.json"); + var pkg = grunt.file.readJSON("package.json"), + core = [ + "./src/mina.js", + "./src/svg.js", + "./src/element.js", + "./src/animation.js", + "./src/matrix.js", + "./src/attr.js", + "./src/class.js", + "./src/attradd.js", + "./src/paper.js", + "./src/path.js", + "./src/set.js", + "./src/equal.js", + "./src/mouse.js", + "./src/filter.js", + "./src/align.js", + "./src/colors.js" + ], + src = [ + "./node_modules/eve/eve.js", + "./src/amd-banner.js", + "./src/amd-footer.js" + ]; + src.splice(2, 0, core); // Project configuration. grunt.initConfig({ // Metadata. @@ -26,30 +50,31 @@ module.exports = function(grunt) { }, target: { dest: "dist/snap.svg.js", - src: [ - "./node_modules/eve/eve.js", - "./src/amd-banner.js", - "./src/mina.js", - "./src/svg.js", - "./src/element.js", - "./src/matrix.js", - "./src/attr.js", - "./src/class.js", - "./src/attradd.js", - "./src/paper.js", - "./src/path.js", - "./src/set.js", - "./src/equal.js", - "./src/mouse.js", - "./src/filter.js", - "./src/align.js", - "./src/amd-footer.js" - ] + src: src } }, exec: { dr: { command: "node node_modules/dr.js/dr dr.json" + }, + test: { + command: "cd test; phantomjs test.js" + }, + eslint: { + command: "./node_modules/eslint/bin/eslint.js " + core.join(" ") + }, + }, + prettify: { + options: { + indent: 4, + indent_char: " ", + wrap_line_length: 80, + brace_style: "expand", + unformatted: ["code", "pre", "script"] + }, + one: { + src: "./doc/reference.html", + dest: "./doc/reference.html" } } }); @@ -57,6 +82,9 @@ module.exports = function(grunt) { grunt.loadNpmTasks("grunt-contrib-concat"); grunt.loadNpmTasks("grunt-contrib-uglify"); grunt.loadNpmTasks("grunt-exec"); + grunt.loadNpmTasks("grunt-prettify"); - grunt.registerTask("default", ["concat", "uglify", "exec"]); + grunt.registerTask("default", ["exec:eslint", "concat", "uglify", "exec:dr", "prettify"]); + grunt.registerTask("lint", ["exec:eslint"]); + grunt.registerTask("test", ["exec:test"]); }; diff --git a/README.md b/README.md index 4a5e789..570e6bb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[Snap.svg](http://snapsvg.io) +[Snap.svg](http://snapsvg.io) · [![Build Status](https://travis-ci.org/adobe-webplatform/Snap.svg.svg?branch=dev)](https://travis-ci.org/adobe-webplatform/Snap.svg) [![CDNJS](https://img.shields.io/cdnjs/v/snap.svg.svg)](https://cdnjs.com/libraries/snap.svg/) [![GitHub Tag](https://img.shields.io/github/tag/adobe-webplatform/snap.svg.svg)](https://github.com/adobe-webplatform/Snap.svg/releases) [![License](https://img.shields.io/npm/l/snapsvg.svg)](https://github.com/adobe-webplatform/Snap.svg/blob/master/LICENSE) ====== A JavaScript SVG library for the modern web. Learn more at [snapsvg.io](http://snapsvg.io). @@ -6,7 +6,8 @@ A JavaScript SVG library for the modern web. Learn more at [snapsvg.io](http://s [Follow us on Twitter.](https://twitter.com/snapsvg) ### Install -* [Bower](http://bower.io/) - `bower install snap.svg` +* [Bower](http://bower.io/) - `bower install snap.svg` ![Bower](https://img.shields.io/bower/v/snap.svg.svg) +* [npm](http://npmjs.com/) - `npm install snapsvg` [![npm version](https://img.shields.io/npm/v/snapsvg.svg?style=flat)](https://www.npmjs.com/package/snapsvg) [![Downloads](https://img.shields.io/npm/dt/snapsvg.svg)](https://www.npmjs.com/package/snapsvg) * Manual Minified - https://github.com/adobe-webplatform/Snap.svg/raw/master/dist/snap.svg-min.js * Manual Unminified - https://raw.githubusercontent.com/adobe-webplatform/Snap.svg/master/dist/snap.svg.js @@ -16,6 +17,7 @@ A JavaScript SVG library for the modern web. Learn more at [snapsvg.io](http://s * [About Snap.svg](http://snapsvg.io/about/) * [Getting Started](http://snapsvg.io/start/) * [API Reference](http://snapsvg.io/docs/) +* [Slack Room](https://snapsvg.slack.com/). [Invite](https://snapsvg.slack.com/shared_invite/MTM2NTE4MTk3MDYwLTE0ODYwODgzNzUtYjQ0YmM1N2U0Mg) ### Use @@ -31,6 +33,7 @@ const Snap = require(`imports-loader?this=>window,fix=>module.exports=0!snapsvg/ ``` ### Build +[![Build Status](https://travis-ci.org/adobe-webplatform/Snap.svg.svg?branch=dev)](https://travis-ci.org/adobe-webplatform/Snap.svg) Snap.svg uses [Grunt](http://gruntjs.com/) to build. @@ -50,10 +53,22 @@ npm install ``` _*Snap.svg uses Grunt 0.4.0. You might want to [read](http://gruntjs.com/getting-started) more on their website if you haven’t upgraded since a lot has changed._ -* Type `grunt` in the command line to build the files. -* The results will be built into the release folder. +* To build the files run +```sh +grunt +``` +* The results will be built into the `dist` folder. * Alternatively type `grunt watch` to have the build run automatically when you make changes to source files. +### Testing + +Tests are located in `test` folder. To run tests, simply open `test.html` in there. Automatic tests use PhantomJS to scrap this file, so you can use it as a reference. + +Alternatively, install [PhantomJS](http://phantomjs.org) and run command +```sh +grunt test +``` + ### Contribute * [Fill out the CLA](http://snapsvg.io/contributions/). @@ -63,6 +78,7 @@ _*Snap.svg uses Grunt 0.4.0. You might want to [read](http://gruntjs.com/getting git checkout -b my_branch ``` * Add your changes. +* Check that tests are passing * Commit your changes: ```sh git commit -am "Added some awesome stuff" diff --git a/bower.json b/bower.json index d015466..8fa199d 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "Snap.svg", - "version": "0.4.1", + "version": "0.5.0", "homepage": "http://snapsvg.io", "authors": [ "Dmitry Baranovskiy " diff --git a/component.json b/component.json index a9fdee3..298c373 100644 --- a/component.json +++ b/component.json @@ -2,7 +2,7 @@ "name": "Snap.svg", "repo": "adobe-webplatform/Snap.svg", "description": "The JavaScript library for modern SVG graphics.", - "version": "0.3.0", + "version": "0.5.0", "keywords": ["svg", "snap", "js", "javascript"], "dependencies": {}, "development": {}, diff --git a/dist/snap.svg-min.js b/dist/snap.svg-min.js index 6567d19..29793a5 100644 --- a/dist/snap.svg-min.js +++ b/dist/snap.svg-min.js @@ -1,6 +1,6 @@ -// Snap.svg 0.4.1 +// Snap.svg 0.5.0 // -// Copyright (c) 2013 – 2015 Adobe Systems Incorporated. All rights reserved. +// Copyright (c) 2013 – 2017 Adobe Systems Incorporated. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,8 +14,8 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// build: 2015-04-13 +// build: 2017-02-05 -!function(a){var b,c,d="0.4.2",e="hasOwnProperty",f=/[\.\/]/,g=/\s*,\s*/,h="*",i=function(a,b){return a-b},j={n:{}},k=function(){for(var a=0,b=this.length;b>a;a++)if("undefined"!=typeof this[a])return this[a]},l=function(){for(var a=this.length;--a;)if("undefined"!=typeof this[a])return this[a]},m=function(a,d){a=String(a);var e,f=c,g=Array.prototype.slice.call(arguments,2),h=m.listeners(a),j=0,n=[],o={},p=[],q=b;p.firstDefined=k,p.lastDefined=l,b=a,c=0;for(var r=0,s=h.length;s>r;r++)"zIndex"in h[r]&&(n.push(h[r].zIndex),h[r].zIndex<0&&(o[h[r].zIndex]=h[r]));for(n.sort(i);n[j]<0;)if(e=o[n[j++]],p.push(e.apply(d,g)),c)return c=f,p;for(r=0;s>r;r++)if(e=h[r],"zIndex"in e)if(e.zIndex==n[j]){if(p.push(e.apply(d,g)),c)break;do if(j++,e=o[n[j]],e&&p.push(e.apply(d,g)),c)break;while(e)}else o[e.zIndex]=e;else if(p.push(e.apply(d,g)),c)break;return c=f,b=q,p};m._events=j,m.listeners=function(a){var b,c,d,e,g,i,k,l,m=a.split(f),n=j,o=[n],p=[];for(e=0,g=m.length;g>e;e++){for(l=[],i=0,k=o.length;k>i;i++)for(n=o[i].n,c=[n[m[e]],n[h]],d=2;d--;)b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l}return p},m.on=function(a,b){if(a=String(a),"function"!=typeof b)return function(){};for(var c=a.split(g),d=0,e=c.length;e>d;d++)!function(a){for(var c,d=a.split(f),e=j,g=0,h=d.length;h>g;g++)e=e.n,e=e.hasOwnProperty(d[g])&&e[d[g]]||(e[d[g]]={n:{}});for(e.f=e.f||[],g=0,h=e.f.length;h>g;g++)if(e.f[g]==b){c=!0;break}!c&&e.f.push(b)}(c[d]);return function(a){+a==+a&&(b.zIndex=+a)}},m.f=function(a){var b=[].slice.call(arguments,1);return function(){m.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},m.stop=function(){c=1},m.nt=function(a){return a?new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)").test(b):b},m.nts=function(){return b.split(f)},m.off=m.unbind=function(a,b){if(!a)return void(m._events=j={n:{}});var c=a.split(g);if(c.length>1)for(var d=0,i=c.length;i>d;d++)m.off(c[d],b);else{c=a.split(f);var k,l,n,d,i,o,p,q=[j];for(d=0,i=c.length;i>d;d++)for(o=0;od;d++)for(k=q[d];k.n;){if(b){if(k.f){for(o=0,p=k.f.length;p>o;o++)if(k.f[o]==b){k.f.splice(o,1);break}!k.f.length&&delete k.f}for(l in k.n)if(k.n[e](l)&&k.n[l].f){var r=k.n[l].f;for(o=0,p=r.length;p>o;o++)if(r[o]==b){r.splice(o,1);break}!r.length&&delete k.n[l].f}}else{delete k.f;for(l in k.n)k.n[e](l)&&k.n[l].f&&delete k.n[l].f}k=k.n}}},m.once=function(a,b){var c=function(){return m.unbind(a,c),b.apply(this,arguments)};return m.on(a,c)},m.version=d,m.toString=function(){return"You are running Eve "+d},"undefined"!=typeof module&&module.exports?module.exports=m:"function"==typeof define&&define.amd?define("eve",[],function(){return m}):a.eve=m}(this),function(a,b){if("function"==typeof define&&define.amd)define(["eve"],function(c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("eve");module.exports=b(a,c)}else b(a,a.eve)}(window||this,function(a,b){var c=function(b){var c={},d=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||function(a){setTimeout(a,16)},e=Array.isArray||function(a){return a instanceof Array||"[object Array]"==Object.prototype.toString.call(a)},f=0,g="M"+(+new Date).toString(36),h=function(){return g+(f++).toString(36)},i=Date.now||function(){return+new Date},j=function(a){var b=this;if(null==a)return b.s;var c=b.s-a;b.b+=b.dur*c,b.B+=b.dur*c,b.s=a},k=function(a){var b=this;return null==a?b.spd:void(b.spd=a)},l=function(a){var b=this;return null==a?b.dur:(b.s=b.s*a/b.dur,void(b.dur=a))},m=function(){var a=this;delete c[a.id],a.update(),b("mina.stop."+a.id,a)},n=function(){var a=this;a.pdif||(delete c[a.id],a.update(),a.pdif=a.get()-a.b)},o=function(){var a=this;a.pdif&&(a.b=a.get()-a.pdif,delete a.pdif,c[a.id]=a)},p=function(){var a,b=this;if(e(b.start)){a=[];for(var c=0,d=b.start.length;d>c;c++)a[c]=+b.start[c]+(b.end[c]-b.start[c])*b.easing(b.s)}else a=+b.start+(b.end-b.start)*b.easing(b.s);b.set(a)},q=function(){var a=0;for(var e in c)if(c.hasOwnProperty(e)){var f=c[e],g=f.get();a++,f.s=(g-f.b)/(f.dur/f.spd),f.s>=1&&(delete c[e],f.s=1,a--,function(a){setTimeout(function(){b("mina.finish."+a.id,a)})}(f)),f.update()}a&&d(q)},r=function(a,b,e,f,g,i,s){var t={id:h(),start:a,end:b,b:e,s:0,dur:f-e,spd:1,get:g,set:i,easing:s||r.linear,status:j,speed:k,duration:l,stop:m,pause:n,resume:o,update:p};c[t.id]=t;var u,v=0;for(u in c)if(c.hasOwnProperty(u)&&(v++,2==v))break;return 1==v&&d(q),t};return r.time=i,r.getById=function(a){return c[a]||null},r.linear=function(a){return a},r.easeout=function(a){return Math.pow(a,1.7)},r.easein=function(a){return Math.pow(a,.48)},r.easeinout=function(a){if(1==a)return 1;if(0==a)return 0;var b=.48-a/1.04,c=Math.sqrt(.1734+b*b),d=c-b,e=Math.pow(Math.abs(d),1/3)*(0>d?-1:1),f=-c-b,g=Math.pow(Math.abs(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},r.backin=function(a){if(1==a)return 1;var b=1.70158;return a*a*((b+1)*a-b)},r.backout=function(a){if(0==a)return 0;a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},r.elastic=function(a){return a==!!a?a:Math.pow(2,-10*a)*Math.sin(2*(a-.075)*Math.PI/.3)+1},r.bounce=function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b},a.mina=r,r}("undefined"==typeof b?function(){}:b),d=function(a){function c(a,b){if(a){if(a.nodeType)return w(a);if(e(a,"array")&&c.set)return c.set.apply(c,a);if(a instanceof s)return a;if(null==b)return a=y.doc.querySelector(String(a)),w(a)}return a=null==a?"100%":a,b=null==b?"100%":b,new v(a,b)}function d(a,b){if(b){if("#text"==a&&(a=y.doc.createTextNode(b.text||b["#text"]||"")),"#comment"==a&&(a=y.doc.createComment(b.text||b["#text"]||"")),"string"==typeof a&&(a=d(a)),"string"==typeof b)return 1==a.nodeType?"xlink:"==b.substring(0,6)?a.getAttributeNS(T,b.substring(6)):"xml:"==b.substring(0,4)?a.getAttributeNS(U,b.substring(4)):a.getAttribute(b):"text"==b?a.nodeValue:null;if(1==a.nodeType){for(var c in b)if(b[z](c)){var e=A(b[c]);e?"xlink:"==c.substring(0,6)?a.setAttributeNS(T,c.substring(6),e):"xml:"==c.substring(0,4)?a.setAttributeNS(U,c.substring(4),e):a.setAttribute(c,e):a.removeAttribute(c)}}else"text"in b&&(a.nodeValue=b.text)}else a=y.doc.createElementNS(U,a);return a}function e(a,b){return b=A.prototype.toLowerCase.call(b),"finite"==b?isFinite(a):"array"==b&&(a instanceof Array||Array.isArray&&Array.isArray(a))?!0:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||J.call(a).slice(8,-1).toLowerCase()==b}function f(a){if("function"==typeof a||Object(a)!==a)return a;var b=new a.constructor;for(var c in a)a[z](c)&&(b[c]=f(a[c]));return b}function h(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function i(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),g=d.cache=d.cache||{},i=d.count=d.count||[];return g[z](f)?(h(i,f),c?c(g[f]):g[f]):(i.length>=1e3&&delete g[i.shift()],i.push(f),g[f]=a.apply(b,e),c?c(g[f]):g[f])}return d}function j(a,b,c,d,e,f){if(null==e){var g=a-c,h=b-d;return g||h?(180+180*D.atan2(-h,-g)/H+360)%360:0}return j(a,b,e,f)-j(c,d,e,f)}function k(a){return a%360*H/180}function l(a){return 180*a/H%360}function m(a){var b=[];return a=a.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g,function(a,c,d){return d=d.split(/\s*,\s*|\s+/),"rotate"==c&&1==d.length&&d.push(0,0),"scale"==c&&(d.length>2?d=d.slice(0,2):2==d.length&&d.push(0,0),1==d.length&&d.push(d[0],0,0)),b.push("skewX"==c?["m",1,0,D.tan(k(d[0])),1,0,0]:"skewY"==c?["m",1,D.tan(k(d[0])),0,1,0,0]:[c.charAt(0)].concat(d)),a}),b}function n(a,b){var d=ab(a),e=new c.Matrix;if(d)for(var f=0,g=d.length;g>f;f++){var h,i,j,k,l,m=d[f],n=m.length,o=A(m[0]).toLowerCase(),p=m[0]!=o,q=p?e.invert():0;"t"==o&&2==n?e.translate(m[1],0):"t"==o&&3==n?p?(h=q.x(0,0),i=q.y(0,0),j=q.x(m[1],m[2]),k=q.y(m[1],m[2]),e.translate(j-h,k-i)):e.translate(m[1],m[2]):"r"==o?2==n?(l=l||b,e.rotate(m[1],l.x+l.width/2,l.y+l.height/2)):4==n&&(p?(j=q.x(m[2],m[3]),k=q.y(m[2],m[3]),e.rotate(m[1],j,k)):e.rotate(m[1],m[2],m[3])):"s"==o?2==n||3==n?(l=l||b,e.scale(m[1],m[n-1],l.x+l.width/2,l.y+l.height/2)):4==n?p?(j=q.x(m[2],m[3]),k=q.y(m[2],m[3]),e.scale(m[1],m[1],j,k)):e.scale(m[1],m[1],m[2],m[3]):5==n&&(p?(j=q.x(m[3],m[4]),k=q.y(m[3],m[4]),e.scale(m[1],m[2],j,k)):e.scale(m[1],m[2],m[3],m[4])):"m"==o&&7==n&&e.add(m[1],m[2],m[3],m[4],m[5],m[6])}return e}function o(a){var b=a.node.ownerSVGElement&&w(a.node.ownerSVGElement)||a.node.parentNode&&w(a.node.parentNode)||c.select("svg")||c(0,0),d=b.select("defs"),e=null==d?!1:d.node;return e||(e=u("defs",b.node).node),e}function p(a){return a.node.ownerSVGElement&&w(a.node.ownerSVGElement)||c.select("svg")}function q(a,b,c){function e(a){if(null==a)return I;if(a==+a)return a;d(j,{width:a});try{return j.getBBox().width}catch(b){return 0}}function f(a){if(null==a)return I;if(a==+a)return a;d(j,{height:a});try{return j.getBBox().height}catch(b){return 0}}function g(d,e){null==b?i[d]=e(a.attr(d)||0):d==b&&(i=e(null==c?a.attr(d)||0:c))}var h=p(a).node,i={},j=h.querySelector(".svg---mgr");switch(j||(j=d("rect"),d(j,{x:-9e9,y:-9e9,width:10,height:10,"class":"svg---mgr",fill:"none"}),h.appendChild(j)),a.type){case"rect":g("rx",e),g("ry",f);case"image":g("width",e),g("height",f);case"text":g("x",e),g("y",f);break;case"circle":g("cx",e),g("cy",f),g("r",e);break;case"ellipse":g("cx",e),g("cy",f),g("rx",e),g("ry",f);break;case"line":g("x1",e),g("x2",e),g("y1",f),g("y2",f);break;case"marker":g("refX",e),g("markerWidth",e),g("refY",f),g("markerHeight",f);break;case"radialGradient":g("fx",e),g("fy",f);break;case"tspan":g("dx",e),g("dy",f);break;default:g(b,e)}return h.removeChild(j),i}function r(a){e(a,"array")||(a=Array.prototype.slice.call(arguments,0));for(var b=0,c=0,d=this.node;this[b];)delete this[b++];for(b=0;bc;c++){var e={type:a[c].type,attr:a[c].attr()},f=a[c].children();b.push(e),f.length&&x(f,e.childNodes=[])}}c.version="0.4.0",c.toString=function(){return"Snap v"+this.version},c._={};var y={win:a.window,doc:a.window.document};c._.glob=y;{var z="hasOwnProperty",A=String,B=parseFloat,C=parseInt,D=Math,E=D.max,F=D.min,G=D.abs,H=(D.pow,D.PI),I=(D.round,""),J=Object.prototype.toString,K=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i,L=(c._.separator=/[,\s]+/,/[\s]*,[\s]*/),M={hs:1,rg:1},N=/([a-z])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/gi,O=/([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/gi,P=/(-?\d*\.?\d*(?:e[\-+]?\\d+)?)[\s]*,?[\s]*/gi,Q=0,R="S"+(+new Date).toString(36),S=function(a){return(a&&a.type?a.type:I)+R+(Q++).toString(36)},T="http://www.w3.org/1999/xlink",U="http://www.w3.org/2000/svg",V={};c.url=function(a){return"url('#"+a+"')"}}c._.$=d,c._.id=S,c.format=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return A(b).replace(a,function(a,b){return c(a,b,d)})}}(),c._.clone=f,c._.cacher=i,c.rad=k,c.deg=l,c.sin=function(a){return D.sin(c.rad(a))},c.tan=function(a){return D.tan(c.rad(a))},c.cos=function(a){return D.cos(c.rad(a))},c.asin=function(a){return c.deg(D.asin(a))},c.acos=function(a){return c.deg(D.acos(a))},c.atan=function(a){return c.deg(D.atan(a))},c.atan2=function(a){return c.deg(D.atan2(a))},c.angle=j,c.len=function(a,b,d,e){return Math.sqrt(c.len2(a,b,d,e))},c.len2=function(a,b,c,d){return(a-c)*(a-c)+(b-d)*(b-d)},c.closestPoint=function(a,b,c){function d(a){var d=a.x-b,e=a.y-c;return d*d+e*e}for(var e,f,g,h,i=a.node,j=i.getTotalLength(),k=j/i.pathSegList.numberOfItems*.125,l=1/0,m=0;j>=m;m+=k)(h=d(g=i.getPointAtLength(m))).5;){var n,o,p,q,r,s;(p=f-k)>=0&&(r=d(n=i.getPointAtLength(p)))f)return b-f;if(f>a-c)return b-f+a}return b},c.getRGB=i(function(a){if(!a||(a=A(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:Z};if(!(M[z](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=W(a)),!a)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z};var b,d,f,g,h,i,j=a.match(K);return j?(j[2]&&(f=C(j[2].substring(5),16),d=C(j[2].substring(3,5),16),b=C(j[2].substring(1,3),16)),j[3]&&(f=C((h=j[3].charAt(3))+h,16),d=C((h=j[3].charAt(2))+h,16),b=C((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=B(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),f=B(i[2]),"%"==i[2].slice(-1)&&(f*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100)),j[5]?(i=j[5].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b/=100),d=B(i[1]),"%"==i[1].slice(-1)&&(d/=100),f=B(i[2]),"%"==i[2].slice(-1)&&(f/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),c.hsb2rgb(b,d,f,g)):j[6]?(i=j[6].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b/=100),d=B(i[1]),"%"==i[1].slice(-1)&&(d/=100),f=B(i[2]),"%"==i[2].slice(-1)&&(f/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),c.hsl2rgb(b,d,f,g)):(b=F(D.round(b),255),d=F(D.round(d),255),f=F(D.round(f),255),g=F(E(g,0),1),j={r:b,g:d,b:f,toString:Z},j.hex="#"+(16777216|f|d<<8|b<<16).toString(16).slice(1),j.opacity=e(g,"finite")?g:1,j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z}},c),c.hsb=i(function(a,b,d){return c.hsb2rgb(a,b,d).hex}),c.hsl=i(function(a,b,d){return c.hsl2rgb(a,b,d).hex}),c.rgb=i(function(a,b,c,d){if(e(d,"finite")){var f=D.round;return"rgba("+[f(a),f(b),f(c),+d.toFixed(2)]+")"}return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)});var W=function(a){var b=y.doc.getElementsByTagName("head")[0]||y.doc.getElementsByTagName("svg")[0],c="rgb(255, 0, 0)";return(W=i(function(a){if("red"==a.toLowerCase())return c;b.style.color=c,b.style.color=a;var d=y.doc.defaultView.getComputedStyle(b,I).getPropertyValue("color");return d==c?null:d}))(a)},X=function(){return"hsb("+[this.h,this.s,this.b]+")"},Y=function(){return"hsl("+[this.h,this.s,this.l]+")"},Z=function(){return 1==this.opacity||null==this.opacity?this.hex:"rgba("+[this.r,this.g,this.b,this.opacity]+")"},$=function(a,b,d){if(null==b&&e(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(d=a.b,b=a.g,a=a.r),null==b&&e(a,string)){var f=c.getRGB(a);a=f.r,b=f.g,d=f.b}return(a>1||b>1||d>1)&&(a/=255,b/=255,d/=255),[a,b,d]},_=function(a,b,d,f){a=D.round(255*a),b=D.round(255*b),d=D.round(255*d);var g={r:a,g:b,b:d,opacity:e(f,"finite")?f:1,hex:c.rgb(a,b,d),toString:Z};return e(f,"finite")&&(g.opacity=f),g};c.color=function(a){var b;return e(a,"object")&&"h"in a&&"s"in a&&"b"in a?(b=c.hsb2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):e(a,"object")&&"h"in a&&"s"in a&&"l"in a?(b=c.hsl2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):(e(a,"string")&&(a=c.getRGB(a)),e(a,"object")&&"r"in a&&"g"in a&&"b"in a&&!("error"in a)?(b=c.rgb2hsl(a),a.h=b.h,a.s=b.s,a.l=b.l,b=c.rgb2hsb(a),a.v=b.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1,a.error=1)),a.toString=Z,a},c.hsb2rgb=function(a,b,c,d){e(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,d=a.o,a=a.h),a*=360;var f,g,h,i,j;return a=a%360/60,j=c*b,i=j*(1-G(a%2-1)),f=g=h=c-j,a=~~a,f+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],_(f,g,h,d)},c.hsl2rgb=function(a,b,c,d){e(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var f,g,h,i,j;return a=a%360/60,j=2*b*(.5>c?c:1-c),i=j*(1-G(a%2-1)),f=g=h=c-j/2,a=~~a,f+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],_(f,g,h,d)},c.rgb2hsb=function(a,b,c){c=$(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=E(a,b,c),g=f-F(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:X}},c.rgb2hsl=function(a,b,c){c=$(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=E(a,b,c),h=F(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:Y}},c.parsePathString=function(a){if(!a)return null;var b=c.path(a);if(b.arr)return c.path.clone(b.arr);var d={a:7,c:6,o:2,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,u:3,z:0},f=[];return e(a,"array")&&e(a[0],"array")&&(f=c.path.clone(a)),f.length||A(a).replace(N,function(a,b,c){var e=[],g=b.toLowerCase();if(c.replace(P,function(a,b){b&&e.push(+b)}),"m"==g&&e.length>2&&(f.push([b].concat(e.splice(0,2))),g="l",b="m"==b?"l":"L"),"o"==g&&1==e.length&&f.push([b,e[0]]),"r"==g)f.push([b].concat(e));else for(;e.length>=d[g]&&(f.push([b].concat(e.splice(0,d[g]))),d[g]););}),f.toString=c.path.toString,b.arr=c.path.clone(f),f};var ab=c.parseTransformString=function(a){if(!a)return null;var b=[];return e(a,"array")&&e(a[0],"array")&&(b=c.path.clone(a)),b.length||A(a).replace(O,function(a,c,d){{var e=[];c.toLowerCase()}d.replace(P,function(a,b){b&&e.push(+b)}),b.push([c].concat(e))}),b.toString=c.path.toString,b};c._.svgTransform2string=m,c._.rgTransform=/^[a-z][\s]*-?\.?\d/i,c._.transform2matrix=n,c._unit2px=q;y.doc.contains||y.doc.compareDocumentPosition?function(a,b){var c=9==a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a==d||!(!d||1!=d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)for(;b;)if(b=b.parentNode,b==a)return!0;return!1};c._.getSomeDefs=o,c._.getSomeSVG=p,c.select=function(a){return a=A(a).replace(/([^\\]):/g,"$1\\:"),w(y.doc.querySelector(a))},c.selectAll=function(a){for(var b=y.doc.querySelectorAll(a),d=(c.set||Array)(),e=0;ei;i++)h[g[i].nodeName]=g[i].nodeValue;return h}if(e(a,"string")){if(!(arguments.length>1))return b("snap.util.getattr."+a,d).firstDefined();var k={};k[a]=c,a=k}for(var l in a)a[z](l)&&b("snap.util.attr."+l,d,a[l]);return d},c.parse=function(a){var b=y.doc.createDocumentFragment(),c=!0,d=y.doc.createElement("div");if(a=A(a),a.match(/^\s*<\s*svg(?:\s|>)/)||(a=""+a+"",c=!1),d.innerHTML=a,a=d.getElementsByTagName("svg")[0])if(c)b=a;else for(;a.firstChild;)b.appendChild(a.firstChild);return new t(b)},c.fragment=function(){for(var a=Array.prototype.slice.call(arguments,0),b=y.doc.createDocumentFragment(),d=0,e=a.length;e>d;d++){var f=a[d];f.node&&f.node.nodeType&&b.appendChild(f.node),f.nodeType&&b.appendChild(f),"string"==typeof f&&b.appendChild(c.parse(f).node)}return new t(b)},c._.make=u,c._.wrap=w,v.prototype.el=function(a,b){var c=u(a,this.node);return b&&c.attr(b),c},s.prototype.children=function(){for(var a=[],b=this.node.childNodes,d=0,e=b.length;e>d;d++)a[d]=c(b[d]);return a},s.prototype.toJSON=function(){var a=[];return x([this],a),a[0]},b.on("snap.util.getattr",function(){var a=b.nt();a=a.substring(a.lastIndexOf(".")+1);var c=a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()});return bb[z](c)?this.node.ownerDocument.defaultView.getComputedStyle(this.node,null).getPropertyValue(c):d(this.node,a)});var bb={"alignment-baseline":0,"baseline-shift":0,clip:0,"clip-path":0,"clip-rule":0,color:0,"color-interpolation":0,"color-interpolation-filters":0,"color-profile":0,"color-rendering":0,cursor:0,direction:0,display:0,"dominant-baseline":0,"enable-background":0,fill:0,"fill-opacity":0,"fill-rule":0,filter:0,"flood-color":0,"flood-opacity":0,font:0,"font-family":0,"font-size":0,"font-size-adjust":0,"font-stretch":0,"font-style":0,"font-variant":0,"font-weight":0,"glyph-orientation-horizontal":0,"glyph-orientation-vertical":0,"image-rendering":0,kerning:0,"letter-spacing":0,"lighting-color":0,marker:0,"marker-end":0,"marker-mid":0,"marker-start":0,mask:0,opacity:0,overflow:0,"pointer-events":0,"shape-rendering":0,"stop-color":0,"stop-opacity":0,stroke:0,"stroke-dasharray":0,"stroke-dashoffset":0,"stroke-linecap":0,"stroke-linejoin":0,"stroke-miterlimit":0,"stroke-opacity":0,"stroke-width":0,"text-anchor":0,"text-decoration":0,"text-rendering":0,"unicode-bidi":0,visibility:0,"word-spacing":0,"writing-mode":0};b.on("snap.util.attr",function(a){var c=b.nt(),e={};c=c.substring(c.lastIndexOf(".")+1),e[c]=a;var f=c.replace(/-(\w)/gi,function(a,b){return b.toUpperCase()}),g=c.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()});bb[z](g)?this.node.style[f]=null==a?I:a:d(this.node,e)}),function(){}(v.prototype),c.ajax=function(a,c,d,f){var g=new XMLHttpRequest,h=S();if(g){if(e(c,"function"))f=d,d=c,c=null;else if(e(c,"object")){var i=[];for(var j in c)c.hasOwnProperty(j)&&i.push(encodeURIComponent(j)+"="+encodeURIComponent(c[j]));c=i.join("&")}return g.open(c?"POST":"GET",a,!0),c&&(g.setRequestHeader("X-Requested-With","XMLHttpRequest"),g.setRequestHeader("Content-type","application/x-www-form-urlencoded")),d&&(b.once("snap.ajax."+h+".0",d),b.once("snap.ajax."+h+".200",d),b.once("snap.ajax."+h+".304",d)),g.onreadystatechange=function(){4==g.readyState&&b("snap.ajax."+h+"."+g.status,f,g)},4==g.readyState?g:(g.send(c),g)}},c.load=function(a,b,d){c.ajax(a,function(a){var e=c.parse(a.responseText);d?b.call(d,e):b(e)})};var cb=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,h=e.clientLeft||d.clientLeft||0,i=b.top+(g.win.pageYOffset||e.scrollTop||d.scrollTop)-f,j=b.left+(g.win.pageXOffset||e.scrollLeft||d.scrollLeft)-h;return{y:i,x:j}};return c.getElementByPoint=function(a,b){var c=this,d=(c.canvas,y.doc.elementFromPoint(a,b));if(y.win.opera&&"svg"==d.tagName){var e=cb(d),f=d.createSVGRect();f.x=a-e.x,f.y=b-e.y,f.width=f.height=1;var g=d.getIntersectionList(f,null);g.length&&(d=g[g.length-1])}return d?w(d):null},c.plugin=function(a){a(c,s,v,y,t)},y.win.Snap=c,c}(a||this);return d.plugin(function(d,e,f,g,h){function i(a,b){if(null==b){var c=!0;if(b=a.node.getAttribute("linearGradient"==a.type||"radialGradient"==a.type?"gradientTransform":"pattern"==a.type?"patternTransform":"transform"),!b)return new d.Matrix;b=d._.svgTransform2string(b)}else b=d._.rgTransform.test(b)?o(b).replace(/\.{3}|\u2026/g,a._.transform||""):d._.svgTransform2string(b),n(b,"array")&&(b=d.path?d.path.toString.call(b):o(b)),a._.transform=b;var e=d._.transform2matrix(b,a.getBBox(1));return c?e:void(a.matrix=e)}function j(a){function b(a,b){var c=q(a.node,b);c=c&&c.match(f),c=c&&c[2],c&&"#"==c.charAt()&&(c=c.substring(1),c&&(h[c]=(h[c]||[]).concat(function(c){var d={};d[b]=URL(c),q(a.node,d)})))}function c(a){var b=q(a.node,"xlink:href");b&&"#"==b.charAt()&&(b=b.substring(1),b&&(h[b]=(h[b]||[]).concat(function(b){a.attr("xlink:href","#"+b)})))}for(var d,e=a.selectAll("*"),f=/^\s*url\(("|'|)(.*)\1\)\s*$/,g=[],h={},i=0,j=e.length;j>i;i++){d=e[i],b(d,"fill"),b(d,"stroke"),b(d,"filter"),b(d,"mask"),b(d,"clip-path"),c(d);var k=q(d.node,"id");k&&(q(d.node,{id:d.id}),g.push({old:k,id:d.id}))}for(i=0,j=g.length;j>i;i++){var l=h[g[i].old];if(l)for(var m=0,n=l.length;n>m;m++)l[m](g[i].id)}}function k(a,b,c){return function(d){var e=d.slice(a,b);return 1==e.length&&(e=e[0]),c?c(e):e}}function l(a){return function(){var b=a?"<"+this.type:"",c=this.node.attributes,d=this.node.childNodes;if(a)for(var e=0,f=c.length;f>e;e++)b+=" "+c[e].name+'="'+c[e].value.replace(/"/g,'\\"')+'"';if(d.length){for(a&&(b+=">"),e=0,f=d.length;f>e;e++)3==d[e].nodeType?b+=d[e].nodeValue:1==d[e].nodeType&&(b+=u(d[e]).toString());a&&(b+="")}else a&&(b+="/>");return b}}var m=e.prototype,n=d.is,o=String,p=d._unit2px,q=d._.$,r=d._.make,s=d._.getSomeDefs,t="hasOwnProperty",u=d._.wrap;m.getBBox=function(a){if(!d.Matrix||!d.path)return this.node.getBBox();var b=this,c=new d.Matrix;if(b.removed)return d._.box();for(;"use"==b.type;)if(a||(c=c.add(b.transform().localMatrix.translate(b.attr("x")||0,b.attr("y")||0))),b.original)b=b.original;else{var e=b.attr("xlink:href");b=b.original=b.node.ownerDocument.getElementById(e.substring(e.indexOf("#")+1))}var f=b._,g=d.path.get[b.type]||d.path.get.deflt;try{return a?(f.bboxwt=g?d.path.getBBox(b.realPath=g(b)):d._.box(b.node.getBBox()),d._.box(f.bboxwt)):(b.realPath=g(b),b.matrix=b.transform().localMatrix,f.bbox=d.path.getBBox(d.path.map(b.realPath,c.add(b.matrix))),d._.box(f.bbox))}catch(h){return d._.box()}};var v=function(){return this.string};m.transform=function(a){var b=this._;if(null==a){for(var c,e=this,f=new d.Matrix(this.node.getCTM()),g=i(this),h=[g],j=new d.Matrix,k=g.toTransformString(),l=o(g)==o(this.matrix)?o(b.transform):k;"svg"!=e.type&&(e=e.parent());)h.push(i(e));for(c=h.length;c--;)j.add(h[c]);return{string:l,globalMatrix:f,totalMatrix:j,localMatrix:g,diffMatrix:f.clone().add(g.invert()),global:f.toTransformString(),total:j.toTransformString(),local:k,toString:v}}return a instanceof d.Matrix?(this.matrix=a,this._.transform=a.toTransformString()):i(this,a),this.node&&("linearGradient"==this.type||"radialGradient"==this.type?q(this.node,{gradientTransform:this.matrix}):"pattern"==this.type?q(this.node,{patternTransform:this.matrix}):q(this.node,{transform:this.matrix})),this},m.parent=function(){return u(this.node.parentNode)},m.append=m.add=function(a){if(a){if("set"==a.type){var b=this;return a.forEach(function(a){b.add(a)}),this}a=u(a),this.node.appendChild(a.node),a.paper=this.paper}return this},m.appendTo=function(a){return a&&(a=u(a),a.append(this)),this},m.prepend=function(a){if(a){if("set"==a.type){var b,c=this;return a.forEach(function(a){b?b.after(a):c.prepend(a),b=a}),this}a=u(a);var d=a.parent();this.node.insertBefore(a.node,this.node.firstChild),this.add&&this.add(),a.paper=this.paper,this.parent()&&this.parent().add(),d&&d.add()}return this},m.prependTo=function(a){return a=u(a),a.prepend(this),this},m.before=function(a){if("set"==a.type){var b=this;return a.forEach(function(a){var c=a.parent();b.node.parentNode.insertBefore(a.node,b.node),c&&c.add()}),this.parent().add(),this}a=u(a);var c=a.parent();return this.node.parentNode.insertBefore(a.node,this.node),this.parent()&&this.parent().add(),c&&c.add(),a.paper=this.paper,this},m.after=function(a){a=u(a);var b=a.parent();return this.node.nextSibling?this.node.parentNode.insertBefore(a.node,this.node.nextSibling):this.node.parentNode.appendChild(a.node),this.parent()&&this.parent().add(),b&&b.add(),a.paper=this.paper,this},m.insertBefore=function(a){a=u(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},m.insertAfter=function(a){a=u(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node.nextSibling),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},m.remove=function(){var a=this.parent();return this.node.parentNode&&this.node.parentNode.removeChild(this.node),delete this.paper,this.removed=!0,a&&a.add(),this},m.select=function(a){return u(this.node.querySelector(a))},m.selectAll=function(a){for(var b=this.node.querySelectorAll(a),c=(d.set||Array)(),e=0;eb;b++)a[b].stop();return this},m.animate=function(a,d,e,f){"function"!=typeof e||e.length||(f=e,e=c.linear),a instanceof w&&(f=a.callback,e=a.easing,d=a.dur,a=a.attr);var g,h,i,j,l=[],m=[],p={},q=this;for(var r in a)if(a[t](r)){q.equal?(j=q.equal(r,o(a[r])),g=j.from,h=j.to,i=j.f):(g=+q.attr(r),h=+a[r]);var s=n(g,"array")?g.length:1;p[r]=k(l.length,l.length+s,i),l=l.concat(g),m=m.concat(h)}var u=c.time(),v=c(l,m,u,u+d,c.time,function(a){var b={};for(var c in p)p[t](c)&&(b[c]=p[c](a));q.attr(b)},e);return q.anims[v.id]=v,v._attrs=a,v._callback=f,b("snap.animcreated."+q.id,v),b.once("mina.finish."+v.id,function(){delete q.anims[v.id],f&&f.call(q)}),b.once("mina.stop."+v.id,function(){delete q.anims[v.id]}),q};var x={};m.data=function(a,c){var e=x[this.id]=x[this.id]||{};if(0==arguments.length)return b("snap.data.get."+this.id,this,e,null),e; -if(1==arguments.length){if(d.is(a,"object")){for(var f in a)a[t](f)&&this.data(f,a[f]);return this}return b("snap.data.get."+this.id,this,e[a],a),e[a]}return e[a]=c,b("snap.data.set."+this.id,this,c,a),this},m.removeData=function(a){return null==a?x[this.id]={}:x[this.id]&&delete x[this.id][a],this},m.outerSVG=m.toString=l(1),m.innerSVG=l(),m.toDataURL=function(){if(a&&a.btoa){var b=this.getBBox(),c=d.format('{contents}',{x:+b.x.toFixed(3),y:+b.y.toFixed(3),width:+b.width.toFixed(3),height:+b.height.toFixed(3),contents:this.outerSVG()});return"data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(c)))}},h.prototype.select=m.select,h.prototype.selectAll=m.selectAll}),d.plugin(function(a){function b(a,b,d,e,f,g){return null==b&&"[object SVGMatrix]"==c.call(a)?(this.a=a.a,this.b=a.b,this.c=a.c,this.d=a.d,this.e=a.e,void(this.f=a.f)):void(null!=a?(this.a=+a,this.b=+b,this.c=+d,this.d=+e,this.e=+f,this.f=+g):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0))}var c=Object.prototype.toString,d=String,e=Math,f="";!function(c){function g(a){return a[0]*a[0]+a[1]*a[1]}function h(a){var b=e.sqrt(g(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)}c.add=function(a,c,d,e,f,g){var h,i,j,k,l=[[],[],[]],m=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],n=[[a,d,f],[c,e,g],[0,0,1]];for(a&&a instanceof b&&(n=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),h=0;3>h;h++)for(i=0;3>i;i++){for(k=0,j=0;3>j;j++)k+=m[h][j]*n[j][i];l[h][i]=k}return this.a=l[0][0],this.b=l[1][0],this.c=l[0][1],this.d=l[1][1],this.e=l[0][2],this.f=l[1][2],this},c.invert=function(){var a=this,c=a.a*a.d-a.b*a.c;return new b(a.d/c,-a.b/c,-a.c/c,a.a/c,(a.c*a.f-a.d*a.e)/c,(a.b*a.e-a.a*a.f)/c)},c.clone=function(){return new b(this.a,this.b,this.c,this.d,this.e,this.f)},c.translate=function(a,b){return this.add(1,0,0,1,a,b)},c.scale=function(a,b,c,d){return null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d),this},c.rotate=function(b,c,d){b=a.rad(b),c=c||0,d=d||0;var f=+e.cos(b).toFixed(9),g=+e.sin(b).toFixed(9);return this.add(f,g,-g,f,c,d),this.add(1,0,0,1,-c,-d)},c.x=function(a,b){return a*this.a+b*this.c+this.e},c.y=function(a,b){return a*this.b+b*this.d+this.f},c.get=function(a){return+this[d.fromCharCode(97+a)].toFixed(4)},c.toString=function(){return"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")"},c.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},c.determinant=function(){return this.a*this.d-this.b*this.c},c.split=function(){var b={};b.dx=this.e,b.dy=this.f;var c=[[this.a,this.c],[this.b,this.d]];b.scalex=e.sqrt(g(c[0])),h(c[0]),b.shear=c[0][0]*c[1][0]+c[0][1]*c[1][1],c[1]=[c[1][0]-c[0][0]*b.shear,c[1][1]-c[0][1]*b.shear],b.scaley=e.sqrt(g(c[1])),h(c[1]),b.shear/=b.scaley,this.determinant()<0&&(b.scalex=-b.scalex);var d=-c[0][1],f=c[1][1];return 0>f?(b.rotate=a.deg(e.acos(f)),0>d&&(b.rotate=360-b.rotate)):b.rotate=a.deg(e.asin(d)),b.isSimple=!(+b.shear.toFixed(9)||b.scalex.toFixed(9)!=b.scaley.toFixed(9)&&b.rotate),b.isSuperSimple=!+b.shear.toFixed(9)&&b.scalex.toFixed(9)==b.scaley.toFixed(9)&&!b.rotate,b.noRotation=!+b.shear.toFixed(9)&&!b.rotate,b},c.toTransformString=function(a){var b=a||this.split();return+b.shear.toFixed(9)?"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]:(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[+b.dx.toFixed(4),+b.dy.toFixed(4)]:f)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:f)+(b.rotate?"r"+[+b.rotate.toFixed(4),0,0]:f))}}(b.prototype),a.Matrix=b,a.matrix=function(a,c,d,e,f,g){return new b(a,c,d,e,f,g)}}),d.plugin(function(a,c,d,e,f){function g(d){return function(e){if(b.stop(),e instanceof f&&1==e.node.childNodes.length&&("radialGradient"==e.node.firstChild.tagName||"linearGradient"==e.node.firstChild.tagName||"pattern"==e.node.firstChild.tagName)&&(e=e.node.firstChild,n(this).appendChild(e),e=l(e)),e instanceof c)if("radialGradient"==e.type||"linearGradient"==e.type||"pattern"==e.type){e.node.id||p(e.node,{id:e.id});var g=q(e.node.id)}else g=e.attr(d);else if(g=a.color(e),g.error){var h=a(n(this).ownerSVGElement).gradient(e);h?(h.node.id||p(h.node,{id:h.id}),g=q(h.node.id)):g=e}else g=r(g);var i={};i[d]=g,p(this.node,i),this.node.style[d]=t}}function h(a){b.stop(),a==+a&&(a+="px"),this.node.style.fontSize=a}function i(a){for(var b=[],c=a.childNodes,d=0,e=c.length;e>d;d++){var f=c[d];3==f.nodeType&&b.push(f.nodeValue),"tspan"==f.tagName&&b.push(1==f.childNodes.length&&3==f.firstChild.nodeType?f.firstChild.nodeValue:i(f))}return b}function j(){return b.stop(),this.node.style.fontSize}var k=a._.make,l=a._.wrap,m=a.is,n=a._.getSomeDefs,o=/^url\(#?([^)]+)\)$/,p=a._.$,q=a.url,r=String,s=a._.separator,t="";b.on("snap.util.attr.mask",function(a){if(a instanceof c||a instanceof f){if(b.stop(),a instanceof f&&1==a.node.childNodes.length&&(a=a.node.firstChild,n(this).appendChild(a),a=l(a)),"mask"==a.type)var d=a;else d=k("mask",n(this)),d.node.appendChild(a.node);!d.node.id&&p(d.node,{id:d.id}),p(this.node,{mask:q(d.id)})}}),function(a){b.on("snap.util.attr.clip",a),b.on("snap.util.attr.clip-path",a),b.on("snap.util.attr.clipPath",a)}(function(a){if(a instanceof c||a instanceof f){if(b.stop(),"clipPath"==a.type)var d=a;else d=k("clipPath",n(this)),d.node.appendChild(a.node),!d.node.id&&p(d.node,{id:d.id});p(this.node,{"clip-path":q(d.node.id||d.id)})}}),b.on("snap.util.attr.fill",g("fill")),b.on("snap.util.attr.stroke",g("stroke"));var u=/^([lr])(?:\(([^)]*)\))?(.*)$/i;b.on("snap.util.grad.parse",function(a){a=r(a);var b=a.match(u);if(!b)return null;var c=b[1],d=b[2],e=b[3];return d=d.split(/\s*,\s*/).map(function(a){return+a==a?+a:a}),1==d.length&&0==d[0]&&(d=[]),e=e.split("-"),e=e.map(function(a){a=a.split(":");var b={color:a[0]};return a[1]&&(b.offset=parseFloat(a[1])),b}),{type:c,params:d,stops:e}}),b.on("snap.util.attr.d",function(c){b.stop(),m(c,"array")&&m(c[0],"array")&&(c=a.path.toString.call(c)),c=r(c),c.match(/[ruo]/i)&&(c=a.path.toAbsolute(c)),p(this.node,{d:c})})(-1),b.on("snap.util.attr.#text",function(a){b.stop(),a=r(a);for(var c=e.doc.createTextNode(a);this.node.firstChild;)this.node.removeChild(this.node.firstChild);this.node.appendChild(c)})(-1),b.on("snap.util.attr.path",function(a){b.stop(),this.attr({d:a})})(-1),b.on("snap.util.attr.class",function(a){b.stop(),this.node.className.baseVal=a})(-1),b.on("snap.util.attr.viewBox",function(a){var c;c=m(a,"object")&&"x"in a?[a.x,a.y,a.width,a.height].join(" "):m(a,"array")?a.join(" "):a,p(this.node,{viewBox:c}),b.stop()})(-1),b.on("snap.util.attr.transform",function(a){this.transform(a),b.stop()})(-1),b.on("snap.util.attr.r",function(a){"rect"==this.type&&(b.stop(),p(this.node,{rx:a,ry:a}))})(-1),b.on("snap.util.attr.textpath",function(a){if(b.stop(),"text"==this.type){var d,e,f;if(!a&&this.textPath){for(e=this.textPath;e.node.firstChild;)this.node.appendChild(e.node.firstChild);return e.remove(),void delete this.textPath}if(m(a,"string")){var g=n(this),h=l(g.parentNode).path(a);g.appendChild(h.node),d=h.id,h.attr({id:d})}else a=l(a),a instanceof c&&(d=a.attr("id"),d||(d=a.id,a.attr({id:d})));if(d)if(e=this.textPath,f=this.node,e)e.attr({"xlink:href":"#"+d});else{for(e=p("textPath",{"xlink:href":"#"+d});f.firstChild;)e.appendChild(f.firstChild);f.appendChild(e),this.textPath=l(e)}}})(-1),b.on("snap.util.attr.text",function(a){if("text"==this.type){for(var c=this.node,d=function(a){var b=p("tspan");if(m(a,"array"))for(var c=0;c1&&(a=Array.prototype.slice.call(arguments,0));var b={};return h(a,"object")&&!h(a,"array")?b=a:null!=a&&(b={points:a}),this.el("polyline",b)},g.polygon=function(a){arguments.length>1&&(a=Array.prototype.slice.call(arguments,0));var b={};return h(a,"object")&&!h(a,"array")?b=a:null!=a&&(b={points:a}),this.el("polygon",b)},function(){function d(){return this.selectAll("stop")}function e(a,b){var d=k("stop"),e={offset:+b+"%"};return a=c.color(a),e["stop-color"]=a.hex,a.opacity<1&&(e["stop-opacity"]=a.opacity),k(d,e),this.node.appendChild(d),this}function f(){if("linearGradient"==this.type){var a=k(this.node,"x1")||0,b=k(this.node,"x2")||1,d=k(this.node,"y1")||0,e=k(this.node,"y2")||0;return c._.box(a,d,math.abs(b-a),math.abs(e-d))}var f=this.node.cx||.5,g=this.node.cy||.5,h=this.node.r||0;return c._.box(f-h,g-h,2*h,2*h)}function h(a,c){function d(a,b){for(var c=(b-l)/(a-m),d=m;a>d;d++)g[d].offset=+(+l+c*(d-m)).toFixed(2);m=a,l=b}var e,f=b("snap.util.grad.parse",null,c).firstDefined();if(!f)return null;f.params.unshift(a),e="l"==f.type.toLowerCase()?i.apply(0,f.params):j.apply(0,f.params),f.type!=f.type.toLowerCase()&&k(e.node,{gradientUnits:"userSpaceOnUse"});var g=f.stops,h=g.length,l=0,m=0;h--;for(var n=0;h>n;n++)"offset"in g[n]&&d(n,g[n].offset);for(g[h].offset=g[h].offset||100,d(h,g[h].offset),n=0;h>=n;n++){var o=g[n];e.addStop(o.color,o.offset)}return e}function i(a,b,g,h,i){var j=c._.make("linearGradient",a);return j.stops=d,j.addStop=e,j.getBBox=f,null!=b&&k(j.node,{x1:b,y1:g,x2:h,y2:i}),j}function j(a,b,g,h,i,j){var l=c._.make("radialGradient",a);return l.stops=d,l.addStop=e,l.getBBox=f,null!=b&&k(l.node,{cx:b,cy:g,r:h}),null!=i&&null!=j&&k(l.node,{fx:i,fy:j}),l}var k=c._.$;g.gradient=function(a){return h(this.defs,a)},g.gradientLinear=function(a,b,c,d){return i(this.defs,a,b,c,d)},g.gradientRadial=function(a,b,c,d,e){return j(this.defs,a,b,c,d,e)},g.toString=function(){var a,b=this.node.ownerDocument,d=b.createDocumentFragment(),e=b.createElement("div"),f=this.node.cloneNode(!0);return d.appendChild(e),e.appendChild(f),c._.$(f,{xmlns:"http://www.w3.org/2000/svg"}),a=e.innerHTML,d.removeChild(d.firstChild),a},g.toDataURL=function(){return a&&a.btoa?"data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(this))):void 0},g.clear=function(){for(var a,b=this.node.firstChild;b;)a=b.nextSibling,"defs"!=b.tagName?b.parentNode.removeChild(b):g.clear.call({node:b}),b=a}}()}),d.plugin(function(a,b){function c(a){var b=c.ps=c.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[K](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]}function d(a,b,c,d){return null==a&&(a=b=c=d=0),null==b&&(b=a.y,c=a.width,d=a.height,a=a.x),{x:a,y:b,width:c,w:c,height:d,h:d,x2:a+c,y2:b+d,cx:a+c/2,cy:b+d/2,r1:N.min(c,d)/2,r2:N.max(c,d)/2,r0:N.sqrt(c*c+d*d)/2,path:w(a,b,c,d),vb:[a,b,c,d].join(" ")}}function e(){return this.join(",").replace(L,"$1")}function f(a){var b=J(a);return b.toString=e,b}function g(a,b,c,d,e,f,g,h,j){return null==j?n(a,b,c,d,e,f,g,h):i(a,b,c,d,e,f,g,h,o(a,b,c,d,e,f,g,h,j))}function h(c,d){function e(a){return+(+a).toFixed(3)}return a._.cacher(function(a,f,h){a instanceof b&&(a=a.attr("d")),a=E(a);for(var j,k,l,m,n,o="",p={},q=0,r=0,s=a.length;s>r;r++){if(l=a[r],"M"==l[0])j=+l[1],k=+l[2];else{if(m=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6]),q+m>f){if(d&&!p.start){if(n=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6],f-q),o+=["C"+e(n.start.x),e(n.start.y),e(n.m.x),e(n.m.y),e(n.x),e(n.y)],h)return o;p.start=o,o=["M"+e(n.x),e(n.y)+"C"+e(n.n.x),e(n.n.y),e(n.end.x),e(n.end.y),e(l[5]),e(l[6])].join(),q+=m,j=+l[5],k=+l[6];continue}if(!c&&!d)return n=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6],f-q)}q+=m,j=+l[5],k=+l[6]}o+=l.shift()+l}return p.end=o,n=c?q:d?p:i(j,k,l[0],l[1],l[2],l[3],l[4],l[5],1)},null,a._.clone)}function i(a,b,c,d,e,f,g,h,i){var j=1-i,k=R(j,3),l=R(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*N.atan2(q-s,r-t)/O;return{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}}function j(b,c,e,f,g,h,i,j){a.is(b,"array")||(b=[b,c,e,f,g,h,i,j]);var k=D.apply(null,b);return d(k.min.x,k.min.y,k.max.x-k.min.x,k.max.y-k.min.y)}function k(a,b,c){return b>=a.x&&b<=a.x+a.width&&c>=a.y&&c<=a.y+a.height}function l(a,b){return a=d(a),b=d(b),k(b,a.x,a.y)||k(b,a.x2,a.y)||k(b,a.x,a.y2)||k(b,a.x2,a.y2)||k(a,b.x,b.y)||k(a,b.x2,b.y)||k(a,b.x,b.y2)||k(a,b.x2,b.y2)||(a.xb.x||b.xa.x)&&(a.yb.y||b.ya.y)}function m(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function n(a,b,c,d,e,f,g,h,i){null==i&&(i=1),i=i>1?1:0>i?0:i;for(var j=i/2,k=12,l=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;k>p;p++){var q=j*l[p]+j,r=m(q,a,c,e,g),s=m(q,b,d,f,h),t=r*r+s*s;o+=n[p]*N.sqrt(t)}return j*o}function o(a,b,c,d,e,f,g,h,i){if(!(0>i||n(a,b,c,d,e,f,g,h)o;)l/=2,m+=(i>j?1:-1)*l,j=n(a,b,c,d,e,f,g,h,m);return m}}function p(a,b,c,d,e,f,g,h){if(!(Q(a,c)Q(e,g)||Q(b,d)Q(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+P(a,c).toFixed(2)||n>+Q(a,c).toFixed(2)||n<+P(e,g).toFixed(2)||n>+Q(e,g).toFixed(2)||o<+P(b,d).toFixed(2)||o>+Q(b,d).toFixed(2)||o<+P(f,h).toFixed(2)||o>+Q(f,h).toFixed(2)))return{x:l,y:m}}}}function q(a,b,c){var d=j(a),e=j(b);if(!l(d,e))return c?0:[];for(var f=n.apply(0,a),g=n.apply(0,b),h=~~(f/8),k=~~(g/8),m=[],o=[],q={},r=c?0:[],s=0;h+1>s;s++){var t=i.apply(0,a.concat(s/h));m.push({x:t.x,y:t.y,t:s/h})}for(s=0;k+1>s;s++)t=i.apply(0,b.concat(s/k)),o.push({x:t.x,y:t.y,t:s/k});for(s=0;h>s;s++)for(var u=0;k>u;u++){var v=m[s],w=m[s+1],x=o[u],y=o[u+1],z=S(w.x-v.x)<.001?"y":"x",A=S(y.x-x.x)<.001?"y":"x",B=p(v.x,v.y,w.x,w.y,x.x,x.y,y.x,y.y);if(B){if(q[B.x.toFixed(4)]==B.y.toFixed(4))continue;q[B.x.toFixed(4)]=B.y.toFixed(4);var C=v.t+S((B[z]-v[z])/(w[z]-v[z]))*(w.t-v.t),D=x.t+S((B[A]-x[A])/(y[A]-x[A]))*(y.t-x.t);C>=0&&1>=C&&D>=0&&1>=D&&(c?r++:r.push({x:B.x,y:B.y,t1:C,t2:D}))}}return r}function r(a,b){return t(a,b)}function s(a,b){return t(a,b,1)}function t(a,b,c){a=E(a),b=E(b);for(var d,e,f,g,h,i,j,k,l,m,n=c?0:[],o=0,p=a.length;p>o;o++){var r=a[o];if("M"==r[0])d=h=r[1],e=i=r[2];else{"C"==r[0]?(l=[d,e].concat(r.slice(1)),d=l[6],e=l[7]):(l=[d,e,d,e,h,i,h,i],d=h,e=i);for(var s=0,t=b.length;t>s;s++){var u=b[s];if("M"==u[0])f=j=u[1],g=k=u[2];else{"C"==u[0]?(m=[f,g].concat(u.slice(1)),f=m[6],g=m[7]):(m=[f,g,f,g,j,k,j,k],f=j,g=k);var v=q(l,m,c);if(c)n+=v;else{for(var w=0,x=v.length;x>w;w++)v[w].segment1=o,v[w].segment2=s,v[w].bez1=l,v[w].bez2=m;n=n.concat(v)}}}}}return n}function u(a,b,c){var d=v(a);return k(d,b,c)&&t(a,[["M",b,c],["H",d.x2+10]],1)%2==1}function v(a){var b=c(a);if(b.bbox)return J(b.bbox);if(!a)return d();a=E(a);for(var e,f=0,g=0,h=[],i=[],j=0,k=a.length;k>j;j++)if(e=a[j],"M"==e[0])f=e[1],g=e[2],h.push(f),i.push(g);else{var l=D(f,g,e[1],e[2],e[3],e[4],e[5],e[6]);h=h.concat(l.min.x,l.max.x),i=i.concat(l.min.y,l.max.y),f=e[5],g=e[6]}var m=P.apply(0,h),n=P.apply(0,i),o=Q.apply(0,h),p=Q.apply(0,i),q=d(m,n,o-m,p-n);return b.bbox=J(q),q}function w(a,b,c,d,f){if(f)return[["M",+a+ +f,b],["l",c-2*f,0],["a",f,f,0,0,1,f,f],["l",0,d-2*f],["a",f,f,0,0,1,-f,f],["l",2*f-c,0],["a",f,f,0,0,1,-f,-f],["l",0,2*f-d],["a",f,f,0,0,1,f,-f],["z"]];var g=[["M",a,b],["l",c,0],["l",0,d],["l",-c,0],["z"]];return g.toString=e,g}function x(a,b,c,d,f){if(null==f&&null==d&&(d=c),a=+a,b=+b,c=+c,d=+d,null!=f)var g=Math.PI/180,h=a+c*Math.cos(-d*g),i=a+c*Math.cos(-f*g),j=b+c*Math.sin(-d*g),k=b+c*Math.sin(-f*g),l=[["M",h,j],["A",c,c,0,+(f-d>180),0,i,k]];else l=[["M",a,b],["m",0,-d],["a",c,d,0,1,1,0,2*d],["a",c,d,0,1,1,0,-2*d],["z"]];return l.toString=e,l}function y(b){var d=c(b),g=String.prototype.toLowerCase;if(d.rel)return f(d.rel);a.is(b,"array")&&a.is(b&&b[0],"array")||(b=a.parsePathString(b));var h=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=b[0][1],j=b[0][2],k=i,l=j,m++,h.push(["M",i,j]));for(var n=m,o=b.length;o>n;n++){var p=h[n]=[],q=b[n];if(q[0]!=g.call(q[0]))switch(p[0]=g.call(q[0]),p[0]){case"a":p[1]=q[1],p[2]=q[2],p[3]=q[3],p[4]=q[4],p[5]=q[5],p[6]=+(q[6]-i).toFixed(3),p[7]=+(q[7]-j).toFixed(3);break;case"v":p[1]=+(q[1]-j).toFixed(3);break;case"m":k=q[1],l=q[2];default:for(var r=1,s=q.length;s>r;r++)p[r]=+(q[r]-(r%2?i:j)).toFixed(3)}else{p=h[n]=[],"m"==q[0]&&(k=q[1]+i,l=q[2]+j);for(var t=0,u=q.length;u>t;t++)h[n][t]=q[t]}var v=h[n].length;switch(h[n][0]){case"z":i=k,j=l;break;case"h":i+=+h[n][v-1];break;case"v":j+=+h[n][v-1];break;default:i+=+h[n][v-2],j+=+h[n][v-1]}}return h.toString=e,d.rel=f(h),h}function z(b){var d=c(b);if(d.abs)return f(d.abs);if(I(b,"array")&&I(b&&b[0],"array")||(b=a.parsePathString(b)),!b||!b.length)return[["M",0,0]];var g,h=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=+b[0][1],j=+b[0][2],k=i,l=j,m++,h[0]=["M",i,j]);for(var n,o,p=3==b.length&&"M"==b[0][0]&&"R"==b[1][0].toUpperCase()&&"Z"==b[2][0].toUpperCase(),q=m,r=b.length;r>q;q++){if(h.push(n=[]),o=b[q],g=o[0],g!=g.toUpperCase())switch(n[0]=g.toUpperCase(),n[0]){case"A":n[1]=o[1],n[2]=o[2],n[3]=o[3],n[4]=o[4],n[5]=o[5],n[6]=+o[6]+i,n[7]=+o[7]+j;break;case"V":n[1]=+o[1]+j;break;case"H":n[1]=+o[1]+i;break;case"R":for(var s=[i,j].concat(o.slice(1)),t=2,u=s.length;u>t;t++)s[t]=+s[t]+i,s[++t]=+s[t]+j;h.pop(),h=h.concat(G(s,p));break;case"O":h.pop(),s=x(i,j,o[1],o[2]),s.push(s[0]),h=h.concat(s);break;case"U":h.pop(),h=h.concat(x(i,j,o[1],o[2],o[3])),n=["U"].concat(h[h.length-1].slice(-2));break;case"M":k=+o[1]+i,l=+o[2]+j;default:for(t=1,u=o.length;u>t;t++)n[t]=+o[t]+(t%2?i:j)}else if("R"==g)s=[i,j].concat(o.slice(1)),h.pop(),h=h.concat(G(s,p)),n=["R"].concat(o.slice(-2));else if("O"==g)h.pop(),s=x(i,j,o[1],o[2]),s.push(s[0]),h=h.concat(s);else if("U"==g)h.pop(),h=h.concat(x(i,j,o[1],o[2],o[3])),n=["U"].concat(h[h.length-1].slice(-2));else for(var v=0,w=o.length;w>v;v++)n[v]=o[v];if(g=g.toUpperCase(),"O"!=g)switch(n[0]){case"Z":i=+k,j=+l;break;case"H":i=n[1];break;case"V":j=n[1];break;case"M":k=n[n.length-2],l=n[n.length-1];default:i=n[n.length-2],j=n[n.length-1]}}return h.toString=e,d.abs=f(h),h}function A(a,b,c,d){return[a,b,c,d,c,d]}function B(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]}function C(b,c,d,e,f,g,h,i,j,k){var l,m=120*O/180,n=O/180*(+f||0),o=[],p=a._.cacher(function(a,b,c){var d=a*N.cos(c)-b*N.sin(c),e=a*N.sin(c)+b*N.cos(c);return{x:d,y:e}});if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(b,c,-n),b=l.x,c=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(N.cos(O/180*f),N.sin(O/180*f),(b-i)/2),r=(c-j)/2,s=q*q/(d*d)+r*r/(e*e);s>1&&(s=N.sqrt(s),d=s*d,e=s*e);var t=d*d,u=e*e,v=(g==h?-1:1)*N.sqrt(S((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*d*r/e+(b+i)/2,x=v*-e*q/d+(c+j)/2,y=N.asin(((c-x)/e).toFixed(9)),z=N.asin(((j-x)/e).toFixed(9));y=w>b?O-y:y,z=w>i?O-z:z,0>y&&(y=2*O+y),0>z&&(z=2*O+z),h&&y>z&&(y-=2*O),!h&&z>y&&(z-=2*O)}var A=z-y;if(S(A)>m){var B=z,D=i,E=j;z=y+m*(h&&z>y?1:-1),i=w+d*N.cos(z),j=x+e*N.sin(z),o=C(i,j,d,e,f,0,h,D,E,[z,B,w,x])}A=z-y;var F=N.cos(y),G=N.sin(y),H=N.cos(z),I=N.sin(z),J=N.tan(A/4),K=4/3*d*J,L=4/3*e*J,M=[b,c],P=[b+K*G,c-L*F],Q=[i+K*I,j-L*H],R=[i,j];if(P[0]=2*M[0]-P[0],P[1]=2*M[1]-P[1],k)return[P,Q,R].concat(o);o=[P,Q,R].concat(o).join().split(",");for(var T=[],U=0,V=o.length;V>U;U++)T[U]=U%2?p(o[U-1],o[U],n).y:p(o[U],o[U+1],n).x;return T}function D(a,b,c,d,e,f,g,h){for(var i,j,k,l,m,n,o,p,q=[],r=[[],[]],s=0;2>s;++s)if(0==s?(j=6*a-12*c+6*e,i=-3*a+9*c-9*e+3*g,k=3*c-3*a):(j=6*b-12*d+6*f,i=-3*b+9*d-9*f+3*h,k=3*d-3*b),S(i)<1e-12){if(S(j)<1e-12)continue;l=-k/j,l>0&&1>l&&q.push(l)}else o=j*j-4*k*i,p=N.sqrt(o),0>o||(m=(-j+p)/(2*i),m>0&&1>m&&q.push(m),n=(-j-p)/(2*i),n>0&&1>n&&q.push(n));for(var t,u=q.length,v=u;u--;)l=q[u],t=1-l,r[0][u]=t*t*t*a+3*t*t*l*c+3*t*l*l*e+l*l*l*g,r[1][u]=t*t*t*b+3*t*t*l*d+3*t*l*l*f+l*l*l*h;return r[0][v]=a,r[1][v]=b,r[0][v+1]=g,r[1][v+1]=h,r[0].length=r[1].length=v+2,{min:{x:P.apply(0,r[0]),y:P.apply(0,r[1])},max:{x:Q.apply(0,r[0]),y:Q.apply(0,r[1])}}}function E(a,b){var d=!b&&c(a);if(!b&&d.curve)return f(d.curve);for(var e=z(a),g=b&&z(b),h={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},i={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},j=(function(a,b,c){var d,e;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"].concat(C.apply(0,[b.x,b.y].concat(a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e].concat(a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"].concat(B(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"].concat(B(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"].concat(A(b.x,b.y,a[1],a[2]));break;case"H":a=["C"].concat(A(b.x,b.y,a[1],b.y));break;case"V":a=["C"].concat(A(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"].concat(A(b.x,b.y,b.X,b.Y))}return a}),k=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)m[b]="A",g&&(n[b]="A"),a.splice(b++,0,["C"].concat(c.splice(0,6)));a.splice(b,1),r=Q(e.length,g&&g.length||0)}},l=function(a,b,c,d,f){a&&b&&"M"==a[f][0]&&"M"!=b[f][0]&&(b.splice(f,0,["M",d.x,d.y]),c.bx=0,c.by=0,c.x=a[f][1],c.y=a[f][2],r=Q(e.length,g&&g.length||0))},m=[],n=[],o="",p="",q=0,r=Q(e.length,g&&g.length||0);r>q;q++){e[q]&&(o=e[q][0]),"C"!=o&&(m[q]=o,q&&(p=m[q-1])),e[q]=j(e[q],h,p),"A"!=m[q]&&"C"==o&&(m[q]="C"),k(e,q),g&&(g[q]&&(o=g[q][0]),"C"!=o&&(n[q]=o,q&&(p=n[q-1])),g[q]=j(g[q],i,p),"A"!=n[q]&&"C"==o&&(n[q]="C"),k(g,q)),l(e,g,h,i,q),l(g,e,i,h,q);var s=e[q],t=g&&g[q],u=s.length,v=g&&t.length;h.x=s[u-2],h.y=s[u-1],h.bx=M(s[u-4])||h.x,h.by=M(s[u-3])||h.y,i.bx=g&&(M(t[v-4])||i.x),i.by=g&&(M(t[v-3])||i.y),i.x=g&&t[v-2],i.y=g&&t[v-1]}return g||(d.curve=f(e)),g?[e,g]:e}function F(a,b){if(!b)return a;var c,d,e,f,g,h,i;for(a=E(a),e=0,g=a.length;g>e;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a}function G(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}var H=b.prototype,I=a.is,J=a._.clone,K="hasOwnProperty",L=/,?([a-z]),?/gi,M=parseFloat,N=Math,O=N.PI,P=N.min,Q=N.max,R=N.pow,S=N.abs,T=h(1),U=h(),V=h(0,1),W=a._unit2px,X={path:function(a){return a.attr("path")},circle:function(a){var b=W(a);return x(b.cx,b.cy,b.r)},ellipse:function(a){var b=W(a);return x(b.cx||0,b.cy||0,b.rx,b.ry)},rect:function(a){var b=W(a);return w(b.x||0,b.y||0,b.width,b.height,b.rx,b.ry)},image:function(a){var b=W(a);return w(b.x||0,b.y||0,b.width,b.height)},line:function(a){return"M"+[a.attr("x1")||0,a.attr("y1")||0,a.attr("x2"),a.attr("y2")]},polyline:function(a){return"M"+a.attr("points")},polygon:function(a){return"M"+a.attr("points")+"z"},deflt:function(a){var b=a.node.getBBox();return w(b.x,b.y,b.width,b.height)}};a.path=c,a.path.getTotalLength=T,a.path.getPointAtLength=U,a.path.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return V(a,b).end;var d=V(a,c,1);return b?V(d,b).end:d},H.getTotalLength=function(){return this.node.getTotalLength?this.node.getTotalLength():void 0},H.getPointAtLength=function(a){return U(this.attr("d"),a)},H.getSubpath=function(b,c){return a.path.getSubpath(this.attr("d"),b,c)},a._.box=d,a.path.findDotsAtSegment=i,a.path.bezierBBox=j,a.path.isPointInsideBBox=k,a.closest=function(b,c,e,f){for(var g=100,h=d(b-g/2,c-g/2,g,g),i=[],j=e[0].hasOwnProperty("x")?function(a){return{x:e[a].x,y:e[a].y}}:function(a){return{x:e[a],y:f[a]}},l=0;1e6>=g&&!l;){for(var m=0,n=e.length;n>m;m++){var o=j(m);if(k(h,o.x,o.y)){l++,i.push(o);break}}l||(g*=2,h=d(b-g/2,c-g/2,g,g))}if(1e6!=g){var p,q=1/0;for(m=0,n=i.length;n>m;m++){var r=a.len(b,c,i[m].x,i[m].y);q>r&&(q=r,i[m].len=r,p=i[m])}return p}},a.path.isBBoxIntersect=l,a.path.intersection=r,a.path.intersectionNumber=s,a.path.isPointInside=u,a.path.getBBox=v,a.path.get=X,a.path.toRelative=y,a.path.toAbsolute=z,a.path.toCubic=E,a.path.map=F,a.path.toString=e,a.path.clone=f}),d.plugin(function(a){var d=Math.max,e=Math.min,f=function(a){if(this.items=[],this.bindings={},this.length=0,this.type="set",a)for(var b=0,c=a.length;c>b;b++)a[b]&&(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},g=f.prototype;g.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],a&&(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},g.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},g.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this},g.animate=function(d,e,f,g){"function"!=typeof f||f.length||(g=f,f=c.linear),d instanceof a._.Animation&&(g=d.callback,f=d.easing,e=f.dur,d=d.attr);var h=arguments;if(a.is(d,"array")&&a.is(h[h.length-1],"array"))var i=!0;var j,k=function(){j?this.b=j:j=this.b},l=0,m=this,n=g&&function(){++l==m.length&&g.call(this) -};return this.forEach(function(a,c){b.once("snap.animcreated."+a.id,k),i?h[c]&&a.animate.apply(a,h[c]):a.animate(d,e,f,n)})},g.remove=function(){for(;this.length;)this.pop().remove();return this},g.bind=function(a,b,c){var d={};if("function"==typeof b)this.bindings[a]=b;else{var e=c||a;this.bindings[a]=function(a){d[e]=a,b.attr(d)}}return this},g.attr=function(a){var b={};for(var c in a)this.bindings[c]?this.bindings[c](a[c]):b[c]=a[c];for(var d=0,e=this.items.length;e>d;d++)this.items[d].attr(b);return this},g.clear=function(){for(;this.length;)this.pop()},g.splice=function(a,b){a=0>a?d(this.length+a,0):a,b=d(0,e(this.length-a,b));var c,g=[],h=[],i=[];for(c=2;cc;c++)h.push(this[a+c]);for(;cc?i[c]:g[c-j];for(c=this.items.length=this.length-=b-j;this[c];)delete this[c++];return new f(h)},g.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0;return!1},g.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},g.getBBox=function(){for(var a=[],b=[],c=[],f=[],g=this.items.length;g--;)if(!this.items[g].removed){var h=this.items[g].getBBox();a.push(h.x),b.push(h.y),c.push(h.x+h.width),f.push(h.y+h.height)}return a=e.apply(0,a),b=e.apply(0,b),c=d.apply(0,c),f=d.apply(0,f),{x:a,y:b,x2:c,y2:f,width:c-a,height:f-b,cx:a+(c-a)/2,cy:b+(f-b)/2}},g.clone=function(a){a=new f;for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},g.toString=function(){return"Snap‘s set"},g.type="set",a.Set=f,a.set=function(){var a=new f;return arguments.length&&a.push.apply(a,Array.prototype.slice.call(arguments,0)),a}}),d.plugin(function(a,c){function d(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}}function e(b,c,e){c=p(c).replace(/\.{3}|\u2026/g,b),b=a.parseTransformString(b)||[],c=a.parseTransformString(c)||[];for(var f,g,h,i,l=Math.max(b.length,c.length),m=[],n=[],o=0;l>o;o++){if(h=b[o]||d(c[o]),i=c[o]||d(h),h[0]!=i[0]||"r"==h[0].toLowerCase()&&(h[2]!=i[2]||h[3]!=i[3])||"s"==h[0].toLowerCase()&&(h[3]!=i[3]||h[4]!=i[4])){b=a._.transform2matrix(b,e()),c=a._.transform2matrix(c,e()),m=[["m",b.a,b.b,b.c,b.d,b.e,b.f]],n=[["m",c.a,c.b,c.c,c.d,c.e,c.f]];break}for(m[o]=[],n[o]=[],f=0,g=Math.max(h.length,i.length);g>f;f++)f in h&&(m[o][f]=h[f]),f in i&&(n[o][f]=i[f])}return{from:k(m),to:k(n),f:j(m)}}function f(a){return a}function g(a){return function(b){return+b.toFixed(3)+a}}function h(a){return a.join(" ")}function i(b){return a.rgb(b[0],b[1],b[2])}function j(a){var b,c,d,e,f,g,h=0,i=[];for(b=0,c=a.length;c>b;b++){for(f="[",g=['"'+a[b][0]+'"'],d=1,e=a[b].length;e>d;d++)g[d]="val["+h++ +"]";f+=g+"]",i[b]=f}return Function("val","return Snap.path.toString.call(["+i+"])")}function k(a){for(var b=[],c=0,d=a.length;d>c;c++)for(var e=1,f=a[c].length;f>e;e++)b.push(a[c][e]);return b}function l(a){return isFinite(parseFloat(a))}function m(b,c){return a.is(b,"array")&&a.is(c,"array")?b.toString()==c.toString():!1}var n={},o=/[a-z]+$/i,p=String;n.stroke=n.fill="colour",c.prototype.equal=function(a,c){return b("snap.util.equal",this,a,c).firstDefined()},b.on("snap.util.equal",function(b,c){var d,q,r=p(this.attr(b)||""),s=this;if(l(r)&&l(c))return{from:parseFloat(r),to:parseFloat(c),f:f};if("colour"==n[b])return d=a.color(r),q=a.color(c),{from:[d.r,d.g,d.b,d.opacity],to:[q.r,q.g,q.b,q.opacity],f:i};if("viewBox"==b)return d=this.attr(b).vb.split(" ").map(Number),q=c.split(" ").map(Number),{from:d,to:q,f:h};if("transform"==b||"gradientTransform"==b||"patternTransform"==b)return c instanceof a.Matrix&&(c=c.toTransformString()),a._.rgTransform.test(c)||(c=a._.svgTransform2string(c)),e(r,c,function(){return s.getBBox(1)});if("d"==b||"path"==b)return d=a.path.toCubic(r,c),{from:k(d[0]),to:k(d[1]),f:j(d[0])};if("points"==b)return d=p(r).split(a._.separator),q=p(c).split(a._.separator),{from:d,to:q,f:function(a){return a}};var t=r.match(o),u=p(c).match(o);return t&&m(t,u)?{from:parseFloat(r),to:parseFloat(c),f:g(t)}:{from:this.asPX(b),to:this.asPX(b,c),f:f}})}),d.plugin(function(a,c,d,e){for(var f=c.prototype,g="hasOwnProperty",h=("createTouch"in e.doc),i=["click","dblclick","mousedown","mousemove","mouseout","mouseover","mouseup","touchstart","touchmove","touchend","touchcancel"],j={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},k=(function(a,b){var c="y"==a?"scrollTop":"scrollLeft",d=b&&b.node?b.node.ownerDocument:e.doc;return d[c in d.documentElement?"documentElement":"body"][c]}),l=function(){return this.originalEvent.preventDefault()},m=function(){return this.originalEvent.stopPropagation()},n=function(a,b,c,d){var e=h&&j[b]?j[b]:b,f=function(e){var f=k("y",d),i=k("x",d);if(h&&j[g](b))for(var n=0,o=e.targetTouches&&e.targetTouches.length;o>n;n++)if(e.targetTouches[n].target==a||a.contains(e.targetTouches[n].target)){var p=e;e=e.targetTouches[n],e.originalEvent=p,e.preventDefault=l,e.stopPropagation=m;break}var q=e.clientX+i,r=e.clientY+f;return c.call(d,e,q,r)};return b!==e&&a.addEventListener(b,f,!1),a.addEventListener(e,f,!1),function(){return b!==e&&a.removeEventListener(b,f,!1),a.removeEventListener(e,f,!1),!0}},o=[],p=function(a){for(var c,d=a.clientX,e=a.clientY,f=k("y"),g=k("x"),i=o.length;i--;){if(c=o[i],h){for(var j,l=a.touches&&a.touches.length;l--;)if(j=a.touches[l],j.identifier==c.el._drag.id||c.el.node.contains(j.target)){d=j.clientX,e=j.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}else a.preventDefault();{var m=c.el.node;m.nextSibling,m.parentNode,m.style.display}d+=g,e+=f,b("snap.drag.move."+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,a)}},q=function(c){a.unmousemove(p).unmouseup(q);for(var d,e=o.length;e--;)d=o[e],d.el._drag={},b("snap.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,c),b.off("snap.drag.*."+d.el.id);o=[]},r=i.length;r--;)!function(b){a[b]=f[b]=function(c,d){if(a.is(c,"function"))this.events=this.events||[],this.events.push({name:b,f:c,unbind:n(this.node||document,b,c,d||this)});else for(var e=0,f=this.events.length;f>e;e++)if(this.events[e].name==b)try{this.events[e].f.call(this)}catch(g){}return this},a["un"+b]=f["un"+b]=function(a){for(var c=this.events||[],d=c.length;d--;)if(c[d].name==b&&(c[d].f==a||!a))return c[d].unbind(),c.splice(d,1),!c.length&&delete this.events,this;return this}}(i[r]);f.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},f.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var s=[];f.drag=function(c,d,e,f,g,h){function i(i,j,l){(i.originalEvent||i).preventDefault(),k._drag.x=j,k._drag.y=l,k._drag.id=i.identifier,!o.length&&a.mousemove(p).mouseup(q),o.push({el:k,move_scope:f,start_scope:g,end_scope:h}),d&&b.on("snap.drag.start."+k.id,d),c&&b.on("snap.drag.move."+k.id,c),e&&b.on("snap.drag.end."+k.id,e),b("snap.drag.start."+k.id,g||f||k,j,l,i)}function j(a,c,d){b("snap.draginit."+k.id,k,a,c,d)}var k=this;if(!arguments.length){var l;return k.drag(function(a,b){this.attr({transform:l+(l?"T":"t")+[a,b]})},function(){l=this.transform().local})}return b.on("snap.draginit."+k.id,i),k._drag={},s.push({el:k,start:i,init:j}),k.mousedown(j),k},f.undrag=function(){for(var c=s.length;c--;)s[c].el==this&&(this.unmousedown(s[c].init),s.splice(c,1),b.unbind("snap.drag.*."+this.id),b.unbind("snap.draginit."+this.id));return!s.length&&a.unmousemove(p).unmouseup(q),this}}),d.plugin(function(a,c,d){var e=(c.prototype,d.prototype),f=/^\s*url\((.+)\)/,g=String,h=a._.$;a.filter={},e.filter=function(b){var d=this;"svg"!=d.type&&(d=d.paper);var e=a.parse(g(b)),f=a._.id(),i=(d.node.offsetWidth,d.node.offsetHeight,h("filter"));return h(i,{id:f,filterUnits:"userSpaceOnUse"}),i.appendChild(e.node),d.defs.appendChild(i),new c(i)},b.on("snap.util.getattr.filter",function(){b.stop();var c=h(this.node,"filter");if(c){var d=g(c).match(f);return d&&a.select(d[1])}}),b.on("snap.util.attr.filter",function(d){if(d instanceof c&&"filter"==d.type){b.stop();var e=d.node.id;e||(h(d.node,{id:d.id}),e=d.id),h(this.node,{filter:a.url(e)})}d&&"none"!=d||(b.stop(),this.node.removeAttribute("filter"))}),a.filter.blur=function(b,c){null==b&&(b=2);var d=null==c?b:[b,c];return a.format('',{def:d})},a.filter.blur.toString=function(){return this()},a.filter.shadow=function(b,c,d,e,f){return"string"==typeof d&&(e=d,f=e,d=4),"string"!=typeof e&&(f=e,e="#000"),e=e||"#000",null==d&&(d=4),null==f&&(f=1),null==b&&(b=0,c=2),null==c&&(c=b),e=a.color(e),a.format('',{color:e,dx:b,dy:c,blur:d,opacity:f})},a.filter.shadow.toString=function(){return this()},a.filter.grayscale=function(b){return null==b&&(b=1),a.format('',{a:.2126+.7874*(1-b),b:.7152-.7152*(1-b),c:.0722-.0722*(1-b),d:.2126-.2126*(1-b),e:.7152+.2848*(1-b),f:.0722-.0722*(1-b),g:.2126-.2126*(1-b),h:.0722+.9278*(1-b)})},a.filter.grayscale.toString=function(){return this()},a.filter.sepia=function(b){return null==b&&(b=1),a.format('',{a:.393+.607*(1-b),b:.769-.769*(1-b),c:.189-.189*(1-b),d:.349-.349*(1-b),e:.686+.314*(1-b),f:.168-.168*(1-b),g:.272-.272*(1-b),h:.534-.534*(1-b),i:.131+.869*(1-b)})},a.filter.sepia.toString=function(){return this()},a.filter.saturate=function(b){return null==b&&(b=1),a.format('',{amount:1-b})},a.filter.saturate.toString=function(){return this()},a.filter.hueRotate=function(b){return b=b||0,a.format('',{angle:b})},a.filter.hueRotate.toString=function(){return this()},a.filter.invert=function(b){return null==b&&(b=1),a.format('',{amount:b,amount2:1-b})},a.filter.invert.toString=function(){return this()},a.filter.brightness=function(b){return null==b&&(b=1),a.format('',{amount:b})},a.filter.brightness.toString=function(){return this()},a.filter.contrast=function(b){return null==b&&(b=1),a.format('',{amount:b,amount2:.5-b/2})},a.filter.contrast.toString=function(){return this()}}),d.plugin(function(a,b){var c=a._.box,d=a.is,e=/^[^a-z]*([tbmlrc])/i,f=function(){return"T"+this.dx+","+this.dy};b.prototype.getAlign=function(a,b){null==b&&d(a,"string")&&(b=a,a=null),a=a||this.paper;var g=a.getBBox?a.getBBox():c(a),h=this.getBBox(),i={};switch(b=b&&b.match(e),b=b?b[1].toLowerCase():"c"){case"t":i.dx=0,i.dy=g.y-h.y;break;case"b":i.dx=0,i.dy=g.y2-h.y2;break;case"m":i.dx=0,i.dy=g.cy-h.cy;break;case"l":i.dx=g.x-h.x,i.dy=0;break;case"r":i.dx=g.x2-h.x2,i.dy=0;break;default:i.dx=g.cx-h.cx,i.dy=0}return i.toString=f,i},b.prototype.align=function(a,b){return this.transform("..."+this.getAlign(a,b))}}),d}); +!function(a){var b,c,d="0.5.0",e="hasOwnProperty",f=/[\.\/]/,g=/\s*,\s*/,h="*",i=function(a,b){return a-b},j={n:{}},k=function(){for(var a=0,b=this.length;b>a;a++)if("undefined"!=typeof this[a])return this[a]},l=function(){for(var a=this.length;--a;)if("undefined"!=typeof this[a])return this[a]},m=Object.prototype.toString,n=String,o=Array.isArray||function(a){return a instanceof Array||"[object Array]"==m.call(a)};eve=function(a,d){var e,f=c,g=Array.prototype.slice.call(arguments,2),h=eve.listeners(a),j=0,m=[],n={},o=[],p=b;o.firstDefined=k,o.lastDefined=l,b=a,c=0;for(var q=0,r=h.length;r>q;q++)"zIndex"in h[q]&&(m.push(h[q].zIndex),h[q].zIndex<0&&(n[h[q].zIndex]=h[q]));for(m.sort(i);m[j]<0;)if(e=n[m[j++]],o.push(e.apply(d,g)),c)return c=f,o;for(q=0;r>q;q++)if(e=h[q],"zIndex"in e)if(e.zIndex==m[j]){if(o.push(e.apply(d,g)),c)break;do if(j++,e=n[m[j]],e&&o.push(e.apply(d,g)),c)break;while(e)}else n[e.zIndex]=e;else if(o.push(e.apply(d,g)),c)break;return c=f,b=p,o},eve._events=j,eve.listeners=function(a){var b,c,d,e,g,i,k,l,m=o(a)?a:a.split(f),n=j,p=[n],q=[];for(e=0,g=m.length;g>e;e++){for(l=[],i=0,k=p.length;k>i;i++)for(n=p[i].n,c=[n[m[e]],n[h]],d=2;d--;)b=c[d],b&&(l.push(b),q=q.concat(b.f||[]));p=l}return q},eve.separator=function(a){a?(a=n(a).replace(/(?=[\.\^\]\[\-])/g,"\\"),a="["+a+"]",f=new RegExp(a)):f=/[\.\/]/},eve.on=function(a,b){if("function"!=typeof b)return function(){};for(var c=o(a)?o(a[0])?a:[a]:n(a).split(g),d=0,e=c.length;e>d;d++)!function(a){for(var c,d=o(a)?a:n(a).split(f),e=j,g=0,h=d.length;h>g;g++)e=e.n,e=e.hasOwnProperty(d[g])&&e[d[g]]||(e[d[g]]={n:{}});for(e.f=e.f||[],g=0,h=e.f.length;h>g;g++)if(e.f[g]==b){c=!0;break}!c&&e.f.push(b)}(c[d]);return function(a){+a==+a&&(b.zIndex=+a)}},eve.f=function(a){var b=[].slice.call(arguments,1);return function(){eve.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},eve.stop=function(){c=1},eve.nt=function(a){var c=o(b)?b.join("."):b;return a?new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)").test(c):c},eve.nts=function(){return o(b)?b:b.split(f)},eve.off=eve.unbind=function(a,b){if(!a)return void(eve._events=j={n:{}});var c=o(a)?o(a[0])?a:[a]:n(a).split(g);if(c.length>1)for(var d=0,i=c.length;i>d;d++)eve.off(c[d],b);else{c=o(a)?a:n(a).split(f);var k,l,m,d,i,p,q,r=[j],s=[];for(d=0,i=c.length;i>d;d++)for(p=0;pd;d++)for(k=r[d];k.n;){if(b){if(k.f){for(p=0,q=k.f.length;q>p;p++)if(k.f[p]==b){k.f.splice(p,1);break}!k.f.length&&delete k.f}for(l in k.n)if(k.n[e](l)&&k.n[l].f){var t=k.n[l].f;for(p=0,q=t.length;q>p;p++)if(t[p]==b){t.splice(p,1);break}!t.length&&delete k.n[l].f}}else{delete k.f;for(l in k.n)k.n[e](l)&&k.n[l].f&&delete k.n[l].f}k=k.n}a:for(d=0,i=s.length;i>d;d++){k=s[d];for(l in k.n[k.name].f)continue a;for(l in k.n[k.name].n)continue a;delete k.n[k.name]}}},eve.once=function(a,b){var c=function(){return eve.off(a,c),b.apply(this,arguments)};return eve.on(a,c)},eve.version=d,eve.toString=function(){return"You are running Eve "+d},"undefined"!=typeof module&&module.exports?module.exports=eve:"function"==typeof define&&define.amd?define("eve",[],function(){return eve}):a.eve=eve}(this),function(a,b){if("function"==typeof define&&define.amd)define(["eve"],function(c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("eve");module.exports=b(a,c)}else b(a,a.eve)}(window||this,function(a,b){var c=function(b){var c,d={},e=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||function(a){return setTimeout(a,16,(new Date).getTime()),!0},f=Array.isArray||function(a){return a instanceof Array||"[object Array]"==Object.prototype.toString.call(a)},g=0,h="M"+(+new Date).toString(36),i=function(){return h+(g++).toString(36)},j=Date.now||function(){return+new Date},k=function(a){var b=this;if(null==a)return b.s;var c=b.s-a;b.b+=b.dur*c,b.B+=b.dur*c,b.s=a},l=function(a){var b=this;return null==a?b.spd:void(b.spd=a)},m=function(a){var b=this;return null==a?b.dur:(b.s=b.s*a/b.dur,void(b.dur=a))},n=function(){var a=this;delete d[a.id],a.update(),b("mina.stop."+a.id,a)},o=function(){var a=this;a.pdif||(delete d[a.id],a.update(),a.pdif=a.get()-a.b)},p=function(){var a=this;a.pdif&&(a.b=a.get()-a.pdif,delete a.pdif,d[a.id]=a,r())},q=function(){var a,b=this;if(f(b.start)){a=[];for(var c=0,d=b.start.length;d>c;c++)a[c]=+b.start[c]+(b.end[c]-b.start[c])*b.easing(b.s)}else a=+b.start+(b.end-b.start)*b.easing(b.s);b.set(a)},r=function(a){if(!a)return void(c||(c=e(r)));var f=0;for(var g in d)if(d.hasOwnProperty(g)){var h=d[g],i=h.get();f++,h.s=(i-h.b)/(h.dur/h.spd),h.s>=1&&(delete d[g],h.s=1,f--,function(a){setTimeout(function(){b("mina.finish."+a.id,a)})}(h)),h.update()}c=f?e(r):!1},s=function(a,b,c,e,f,g,h){var j={id:i(),start:a,end:b,b:c,s:0,dur:e-c,spd:1,get:f,set:g,easing:h||s.linear,status:k,speed:l,duration:m,stop:n,pause:o,resume:p,update:q};d[j.id]=j;var t,u=0;for(t in d)if(d.hasOwnProperty(t)&&(u++,2==u))break;return 1==u&&r(),j};return s.time=j,s.getById=function(a){return d[a]||null},s.linear=function(a){return a},s.easeout=function(a){return Math.pow(a,1.7)},s.easein=function(a){return Math.pow(a,.48)},s.easeinout=function(a){if(1==a)return 1;if(0==a)return 0;var b=.48-a/1.04,c=Math.sqrt(.1734+b*b),d=c-b,e=Math.pow(Math.abs(d),1/3)*(0>d?-1:1),f=-c-b,g=Math.pow(Math.abs(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},s.backin=function(a){if(1==a)return 1;var b=1.70158;return a*a*((b+1)*a-b)},s.backout=function(a){if(0==a)return 0;a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},s.elastic=function(a){return a==!!a?a:Math.pow(2,-10*a)*Math.sin((a-.075)*(2*Math.PI)/.3)+1},s.bounce=function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b},a.mina=s,s}("undefined"==typeof b?function(){}:b),d=function(a){function c(a,b){if(a){if(a.nodeType)return w(a);if(e(a,"array")&&c.set)return c.set.apply(c,a);if(a instanceof s)return a;if(null==b)return a=y.doc.querySelector(String(a)),w(a)}return a=null==a?"100%":a,b=null==b?"100%":b,new v(a,b)}function d(a,b){if(b){if("#text"==a&&(a=y.doc.createTextNode(b.text||b["#text"]||"")),"#comment"==a&&(a=y.doc.createComment(b.text||b["#text"]||"")),"string"==typeof a&&(a=d(a)),"string"==typeof b)return 1==a.nodeType?"xlink:"==b.substring(0,6)?a.getAttributeNS(T,b.substring(6)):"xml:"==b.substring(0,4)?a.getAttributeNS(U,b.substring(4)):a.getAttribute(b):"text"==b?a.nodeValue:null;if(1==a.nodeType){for(var c in b)if(b[z](c)){var e=A(b[c]);e?"xlink:"==c.substring(0,6)?a.setAttributeNS(T,c.substring(6),e):"xml:"==c.substring(0,4)?a.setAttributeNS(U,c.substring(4),e):a.setAttribute(c,e):a.removeAttribute(c)}}else"text"in b&&(a.nodeValue=b.text)}else a=y.doc.createElementNS(U,a);return a}function e(a,b){return b=A.prototype.toLowerCase.call(b),"finite"==b?isFinite(a):"array"==b&&(a instanceof Array||Array.isArray&&Array.isArray(a))?!0:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||J.call(a).slice(8,-1).toLowerCase()==b}function f(a){if("function"==typeof a||Object(a)!==a)return a;var b=new a.constructor;for(var c in a)a[z](c)&&(b[c]=f(a[c]));return b}function h(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function i(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),g=d.cache=d.cache||{},i=d.count=d.count||[];return g[z](f)?(h(i,f),c?c(g[f]):g[f]):(i.length>=1e3&&delete g[i.shift()],i.push(f),g[f]=a.apply(b,e),c?c(g[f]):g[f])}return d}function j(a,b,c,d,e,f){if(null==e){var g=a-c,h=b-d;return g||h?(180+180*D.atan2(-h,-g)/H+360)%360:0}return j(a,b,e,f)-j(c,d,e,f)}function k(a){return a%360*H/180}function l(a){return 180*a/H%360}function m(a){var b=[];return a=a.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g,function(a,c,d){return d=d.split(/\s*,\s*|\s+/),"rotate"==c&&1==d.length&&d.push(0,0),"scale"==c&&(d.length>2?d=d.slice(0,2):2==d.length&&d.push(0,0),1==d.length&&d.push(d[0],0,0)),"skewX"==c?b.push(["m",1,0,D.tan(k(d[0])),1,0,0]):"skewY"==c?b.push(["m",1,D.tan(k(d[0])),0,1,0,0]):b.push([c.charAt(0)].concat(d)),a}),b}function n(a,b){var d=aa(a),e=new c.Matrix;if(d)for(var f=0,g=d.length;g>f;f++){var h,i,j,k,l,m=d[f],n=m.length,o=A(m[0]).toLowerCase(),p=m[0]!=o,q=p?e.invert():0;"t"==o&&2==n?e.translate(m[1],0):"t"==o&&3==n?p?(h=q.x(0,0),i=q.y(0,0),j=q.x(m[1],m[2]),k=q.y(m[1],m[2]),e.translate(j-h,k-i)):e.translate(m[1],m[2]):"r"==o?2==n?(l=l||b,e.rotate(m[1],l.x+l.width/2,l.y+l.height/2)):4==n&&(p?(j=q.x(m[2],m[3]),k=q.y(m[2],m[3]),e.rotate(m[1],j,k)):e.rotate(m[1],m[2],m[3])):"s"==o?2==n||3==n?(l=l||b,e.scale(m[1],m[n-1],l.x+l.width/2,l.y+l.height/2)):4==n?p?(j=q.x(m[2],m[3]),k=q.y(m[2],m[3]),e.scale(m[1],m[1],j,k)):e.scale(m[1],m[1],m[2],m[3]):5==n&&(p?(j=q.x(m[3],m[4]),k=q.y(m[3],m[4]),e.scale(m[1],m[2],j,k)):e.scale(m[1],m[2],m[3],m[4])):"m"==o&&7==n&&e.add(m[1],m[2],m[3],m[4],m[5],m[6])}return e}function o(a){var b=a.node.ownerSVGElement&&w(a.node.ownerSVGElement)||a.node.parentNode&&w(a.node.parentNode)||c.select("svg")||c(0,0),d=b.select("defs"),e=null==d?!1:d.node;return e||(e=u("defs",b.node).node),e}function p(a){return a.node.ownerSVGElement&&w(a.node.ownerSVGElement)||c.select("svg")}function q(a,b,c){function e(a){if(null==a)return I;if(a==+a)return a;d(j,{width:a});try{return j.getBBox().width}catch(b){return 0}}function f(a){if(null==a)return I;if(a==+a)return a;d(j,{height:a});try{return j.getBBox().height}catch(b){return 0}}function g(d,e){null==b?i[d]=e(a.attr(d)||0):d==b&&(i=e(null==c?a.attr(d)||0:c))}var h=p(a).node,i={},j=h.querySelector(".svg---mgr");switch(j||(j=d("rect"),d(j,{x:-9e9,y:-9e9,width:10,height:10,"class":"svg---mgr",fill:"none"}),h.appendChild(j)),a.type){case"rect":g("rx",e),g("ry",f);case"image":g("width",e),g("height",f);case"text":g("x",e),g("y",f);break;case"circle":g("cx",e),g("cy",f),g("r",e);break;case"ellipse":g("cx",e),g("cy",f),g("rx",e),g("ry",f);break;case"line":g("x1",e),g("x2",e),g("y1",f),g("y2",f);break;case"marker":g("refX",e),g("markerWidth",e),g("refY",f),g("markerHeight",f);break;case"radialGradient":g("fx",e),g("fy",f);break;case"tspan":g("dx",e),g("dy",f);break;default:g(b,e)}return h.removeChild(j),i}function r(a){e(a,"array")||(a=Array.prototype.slice.call(arguments,0));for(var b=0,c=0,d=this.node;this[b];)delete this[b++];for(b=0;bc;c++){var e={type:a[c].type,attr:a[c].attr()},f=a[c].children();b.push(e),f.length&&x(f,e.childNodes=[])}}c.version="0.5.0",c.toString=function(){return"Snap v"+this.version},c._={};var y={win:a.window,doc:a.window.document};c._.glob=y;var z="hasOwnProperty",A=String,B=parseFloat,C=parseInt,D=Math,E=D.max,F=D.min,G=D.abs,H=(D.pow,D.PI),I=(D.round,""),J=Object.prototype.toString,K=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i,L=(c._.separator=/[,\s]+/,/[\s]*,[\s]*/),M={hs:1,rg:1},N=/([a-z])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/gi,O=/([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/gi,P=/(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\s]*,?[\s]*/gi,Q=0,R="S"+(+new Date).toString(36),S=function(a){return(a&&a.type?a.type:I)+R+(Q++).toString(36)},T="http://www.w3.org/1999/xlink",U="http://www.w3.org/2000/svg",V={};c.url=function(a){return"url('#"+a+"')"};c._.$=d,c._.id=S,c.format=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return A(b).replace(a,function(a,b){return c(a,b,d)})}}(),c._.clone=f,c._.cacher=i,c.rad=k,c.deg=l,c.sin=function(a){return D.sin(c.rad(a))},c.tan=function(a){return D.tan(c.rad(a))},c.cos=function(a){return D.cos(c.rad(a))},c.asin=function(a){return c.deg(D.asin(a))},c.acos=function(a){return c.deg(D.acos(a))},c.atan=function(a){return c.deg(D.atan(a))},c.atan2=function(a){return c.deg(D.atan2(a))},c.angle=j,c.len=function(a,b,d,e){return Math.sqrt(c.len2(a,b,d,e))},c.len2=function(a,b,c,d){return(a-c)*(a-c)+(b-d)*(b-d)},c.closestPoint=function(a,b,c){function d(a){var d=a.x-b,e=a.y-c;return d*d+e*e}for(var e,f,g,h,i=a.node,j=i.getTotalLength(),k=j/i.pathSegList.numberOfItems*.125,l=1/0,m=0;j>=m;m+=k)(h=d(g=i.getPointAtLength(m))).5;){var n,o,p,q,r,s;(p=f-k)>=0&&(r=d(n=i.getPointAtLength(p)))f)return b-f;if(f>a-c)return b-f+a}return b},c.getRGB=i(function(a){if(!a||(a=A(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:Z};if(!(M[z](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=W(a)),!a)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z};var b,d,f,g,h,i,j=a.match(K);return j?(j[2]&&(f=C(j[2].substring(5),16),d=C(j[2].substring(3,5),16),b=C(j[2].substring(1,3),16)),j[3]&&(f=C((h=j[3].charAt(3))+h,16),d=C((h=j[3].charAt(2))+h,16),b=C((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=B(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),f=B(i[2]),"%"==i[2].slice(-1)&&(f*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100)),j[5]?(i=j[5].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b/=100),d=B(i[1]),"%"==i[1].slice(-1)&&(d/=100),f=B(i[2]),"%"==i[2].slice(-1)&&(f/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),c.hsb2rgb(b,d,f,g)):j[6]?(i=j[6].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b/=100),d=B(i[1]),"%"==i[1].slice(-1)&&(d/=100),f=B(i[2]),"%"==i[2].slice(-1)&&(f/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),c.hsl2rgb(b,d,f,g)):(b=F(D.round(b),255),d=F(D.round(d),255),f=F(D.round(f),255),g=F(E(g,0),1),j={r:b,g:d,b:f,toString:Z},j.hex="#"+(16777216|f|d<<8|b<<16).toString(16).slice(1),j.opacity=e(g,"finite")?g:1,j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z}},c),c.hsb=i(function(a,b,d){return c.hsb2rgb(a,b,d).hex}),c.hsl=i(function(a,b,d){return c.hsl2rgb(a,b,d).hex}),c.rgb=i(function(a,b,c,d){if(e(d,"finite")){var f=D.round;return"rgba("+[f(a),f(b),f(c),+d.toFixed(2)]+")"}return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)});var W=function(a){var b=y.doc.getElementsByTagName("head")[0]||y.doc.getElementsByTagName("svg")[0],c="rgb(255, 0, 0)";return(W=i(function(a){if("red"==a.toLowerCase())return c;b.style.color=c,b.style.color=a;var d=y.doc.defaultView.getComputedStyle(b,I).getPropertyValue("color");return d==c?null:d}))(a)},X=function(){return"hsb("+[this.h,this.s,this.b]+")"},Y=function(){return"hsl("+[this.h,this.s,this.l]+")"},Z=function(){return 1==this.opacity||null==this.opacity?this.hex:"rgba("+[this.r,this.g,this.b,this.opacity]+")"},$=function(a,b,d){if(null==b&&e(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(d=a.b,b=a.g,a=a.r),null==b&&e(a,string)){var f=c.getRGB(a);a=f.r,b=f.g,d=f.b}return(a>1||b>1||d>1)&&(a/=255,b/=255,d/=255),[a,b,d]},_=function(a,b,d,f){a=D.round(255*a),b=D.round(255*b),d=D.round(255*d);var g={r:a,g:b,b:d,opacity:e(f,"finite")?f:1,hex:c.rgb(a,b,d),toString:Z};return e(f,"finite")&&(g.opacity=f),g};c.color=function(a){var b;return e(a,"object")&&"h"in a&&"s"in a&&"b"in a?(b=c.hsb2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):e(a,"object")&&"h"in a&&"s"in a&&"l"in a?(b=c.hsl2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):(e(a,"string")&&(a=c.getRGB(a)),e(a,"object")&&"r"in a&&"g"in a&&"b"in a&&!("error"in a)?(b=c.rgb2hsl(a),a.h=b.h,a.s=b.s,a.l=b.l,b=c.rgb2hsb(a),a.v=b.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1,a.error=1)),a.toString=Z,a},c.hsb2rgb=function(a,b,c,d){e(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,d=a.o,a=a.h),a*=360;var f,g,h,i,j;return a=a%360/60,j=c*b,i=j*(1-G(a%2-1)),f=g=h=c-j,a=~~a,f+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],_(f,g,h,d)},c.hsl2rgb=function(a,b,c,d){e(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var f,g,h,i,j;return a=a%360/60,j=2*b*(.5>c?c:1-c),i=j*(1-G(a%2-1)),f=g=h=c-j/2,a=~~a,f+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],_(f,g,h,d)},c.rgb2hsb=function(a,b,c){c=$(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=E(a,b,c),g=f-F(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:X}},c.rgb2hsl=function(a,b,c){c=$(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=E(a,b,c),h=F(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:Y}},c.parsePathString=function(a){if(!a)return null;var b=c.path(a);if(b.arr)return c.path.clone(b.arr);var d={a:7,c:6,o:2,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,u:3,z:0},f=[];return e(a,"array")&&e(a[0],"array")&&(f=c.path.clone(a)),f.length||A(a).replace(N,function(a,b,c){var e=[],g=b.toLowerCase();if(c.replace(P,function(a,b){b&&e.push(+b)}),"m"==g&&e.length>2&&(f.push([b].concat(e.splice(0,2))),g="l",b="m"==b?"l":"L"),"o"==g&&1==e.length&&f.push([b,e[0]]),"r"==g)f.push([b].concat(e));else for(;e.length>=d[g]&&(f.push([b].concat(e.splice(0,d[g]))),d[g]););}),f.toString=c.path.toString,b.arr=c.path.clone(f),f};var aa=c.parseTransformString=function(a){if(!a)return null;var b=[];return e(a,"array")&&e(a[0],"array")&&(b=c.path.clone(a)),b.length||A(a).replace(O,function(a,c,d){var e=[];c.toLowerCase();d.replace(P,function(a,b){b&&e.push(+b)}),b.push([c].concat(e))}),b.toString=c.path.toString,b};c._.svgTransform2string=m,c._.rgTransform=/^[a-z][\s]*-?\.?\d/i,c._.transform2matrix=n,c._unit2px=q;y.doc.contains||y.doc.compareDocumentPosition?function(a,b){var c=9==a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a==d||!(!d||1!=d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)for(;b;)if(b=b.parentNode,b==a)return!0;return!1};c._.getSomeDefs=o,c._.getSomeSVG=p,c.select=function(a){return a=A(a).replace(/([^\\]):/g,"$1\\:"),w(y.doc.querySelector(a))},c.selectAll=function(a){for(var b=y.doc.querySelectorAll(a),d=(c.set||Array)(),e=0;ei;i++)h[g[i].nodeName]=g[i].nodeValue;return h}if(e(a,"string")){if(!(arguments.length>1))return b("snap.util.getattr."+a,d).firstDefined();var k={};k[a]=c,a=k}for(var l in a)a[z](l)&&b("snap.util.attr."+l,d,a[l]);return d},c.parse=function(a){var b=y.doc.createDocumentFragment(),c=!0,d=y.doc.createElement("div");if(a=A(a),a.match(/^\s*<\s*svg(?:\s|>)/)||(a=""+a+"",c=!1),d.innerHTML=a,a=d.getElementsByTagName("svg")[0])if(c)b=a;else for(;a.firstChild;)b.appendChild(a.firstChild);return new t(b)},c.fragment=function(){for(var a=Array.prototype.slice.call(arguments,0),b=y.doc.createDocumentFragment(),d=0,e=a.length;e>d;d++){var f=a[d];f.node&&f.node.nodeType&&b.appendChild(f.node),f.nodeType&&b.appendChild(f),"string"==typeof f&&b.appendChild(c.parse(f).node)}return new t(b)},c._.make=u,c._.wrap=w,v.prototype.el=function(a,b){var c=u(a,this.node);return b&&c.attr(b),c},s.prototype.children=function(){for(var a=[],b=this.node.childNodes,d=0,e=b.length;e>d;d++)a[d]=c(b[d]);return a},s.prototype.toJSON=function(){var a=[];return x([this],a),a[0]},b.on("snap.util.getattr",function(){var a=b.nt();a=a.substring(a.lastIndexOf(".")+1);var c=a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()});return ba[z](c)?this.node.ownerDocument.defaultView.getComputedStyle(this.node,null).getPropertyValue(c):d(this.node,a)});var ba={"alignment-baseline":0,"baseline-shift":0,clip:0,"clip-path":0,"clip-rule":0,color:0,"color-interpolation":0,"color-interpolation-filters":0,"color-profile":0,"color-rendering":0,cursor:0,direction:0,display:0,"dominant-baseline":0,"enable-background":0,fill:0,"fill-opacity":0,"fill-rule":0,filter:0,"flood-color":0,"flood-opacity":0,font:0,"font-family":0,"font-size":0,"font-size-adjust":0,"font-stretch":0,"font-style":0,"font-variant":0,"font-weight":0,"glyph-orientation-horizontal":0,"glyph-orientation-vertical":0,"image-rendering":0,kerning:0,"letter-spacing":0,"lighting-color":0,marker:0,"marker-end":0,"marker-mid":0,"marker-start":0,mask:0,opacity:0,overflow:0,"pointer-events":0,"shape-rendering":0,"stop-color":0,"stop-opacity":0,stroke:0,"stroke-dasharray":0,"stroke-dashoffset":0,"stroke-linecap":0,"stroke-linejoin":0,"stroke-miterlimit":0,"stroke-opacity":0,"stroke-width":0,"text-anchor":0,"text-decoration":0,"text-rendering":0,"unicode-bidi":0,visibility:0,"word-spacing":0,"writing-mode":0};b.on("snap.util.attr",function(a){var c=b.nt(),e={};c=c.substring(c.lastIndexOf(".")+1),e[c]=a;var f=c.replace(/-(\w)/gi,function(a,b){return b.toUpperCase()}),g=c.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()});ba[z](g)?this.node.style[f]=null==a?I:a:d(this.node,e)}),function(a){}(v.prototype),c.ajax=function(a,c,d,f){var g=new XMLHttpRequest,h=S();if(g){if(e(c,"function"))f=d,d=c,c=null;else if(e(c,"object")){var i=[];for(var j in c)c.hasOwnProperty(j)&&i.push(encodeURIComponent(j)+"="+encodeURIComponent(c[j]));c=i.join("&")}return g.open(c?"POST":"GET",a,!0),c&&(g.setRequestHeader("X-Requested-With","XMLHttpRequest"),g.setRequestHeader("Content-type","application/x-www-form-urlencoded")),d&&(b.once("snap.ajax."+h+".0",d),b.once("snap.ajax."+h+".200",d),b.once("snap.ajax."+h+".304",d)),g.onreadystatechange=function(){4==g.readyState&&b("snap.ajax."+h+"."+g.status,f,g)},4==g.readyState?g:(g.send(c),g)}},c.load=function(a,b,d){c.ajax(a,function(a){var e=c.parse(a.responseText);d?b.call(d,e):b(e)})};var ca=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,h=e.clientLeft||d.clientLeft||0,i=b.top+(g.win.pageYOffset||e.scrollTop||d.scrollTop)-f,j=b.left+(g.win.pageXOffset||e.scrollLeft||d.scrollLeft)-h;return{y:i,x:j}};return c.getElementByPoint=function(a,b){var c=this,d=(c.canvas,y.doc.elementFromPoint(a,b));if(y.win.opera&&"svg"==d.tagName){var e=ca(d),f=d.createSVGRect();f.x=a-e.x,f.y=b-e.y,f.width=f.height=1;var g=d.getIntersectionList(f,null);g.length&&(d=g[g.length-1])}return d?w(d):null},c.plugin=function(a){a(c,s,v,y,t)},y.win.Snap=c,c}(a||this);return d.plugin(function(c,d,e,f,g){function h(a,b){if(null==b){var d=!0;if(b="linearGradient"==a.type||"radialGradient"==a.type?a.node.getAttribute("gradientTransform"):"pattern"==a.type?a.node.getAttribute("patternTransform"):a.node.getAttribute("transform"),!b)return new c.Matrix;b=c._.svgTransform2string(b)}else b=c._.rgTransform.test(b)?m(b).replace(/\.{3}|\u2026/g,a._.transform||""):c._.svgTransform2string(b),l(b,"array")&&(b=c.path?c.path.toString.call(b):m(b)),a._.transform=b;var e=c._.transform2matrix(b,a.getBBox(1));return d?e:void(a.matrix=e)}function i(a){function b(a,b){var d=o(a.node,b);d=d&&d.match(g),d=d&&d[2],d&&"#"==d.charAt()&&(d=d.substring(1),d&&(i[d]=(i[d]||[]).concat(function(d){var e={};e[b]=c.url(d),o(a.node,e)})))}function d(a){var b=o(a.node,"xlink:href");b&&"#"==b.charAt()&&(b=b.substring(1),b&&(i[b]=(i[b]||[]).concat(function(b){a.attr("xlink:href","#"+b)})))}for(var e,f=a.selectAll("*"),g=/^\s*url\(("|'|)(.*)\1\)\s*$/,h=[],i={},j=0,k=f.length;k>j;j++){e=f[j],b(e,"fill"),b(e,"stroke"),b(e,"filter"),b(e,"mask"),b(e,"clip-path"),d(e);var l=o(e.node,"id");l&&(o(e.node,{id:e.id}),h.push({old:l,id:e.id}))}for(j=0,k=h.length;k>j;j++){var m=i[h[j].old];if(m)for(var n=0,p=m.length;p>n;n++)m[n](h[j].id)}}function j(a){return function(){var b=a?"<"+this.type:"",c=this.node.attributes,d=this.node.childNodes;if(a)for(var e=0,f=c.length;f>e;e++)b+=" "+c[e].name+'="'+c[e].value.replace(/"/g,'\\"')+'"';if(d.length){for(a&&(b+=">"),e=0,f=d.length;f>e;e++)3==d[e].nodeType?b+=d[e].nodeValue:1==d[e].nodeType&&(b+=s(d[e]).toString());a&&(b+="")}else a&&(b+="/>");return b}}var k=d.prototype,l=c.is,m=String,n=c._unit2px,o=c._.$,p=c._.make,q=c._.getSomeDefs,r="hasOwnProperty",s=c._.wrap;k.getBBox=function(a){if("tspan"==this.type)return c._.box(this.node.getClientRects().item(0));if(!c.Matrix||!c.path)return this.node.getBBox();var b=this,d=new c.Matrix;if(b.removed)return c._.box();for(;"use"==b.type;)if(a||(d=d.add(b.transform().localMatrix.translate(b.attr("x")||0,b.attr("y")||0))),b.original)b=b.original;else{var e=b.attr("xlink:href");b=b.original=b.node.ownerDocument.getElementById(e.substring(e.indexOf("#")+1))}var f=b._,g=c.path.get[b.type]||c.path.get.deflt;try{return a?(f.bboxwt=g?c.path.getBBox(b.realPath=g(b)):c._.box(b.node.getBBox()),c._.box(f.bboxwt)):(b.realPath=g(b),b.matrix=b.transform().localMatrix,f.bbox=c.path.getBBox(c.path.map(b.realPath,d.add(b.matrix))),c._.box(f.bbox))}catch(h){return c._.box()}};var t=function(){return this.string};k.transform=function(a){var b=this._;if(null==a){for(var d,e=this,f=new c.Matrix(this.node.getCTM()),g=h(this),i=[g],j=new c.Matrix,k=g.toTransformString(),l=m(g)==m(this.matrix)?m(b.transform):k;"svg"!=e.type&&(e=e.parent());)i.push(h(e));for(d=i.length;d--;)j.add(i[d]);return{string:l,globalMatrix:f,totalMatrix:j,localMatrix:g,diffMatrix:f.clone().add(g.invert()),global:f.toTransformString(),total:j.toTransformString(),local:k,toString:t}}return a instanceof c.Matrix?(this.matrix=a,this._.transform=a.toTransformString()):h(this,a),this.node&&("linearGradient"==this.type||"radialGradient"==this.type?o(this.node,{gradientTransform:this.matrix}):"pattern"==this.type?o(this.node,{patternTransform:this.matrix}):o(this.node,{transform:this.matrix})),this},k.parent=function(){return s(this.node.parentNode)},k.append=k.add=function(a){if(a){if("set"==a.type){var b=this;return a.forEach(function(a){b.add(a)}),this}a=s(a),this.node.appendChild(a.node),a.paper=this.paper}return this},k.appendTo=function(a){return a&&(a=s(a),a.append(this)),this},k.prepend=function(a){if(a){if("set"==a.type){var b,c=this;return a.forEach(function(a){b?b.after(a):c.prepend(a),b=a}),this}a=s(a);var d=a.parent();this.node.insertBefore(a.node,this.node.firstChild),this.add&&this.add(),a.paper=this.paper,this.parent()&&this.parent().add(),d&&d.add()}return this},k.prependTo=function(a){return a=s(a),a.prepend(this),this},k.before=function(a){if("set"==a.type){var b=this;return a.forEach(function(a){var c=a.parent();b.node.parentNode.insertBefore(a.node,b.node),c&&c.add()}),this.parent().add(),this}a=s(a);var c=a.parent();return this.node.parentNode.insertBefore(a.node,this.node),this.parent()&&this.parent().add(),c&&c.add(),a.paper=this.paper,this},k.after=function(a){a=s(a);var b=a.parent();return this.node.nextSibling?this.node.parentNode.insertBefore(a.node,this.node.nextSibling):this.node.parentNode.appendChild(a.node),this.parent()&&this.parent().add(),b&&b.add(),a.paper=this.paper,this},k.insertBefore=function(a){a=s(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},k.insertAfter=function(a){a=s(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node.nextSibling),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},k.remove=function(){var a=this.parent();return this.node.parentNode&&this.node.parentNode.removeChild(this.node),delete this.paper,this.removed=!0,a&&a.add(),this},k.select=function(a){return s(this.node.querySelector(a))},k.selectAll=function(a){for(var b=this.node.querySelectorAll(a),d=(c.set||Array)(),e=0;e{contents}',{x:+b.x.toFixed(3),y:+b.y.toFixed(3),width:+b.width.toFixed(3),height:+b.height.toFixed(3),contents:this.outerSVG()}); +return"data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(d)))}},g.prototype.select=k.select,g.prototype.selectAll=k.selectAll}),d.plugin(function(a,d,e,f,g){function h(a,b,c){return function(d){var e=d.slice(a,b);return 1==e.length&&(e=e[0]),c?c(e):e}}var i=d.prototype,j=a.is,k=String,l="hasOwnProperty",m=function(a,b,d,e){"function"!=typeof d||d.length||(e=d,d=c.linear),this.attr=a,this.dur=b,d&&(this.easing=d),e&&(this.callback=e)};a._.Animation=m,a.animation=function(a,b,c,d){return new m(a,b,c,d)},i.inAnim=function(){var a=this,b=[];for(var c in a.anims)a.anims[l](c)&&!function(a){b.push({anim:new m(a._attrs,a.dur,a.easing,a._callback),mina:a,curStatus:a.status(),status:function(b){return a.status(b)},stop:function(){a.stop()}})}(a.anims[c]);return b},a.animate=function(a,d,e,f,g,h){"function"!=typeof g||g.length||(h=g,g=c.linear);var i=c.time(),j=c(a,d,i,i+f,c.time,e,g);return h&&b.once("mina.finish."+j.id,h),j},i.stop=function(){for(var a=this.inAnim(),b=0,c=a.length;c>b;b++)a[b].stop();return this},i.animate=function(a,d,e,f){"function"!=typeof e||e.length||(f=e,e=c.linear),a instanceof m&&(f=a.callback,e=a.easing,d=a.dur,a=a.attr);var g,i,n,o,p=[],q=[],r={},s=this;for(var t in a)if(a[l](t)){s.equal?(o=s.equal(t,k(a[t])),g=o.from,i=o.to,n=o.f):(g=+s.attr(t),i=+a[t]);var u=j(g,"array")?g.length:1;r[t]=h(p.length,p.length+u,n),p=p.concat(g),q=q.concat(i)}var v=c.time(),w=c(p,q,v,v+d,c.time,function(a){var b={};for(var c in r)r[l](c)&&(b[c]=r[c](a));s.attr(b)},e);return s.anims[w.id]=w,w._attrs=a,w._callback=f,b("snap.animcreated."+s.id,w),b.once("mina.finish."+w.id,function(){b.off("mina.*."+w.id),delete s.anims[w.id],f&&f.call(s)}),b.once("mina.stop."+w.id,function(){b.off("mina.*."+w.id),delete s.anims[w.id]}),s}}),d.plugin(function(a,b,c,d,e){function f(a,b,c,d,e,f){return null==b&&"[object SVGMatrix]"==g.call(a)?(this.a=a.a,this.b=a.b,this.c=a.c,this.d=a.d,this.e=a.e,void(this.f=a.f)):void(null!=a?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0))}var g=Object.prototype.toString,h=String,i=Math,j="";!function(b){function c(a){return a[0]*a[0]+a[1]*a[1]}function d(a){var b=i.sqrt(c(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)}b.add=function(a,b,c,d,e,g){if(a&&a instanceof f)return this.add(a.a,a.b,a.c,a.d,a.e,a.f);var h=a*this.a+b*this.c,i=a*this.b+b*this.d;return this.e+=e*this.a+g*this.c,this.f+=e*this.b+g*this.d,this.c=c*this.a+d*this.c,this.d=c*this.b+d*this.d,this.a=h,this.b=i,this},f.prototype.multLeft=function(a,b,c,d,e,g){if(a&&a instanceof f)return this.multLeft(a.a,a.b,a.c,a.d,a.e,a.f);var h=a*this.a+c*this.b,i=a*this.c+c*this.d,j=a*this.e+c*this.f+e;return this.b=b*this.a+d*this.b,this.d=b*this.c+d*this.d,this.f=b*this.e+d*this.f+g,this.a=h,this.c=i,this.e=j,this},b.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new f(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},b.clone=function(){return new f(this.a,this.b,this.c,this.d,this.e,this.f)},b.translate=function(a,b){return this.e+=a*this.a+b*this.c,this.f+=a*this.b+b*this.d,this},b.scale=function(a,b,c,d){return null==b&&(b=a),(c||d)&&this.translate(c,d),this.a*=a,this.b*=a,this.c*=b,this.d*=b,(c||d)&&this.translate(-c,-d),this},b.rotate=function(b,c,d){b=a.rad(b),c=c||0,d=d||0;var e=+i.cos(b).toFixed(9),f=+i.sin(b).toFixed(9);return this.add(e,f,-f,e,c,d),this.add(1,0,0,1,-c,-d)},b.skewX=function(a){return this.skew(a,0)},b.skewY=function(a){return this.skew(0,a)},b.skew=function(b,c){b=b||0,c=c||0,b=a.rad(b),c=a.rad(c);var d=i.tan(b).toFixed(9),e=i.tan(c).toFixed(9);return this.add(1,e,d,1,0,0)},b.x=function(a,b){return a*this.a+b*this.c+this.e},b.y=function(a,b){return a*this.b+b*this.d+this.f},b.get=function(a){return+this[h.fromCharCode(97+a)].toFixed(4)},b.toString=function(){return"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")"},b.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},b.determinant=function(){return this.a*this.d-this.b*this.c},b.split=function(){var b={};b.dx=this.e,b.dy=this.f;var e=[[this.a,this.b],[this.c,this.d]];b.scalex=i.sqrt(c(e[0])),d(e[0]),b.shear=e[0][0]*e[1][0]+e[0][1]*e[1][1],e[1]=[e[1][0]-e[0][0]*b.shear,e[1][1]-e[0][1]*b.shear],b.scaley=i.sqrt(c(e[1])),d(e[1]),b.shear/=b.scaley,this.determinant()<0&&(b.scalex=-b.scalex);var f=e[0][1],g=e[1][1];return 0>g?(b.rotate=a.deg(i.acos(g)),0>f&&(b.rotate=360-b.rotate)):b.rotate=a.deg(i.asin(f)),b.isSimple=!(+b.shear.toFixed(9)||b.scalex.toFixed(9)!=b.scaley.toFixed(9)&&b.rotate),b.isSuperSimple=!+b.shear.toFixed(9)&&b.scalex.toFixed(9)==b.scaley.toFixed(9)&&!b.rotate,b.noRotation=!+b.shear.toFixed(9)&&!b.rotate,b},b.toTransformString=function(a){var b=a||this.split();return+b.shear.toFixed(9)?"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]:(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[+b.dx.toFixed(4),+b.dy.toFixed(4)]:j)+(b.rotate?"r"+[+b.rotate.toFixed(4),0,0]:j)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:j))}}(f.prototype),a.Matrix=f,a.matrix=function(a,b,c,d,e,g){return new f(a,b,c,d,e,g)}}),d.plugin(function(a,c,d,e,f){function g(d){return function(e){if(b.stop(),e instanceof f&&1==e.node.childNodes.length&&("radialGradient"==e.node.firstChild.tagName||"linearGradient"==e.node.firstChild.tagName||"pattern"==e.node.firstChild.tagName)&&(e=e.node.firstChild,n(this).appendChild(e),e=l(e)),e instanceof c)if("radialGradient"==e.type||"linearGradient"==e.type||"pattern"==e.type){e.node.id||p(e.node,{id:e.id});var g=q(e.node.id)}else g=e.attr(d);else if(g=a.color(e),g.error){var h=a(n(this).ownerSVGElement).gradient(e);h?(h.node.id||p(h.node,{id:h.id}),g=q(h.node.id)):g=e}else g=r(g);var i={};i[d]=g,p(this.node,i),this.node.style[d]=t}}function h(a){b.stop(),a==+a&&(a+="px"),this.node.style.fontSize=a}function i(a){for(var b=[],c=a.childNodes,d=0,e=c.length;e>d;d++){var f=c[d];3==f.nodeType&&b.push(f.nodeValue),"tspan"==f.tagName&&(1==f.childNodes.length&&3==f.firstChild.nodeType?b.push(f.firstChild.nodeValue):b.push(i(f)))}return b}function j(){return b.stop(),this.node.style.fontSize}var k=a._.make,l=a._.wrap,m=a.is,n=a._.getSomeDefs,o=/^url\((['"]?)([^)]+)\1\)$/,p=a._.$,q=a.url,r=String,s=a._.separator,t="";a.deurl=function(a){return String(a).match(o)[2]},b.on("snap.util.attr.mask",function(a){if(a instanceof c||a instanceof f){if(b.stop(),a instanceof f&&1==a.node.childNodes.length&&(a=a.node.firstChild,n(this).appendChild(a),a=l(a)),"mask"==a.type)var d=a;else d=k("mask",n(this)),d.node.appendChild(a.node);!d.node.id&&p(d.node,{id:d.id}),p(this.node,{mask:q(d.id)})}}),function(a){b.on("snap.util.attr.clip",a),b.on("snap.util.attr.clip-path",a),b.on("snap.util.attr.clipPath",a)}(function(a){if(a instanceof c||a instanceof f){b.stop();for(var d,e=a.node;e;){if("clipPath"===e.nodeName){d=new c(e);break}if("svg"===e.nodeName){d=void 0;break}e=e.parentNode}d||(d=k("clipPath",n(this)),d.node.appendChild(a.node),!d.node.id&&p(d.node,{id:d.id})),p(this.node,{"clip-path":q(d.node.id||d.id)})}}),b.on("snap.util.attr.fill",g("fill")),b.on("snap.util.attr.stroke",g("stroke"));var u=/^([lr])(?:\(([^)]*)\))?(.*)$/i;b.on("snap.util.grad.parse",function(a){function b(a,b){for(var c=(b-h)/(a-i),d=i;a>d;d++)f[d].offset=+(+h+c*(d-i)).toFixed(2);i=a,h=b}a=r(a);var c=a.match(u);if(!c)return null;var d=c[1],e=c[2],f=c[3];e=e.split(/\s*,\s*/).map(function(a){return+a==a?+a:a}),1==e.length&&0==e[0]&&(e=[]),f=f.split("-"),f=f.map(function(a){a=a.split(":");var b={color:a[0]};return a[1]&&(b.offset=parseFloat(a[1])),b});var g=f.length,h=0,i=0;g--;for(var j=0;g>j;j++)"offset"in f[j]&&b(j,f[j].offset);return f[g].offset=f[g].offset||100,b(g,f[g].offset),{type:d,params:e,stops:f}}),b.on("snap.util.attr.d",function(c){b.stop(),m(c,"array")&&m(c[0],"array")&&(c=a.path.toString.call(c)),c=r(c),c.match(/[ruo]/i)&&(c=a.path.toAbsolute(c)),p(this.node,{d:c})})(-1),b.on("snap.util.attr.#text",function(a){b.stop(),a=r(a);for(var c=e.doc.createTextNode(a);this.node.firstChild;)this.node.removeChild(this.node.firstChild);this.node.appendChild(c)})(-1),b.on("snap.util.attr.path",function(a){b.stop(),this.attr({d:a})})(-1),b.on("snap.util.attr.class",function(a){b.stop(),this.node.className.baseVal=a})(-1),b.on("snap.util.attr.viewBox",function(a){var c;c=m(a,"object")&&"x"in a?[a.x,a.y,a.width,a.height].join(" "):m(a,"array")?a.join(" "):a,p(this.node,{viewBox:c}),b.stop()})(-1),b.on("snap.util.attr.transform",function(a){this.transform(a),b.stop()})(-1),b.on("snap.util.attr.r",function(a){"rect"==this.type&&(b.stop(),p(this.node,{rx:a,ry:a}))})(-1),b.on("snap.util.attr.textpath",function(a){if(b.stop(),"text"==this.type){var d,e,f;if(!a&&this.textPath){for(e=this.textPath;e.node.firstChild;)this.node.appendChild(e.node.firstChild);return e.remove(),void delete this.textPath}if(m(a,"string")){var g=n(this),h=l(g.parentNode).path(a);g.appendChild(h.node),d=h.id,h.attr({id:d})}else a=l(a),a instanceof c&&(d=a.attr("id"),d||(d=a.id,a.attr({id:d})));if(d)if(e=this.textPath,f=this.node,e)e.attr({"xlink:href":"#"+d});else{for(e=p("textPath",{"xlink:href":"#"+d});f.firstChild;)e.appendChild(f.firstChild);f.appendChild(e),this.textPath=l(e)}}})(-1),b.on("snap.util.attr.text",function(a){if("text"==this.type){for(var c=this.node,d=function(a){var b=p("tspan");if(m(a,"array"))for(var c=0;c1&&(a=Array.prototype.slice.call(arguments,0));var b={};return i(a,"object")&&!i(a,"array")?b=a:null!=a&&(b={points:a}),this.el("polyline",b)},h.polygon=function(a){arguments.length>1&&(a=Array.prototype.slice.call(arguments,0));var b={};return i(a,"object")&&!i(a,"array")?b=a:null!=a&&(b={points:a}),this.el("polygon",b)},function(){function d(){return this.selectAll("stop")}function e(a,b){var d=l("stop"),e={offset:+b+"%"};a=c.color(a),e["stop-color"]=a.hex,a.opacity<1&&(e["stop-opacity"]=a.opacity),l(d,e);for(var f,g=this.stops(),h=0;hb){this.node.insertBefore(d,g[h].node),f=!0;break}}return f||this.node.appendChild(d),this}function f(){if("linearGradient"==this.type){var a=l(this.node,"x1")||0,b=l(this.node,"x2")||1,d=l(this.node,"y1")||0,e=l(this.node,"y2")||0;return c._.box(a,d,math.abs(b-a),math.abs(e-d))}var f=this.node.cx||.5,g=this.node.cy||.5,h=this.node.r||0;return c._.box(f-h,g-h,2*h,2*h)}function g(a){var d=a,e=this.stops();if("string"==typeof a&&(d=b("snap.util.grad.parse",null,"l(0,0,0,1)"+a).firstDefined().stops),c.is(d,"array")){for(var f=0;fh;h++){var i=f[h];d.addStop(i.color,i.offset)}return d}function j(a,b,h,i,j){var k=c._.make("linearGradient",a);return k.stops=d,k.addStop=e,k.getBBox=f,k.setStops=g,null!=b&&l(k.node,{x1:b,y1:h,x2:i,y2:j}),k}function k(a,b,g,h,i,j){var k=c._.make("radialGradient",a);return k.stops=d,k.addStop=e,k.getBBox=f,null!=b&&l(k.node,{cx:b,cy:g,r:h}),null!=i&&null!=j&&l(k.node,{fx:i,fy:j}),k}var l=c._.$;h.gradient=function(a){return i(this.defs,a)},h.gradientLinear=function(a,b,c,d){return j(this.defs,a,b,c,d)},h.gradientRadial=function(a,b,c,d,e){return k(this.defs,a,b,c,d,e)},h.toString=function(){var a,b=this.node.ownerDocument,d=b.createDocumentFragment(),e=b.createElement("div"),f=this.node.cloneNode(!0);return d.appendChild(e),e.appendChild(f),c._.$(f,{xmlns:"http://www.w3.org/2000/svg"}),a=e.innerHTML,d.removeChild(d.firstChild),a},h.toDataURL=function(){return a&&a.btoa?"data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(this))):void 0},h.clear=function(){for(var a,b=this.node.firstChild;b;)a=b.nextSibling,"defs"!=b.tagName?b.parentNode.removeChild(b):h.clear.call({node:b}),b=a}}()}),d.plugin(function(a,b,c,d){function e(a){var b=e.ps=e.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[M](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]}function f(a,b,c,d){return null==a&&(a=b=c=d=0),null==b&&(b=a.y,c=a.width,d=a.height,a=a.x),{x:a,y:b,width:c,w:c,height:d,h:d,x2:a+c,y2:b+d,cx:a+c/2,cy:b+d/2,r1:P.min(c,d)/2,r2:P.max(c,d)/2,r0:P.sqrt(c*c+d*d)/2,path:y(a,b,c,d),vb:[a,b,c,d].join(" ")}}function g(){return this.join(",").replace(N,"$1")}function h(a){var b=L(a);return b.toString=g,b}function i(a,b,c,d,e,f,g,h,i){return null==i?p(a,b,c,d,e,f,g,h):k(a,b,c,d,e,f,g,h,q(a,b,c,d,e,f,g,h,i))}function j(c,d){function e(a){return+(+a).toFixed(3)}return a._.cacher(function(a,f,g){a instanceof b&&(a=a.attr("d")),a=G(a);for(var h,j,l,m,n,o="",p={},q=0,r=0,s=a.length;s>r;r++){if(l=a[r],"M"==l[0])h=+l[1],j=+l[2];else{if(m=i(h,j,l[1],l[2],l[3],l[4],l[5],l[6]),q+m>f){if(d&&!p.start){if(n=i(h,j,l[1],l[2],l[3],l[4],l[5],l[6],f-q),o+=["C"+e(n.start.x),e(n.start.y),e(n.m.x),e(n.m.y),e(n.x),e(n.y)],g)return o;p.start=o,o=["M"+e(n.x),e(n.y)+"C"+e(n.n.x),e(n.n.y),e(n.end.x),e(n.end.y),e(l[5]),e(l[6])].join(),q+=m,h=+l[5],j=+l[6];continue}if(!c&&!d)return n=i(h,j,l[1],l[2],l[3],l[4],l[5],l[6],f-q)}q+=m,h=+l[5],j=+l[6]}o+=l.shift()+l}return p.end=o,n=c?q:d?p:k(h,j,l[0],l[1],l[2],l[3],l[4],l[5],1)},null,a._.clone)}function k(a,b,c,d,e,f,g,h,i){var j=1-i,k=T(j,3),l=T(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*P.atan2(q-s,r-t)/Q;return{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}}function l(b,c,d,e,g,h,i,j){a.is(b,"array")||(b=[b,c,d,e,g,h,i,j]);var k=F.apply(null,b);return f(k.min.x,k.min.y,k.max.x-k.min.x,k.max.y-k.min.y)}function m(a,b,c){return b>=a.x&&b<=a.x+a.width&&c>=a.y&&c<=a.y+a.height}function n(a,b){return a=f(a),b=f(b),m(b,a.x,a.y)||m(b,a.x2,a.y)||m(b,a.x,a.y2)||m(b,a.x2,a.y2)||m(a,b.x,b.y)||m(a,b.x2,b.y)||m(a,b.x,b.y2)||m(a,b.x2,b.y2)||(a.xb.x||b.xa.x)&&(a.yb.y||b.ya.y)}function o(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function p(a,b,c,d,e,f,g,h,i){null==i&&(i=1),i=i>1?1:0>i?0:i;for(var j=i/2,k=12,l=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],m=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],n=0,p=0;k>p;p++){var q=j*l[p]+j,r=o(q,a,c,e,g),s=o(q,b,d,f,h),t=r*r+s*s;n+=m[p]*P.sqrt(t)}return j*n}function q(a,b,c,d,e,f,g,h,i){if(!(0>i||p(a,b,c,d,e,f,g,h)n;)l/=2,m+=(i>j?1:-1)*l,j=p(a,b,c,d,e,f,g,h,m);return m}}function r(a,b,c,d,e,f,g,h){if(!(S(a,c)S(e,g)||S(b,d)S(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+R(a,c).toFixed(2)||n>+S(a,c).toFixed(2)||n<+R(e,g).toFixed(2)||n>+S(e,g).toFixed(2)||o<+R(b,d).toFixed(2)||o>+S(b,d).toFixed(2)||o<+R(f,h).toFixed(2)||o>+S(f,h).toFixed(2)))return{x:l,y:m}}}}function s(a,b,c){var d=l(a),e=l(b);if(!n(d,e))return c?0:[];for(var f=p.apply(0,a),g=p.apply(0,b),h=~~(f/8),i=~~(g/8),j=[],m=[],o={},q=c?0:[],s=0;h+1>s;s++){var t=k.apply(0,a.concat(s/h));j.push({x:t.x,y:t.y,t:s/h})}for(s=0;i+1>s;s++)t=k.apply(0,b.concat(s/i)),m.push({x:t.x,y:t.y,t:s/i});for(s=0;h>s;s++)for(var u=0;i>u;u++){var v=j[s],w=j[s+1],x=m[u],y=m[u+1],z=U(w.x-v.x)<.001?"y":"x",A=U(y.x-x.x)<.001?"y":"x",B=r(v.x,v.y,w.x,w.y,x.x,x.y,y.x,y.y);if(B){if(o[B.x.toFixed(4)]==B.y.toFixed(4))continue;o[B.x.toFixed(4)]=B.y.toFixed(4);var C=v.t+U((B[z]-v[z])/(w[z]-v[z]))*(w.t-v.t),D=x.t+U((B[A]-x[A])/(y[A]-x[A]))*(y.t-x.t);C>=0&&1>=C&&D>=0&&1>=D&&(c?q++:q.push({x:B.x,y:B.y,t1:C,t2:D}))}}return q}function t(a,b){return v(a,b)}function u(a,b){return v(a,b,1)}function v(a,b,c){a=G(a),b=G(b);for(var d,e,f,g,h,i,j,k,l,m,n=c?0:[],o=0,p=a.length;p>o;o++){var q=a[o];if("M"==q[0])d=h=q[1],e=i=q[2];else{"C"==q[0]?(l=[d,e].concat(q.slice(1)),d=l[6],e=l[7]):(l=[d,e,d,e,h,i,h,i],d=h,e=i);for(var r=0,t=b.length;t>r;r++){var u=b[r];if("M"==u[0])f=j=u[1],g=k=u[2];else{"C"==u[0]?(m=[f,g].concat(u.slice(1)),f=m[6],g=m[7]):(m=[f,g,f,g,j,k,j,k],f=j,g=k);var v=s(l,m,c);if(c)n+=v;else{for(var w=0,x=v.length;x>w;w++)v[w].segment1=o,v[w].segment2=r,v[w].bez1=l,v[w].bez2=m;n=n.concat(v)}}}}}return n}function w(a,b,c){var d=x(a);return m(d,b,c)&&v(a,[["M",b,c],["H",d.x2+10]],1)%2==1}function x(a){var b=e(a);if(b.bbox)return L(b.bbox);if(!a)return f();a=G(a);for(var c,d=0,g=0,h=[],i=[],j=0,k=a.length;k>j;j++)if(c=a[j],"M"==c[0])d=c[1],g=c[2],h.push(d),i.push(g);else{var l=F(d,g,c[1],c[2],c[3],c[4],c[5],c[6]);h=h.concat(l.min.x,l.max.x),i=i.concat(l.min.y,l.max.y),d=c[5],g=c[6]}var m=R.apply(0,h),n=R.apply(0,i),o=S.apply(0,h),p=S.apply(0,i),q=f(m,n,o-m,p-n);return b.bbox=L(q),q}function y(a,b,c,d,e){if(e)return[["M",+a+ +e,b],["l",c-2*e,0],["a",e,e,0,0,1,e,e],["l",0,d-2*e],["a",e,e,0,0,1,-e,e],["l",2*e-c,0],["a",e,e,0,0,1,-e,-e],["l",0,2*e-d],["a",e,e,0,0,1,e,-e],["z"]];var f=[["M",a,b],["l",c,0],["l",0,d],["l",-c,0],["z"]];return f.toString=g,f}function z(a,b,c,d,e){if(null==e&&null==d&&(d=c),a=+a,b=+b,c=+c,d=+d,null!=e)var f=Math.PI/180,h=a+c*Math.cos(-d*f),i=a+c*Math.cos(-e*f),j=b+c*Math.sin(-d*f),k=b+c*Math.sin(-e*f),l=[["M",h,j],["A",c,c,0,+(e-d>180),0,i,k]];else l=[["M",a,b],["m",0,-d],["a",c,d,0,1,1,0,2*d],["a",c,d,0,1,1,0,-2*d],["z"]];return l.toString=g,l}function A(b){var c=e(b),d=String.prototype.toLowerCase;if(c.rel)return h(c.rel);a.is(b,"array")&&a.is(b&&b[0],"array")||(b=a.parsePathString(b));var f=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=b[0][1],j=b[0][2],k=i,l=j,m++,f.push(["M",i,j]));for(var n=m,o=b.length;o>n;n++){var p=f[n]=[],q=b[n];if(q[0]!=d.call(q[0]))switch(p[0]=d.call(q[0]),p[0]){case"a":p[1]=q[1],p[2]=q[2],p[3]=q[3],p[4]=q[4],p[5]=q[5],p[6]=+(q[6]-i).toFixed(3),p[7]=+(q[7]-j).toFixed(3);break;case"v":p[1]=+(q[1]-j).toFixed(3);break;case"m":k=q[1],l=q[2];default:for(var r=1,s=q.length;s>r;r++)p[r]=+(q[r]-(r%2?i:j)).toFixed(3)}else{p=f[n]=[],"m"==q[0]&&(k=q[1]+i,l=q[2]+j);for(var t=0,u=q.length;u>t;t++)f[n][t]=q[t]}var v=f[n].length;switch(f[n][0]){case"z":i=k,j=l;break;case"h":i+=+f[n][v-1];break;case"v":j+=+f[n][v-1];break;default:i+=+f[n][v-2],j+=+f[n][v-1]}}return f.toString=g,c.rel=h(f),f}function B(b){var c=e(b);if(c.abs)return h(c.abs);if(K(b,"array")&&K(b&&b[0],"array")||(b=a.parsePathString(b)),!b||!b.length)return[["M",0,0]];var d,f=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=+b[0][1],j=+b[0][2],k=i,l=j,m++,f[0]=["M",i,j]);for(var n,o,p=3==b.length&&"M"==b[0][0]&&"R"==b[1][0].toUpperCase()&&"Z"==b[2][0].toUpperCase(),q=m,r=b.length;r>q;q++){if(f.push(n=[]),o=b[q],d=o[0],d!=d.toUpperCase())switch(n[0]=d.toUpperCase(),n[0]){case"A":n[1]=o[1],n[2]=o[2],n[3]=o[3],n[4]=o[4],n[5]=o[5],n[6]=+o[6]+i,n[7]=+o[7]+j;break;case"V":n[1]=+o[1]+j;break;case"H":n[1]=+o[1]+i;break;case"R":for(var s=[i,j].concat(o.slice(1)),t=2,u=s.length;u>t;t++)s[t]=+s[t]+i,s[++t]=+s[t]+j;f.pop(),f=f.concat(I(s,p));break;case"O":f.pop(),s=z(i,j,o[1],o[2]),s.push(s[0]),f=f.concat(s);break;case"U":f.pop(),f=f.concat(z(i,j,o[1],o[2],o[3])),n=["U"].concat(f[f.length-1].slice(-2));break;case"M":k=+o[1]+i,l=+o[2]+j;default:for(t=1,u=o.length;u>t;t++)n[t]=+o[t]+(t%2?i:j)}else if("R"==d)s=[i,j].concat(o.slice(1)),f.pop(),f=f.concat(I(s,p)),n=["R"].concat(o.slice(-2));else if("O"==d)f.pop(),s=z(i,j,o[1],o[2]),s.push(s[0]),f=f.concat(s);else if("U"==d)f.pop(),f=f.concat(z(i,j,o[1],o[2],o[3])),n=["U"].concat(f[f.length-1].slice(-2));else for(var v=0,w=o.length;w>v;v++)n[v]=o[v];if(d=d.toUpperCase(),"O"!=d)switch(n[0]){case"Z":i=+k,j=+l;break;case"H":i=n[1];break;case"V":j=n[1];break;case"M":k=n[n.length-2],l=n[n.length-1];default:i=n[n.length-2],j=n[n.length-1]}}return f.toString=g,c.abs=h(f),f}function C(a,b,c,d){return[a,b,c,d,c,d]}function D(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]}function E(b,c,d,e,f,g,h,i,j,k){var l,m=120*Q/180,n=Q/180*(+f||0),o=[],p=a._.cacher(function(a,b,c){var d=a*P.cos(c)-b*P.sin(c),e=a*P.sin(c)+b*P.cos(c);return{x:d,y:e}});if(!d||!e)return[b,c,i,j,i,j];if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(b,c,-n),b=l.x,c=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(P.cos(Q/180*f),P.sin(Q/180*f),(b-i)/2),r=(c-j)/2,s=q*q/(d*d)+r*r/(e*e);s>1&&(s=P.sqrt(s),d=s*d,e=s*e);var t=d*d,u=e*e,v=(g==h?-1:1)*P.sqrt(U((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*d*r/e+(b+i)/2,x=v*-e*q/d+(c+j)/2,y=P.asin(((c-x)/e).toFixed(9)),z=P.asin(((j-x)/e).toFixed(9));y=w>b?Q-y:y,z=w>i?Q-z:z,0>y&&(y=2*Q+y),0>z&&(z=2*Q+z),h&&y>z&&(y-=2*Q),!h&&z>y&&(z-=2*Q)}var A=z-y;if(U(A)>m){var B=z,C=i,D=j;z=y+m*(h&&z>y?1:-1),i=w+d*P.cos(z),j=x+e*P.sin(z),o=E(i,j,d,e,f,0,h,C,D,[z,B,w,x])}A=z-y;var F=P.cos(y),G=P.sin(y),H=P.cos(z),I=P.sin(z),J=P.tan(A/4),K=4/3*d*J,L=4/3*e*J,M=[b,c],N=[b+K*G,c-L*F],O=[i+K*I,j-L*H],R=[i,j];if(N[0]=2*M[0]-N[0],N[1]=2*M[1]-N[1],k)return[N,O,R].concat(o);o=[N,O,R].concat(o).join().split(",");for(var S=[],T=0,V=o.length;V>T;T++)S[T]=T%2?p(o[T-1],o[T],n).y:p(o[T],o[T+1],n).x;return S}function F(a,b,c,d,e,f,g,h){for(var i,j,k,l,m,n,o,p,q=[],r=[[],[]],s=0;2>s;++s)if(0==s?(j=6*a-12*c+6*e,i=-3*a+9*c-9*e+3*g,k=3*c-3*a):(j=6*b-12*d+6*f,i=-3*b+9*d-9*f+3*h,k=3*d-3*b),U(i)<1e-12){if(U(j)<1e-12)continue;l=-k/j,l>0&&1>l&&q.push(l)}else o=j*j-4*k*i,p=P.sqrt(o),0>o||(m=(-j+p)/(2*i),m>0&&1>m&&q.push(m),n=(-j-p)/(2*i),n>0&&1>n&&q.push(n));for(var t,u=q.length,v=u;u--;)l=q[u],t=1-l,r[0][u]=t*t*t*a+3*t*t*l*c+3*t*l*l*e+l*l*l*g,r[1][u]=t*t*t*b+3*t*t*l*d+3*t*l*l*f+l*l*l*h;return r[0][v]=a,r[1][v]=b,r[0][v+1]=g,r[1][v+1]=h,r[0].length=r[1].length=v+2,{min:{x:R.apply(0,r[0]),y:R.apply(0,r[1])},max:{x:S.apply(0,r[0]),y:S.apply(0,r[1])}}}function G(a,b){var c=!b&&e(a);if(!b&&c.curve)return h(c.curve);for(var d=B(a),f=b&&B(b),g={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},i={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},j=(function(a,b,c){var d,e;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"].concat(E.apply(0,[b.x,b.y].concat(a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e].concat(a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"].concat(D(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"].concat(D(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"].concat(C(b.x,b.y,a[1],a[2]));break;case"H":a=["C"].concat(C(b.x,b.y,a[1],b.y));break;case"V":a=["C"].concat(C(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"].concat(C(b.x,b.y,b.X,b.Y))}return a}),k=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)m[b]="A",f&&(n[b]="A"),a.splice(b++,0,["C"].concat(c.splice(0,6)));a.splice(b,1),r=S(d.length,f&&f.length||0)}},l=function(a,b,c,e,g){a&&b&&"M"==a[g][0]&&"M"!=b[g][0]&&(b.splice(g,0,["M",e.x,e.y]),c.bx=0,c.by=0,c.x=a[g][1],c.y=a[g][2],r=S(d.length,f&&f.length||0))},m=[],n=[],o="",p="",q=0,r=S(d.length,f&&f.length||0);r>q;q++){d[q]&&(o=d[q][0]),"C"!=o&&(m[q]=o,q&&(p=m[q-1])),d[q]=j(d[q],g,p),"A"!=m[q]&&"C"==o&&(m[q]="C"),k(d,q),f&&(f[q]&&(o=f[q][0]),"C"!=o&&(n[q]=o,q&&(p=n[q-1])),f[q]=j(f[q],i,p),"A"!=n[q]&&"C"==o&&(n[q]="C"),k(f,q)),l(d,f,g,i,q),l(f,d,i,g,q);var s=d[q],t=f&&f[q],u=s.length,v=f&&t.length;g.x=s[u-2],g.y=s[u-1],g.bx=O(s[u-4])||g.x,g.by=O(s[u-3])||g.y,i.bx=f&&(O(t[v-4])||i.x),i.by=f&&(O(t[v-3])||i.y),i.x=f&&t[v-2],i.y=f&&t[v-1]}return f||(c.curve=h(d)),f?[d,f]:d}function H(a,b){if(!b)return a;var c,d,e,f,g,h,i;for(a=G(a),e=0,g=a.length;g>e;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a}function I(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}var J=b.prototype,K=a.is,L=a._.clone,M="hasOwnProperty",N=/,?([a-z]),?/gi,O=parseFloat,P=Math,Q=P.PI,R=P.min,S=P.max,T=P.pow,U=P.abs,V=j(1),W=j(),X=j(0,1),Y=a._unit2px,Z={path:function(a){return a.attr("path")},circle:function(a){var b=Y(a);return z(b.cx,b.cy,b.r)},ellipse:function(a){var b=Y(a);return z(b.cx||0,b.cy||0,b.rx,b.ry); +},rect:function(a){var b=Y(a);return y(b.x||0,b.y||0,b.width,b.height,b.rx,b.ry)},image:function(a){var b=Y(a);return y(b.x||0,b.y||0,b.width,b.height)},line:function(a){return"M"+[a.attr("x1")||0,a.attr("y1")||0,a.attr("x2"),a.attr("y2")]},polyline:function(a){return"M"+a.attr("points")},polygon:function(a){return"M"+a.attr("points")+"z"},deflt:function(a){var b=a.node.getBBox();return y(b.x,b.y,b.width,b.height)}};a.path=e,a.path.getTotalLength=V,a.path.getPointAtLength=W,a.path.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return X(a,b).end;var d=X(a,c,1);return b?X(d,b).end:d},J.getTotalLength=function(){return this.node.getTotalLength?this.node.getTotalLength():void 0},J.getPointAtLength=function(a){return W(this.attr("d"),a)},J.getSubpath=function(b,c){return a.path.getSubpath(this.attr("d"),b,c)},a._.box=f,a.path.findDotsAtSegment=k,a.path.bezierBBox=l,a.path.isPointInsideBBox=m,a.closest=function(b,c,d,e){for(var g=100,h=f(b-g/2,c-g/2,g,g),i=[],j=d[0].hasOwnProperty("x")?function(a){return{x:d[a].x,y:d[a].y}}:function(a){return{x:d[a],y:e[a]}},k=0;1e6>=g&&!k;){for(var l=0,n=d.length;n>l;l++){var o=j(l);if(m(h,o.x,o.y)){k++,i.push(o);break}}k||(g*=2,h=f(b-g/2,c-g/2,g,g))}if(1e6!=g){var p,q=1/0;for(l=0,n=i.length;n>l;l++){var r=a.len(b,c,i[l].x,i[l].y);q>r&&(q=r,i[l].len=r,p=i[l])}return p}},a.path.isBBoxIntersect=n,a.path.intersection=t,a.path.intersectionNumber=u,a.path.isPointInside=w,a.path.getBBox=x,a.path.get=Z,a.path.toRelative=A,a.path.toAbsolute=B,a.path.toCubic=G,a.path.map=H,a.path.toString=g,a.path.clone=h}),d.plugin(function(a,d,e,f){var g=Math.max,h=Math.min,i=function(a){if(this.items=[],this.bindings={},this.length=0,this.type="set",a)for(var b=0,c=a.length;c>b;b++)a[b]&&(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},j=i.prototype;j.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],a&&(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},j.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},j.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this},j.animate=function(d,e,f,g){"function"!=typeof f||f.length||(g=f,f=c.linear),d instanceof a._.Animation&&(g=d.callback,f=d.easing,e=f.dur,d=d.attr);var h=arguments;if(a.is(d,"array")&&a.is(h[h.length-1],"array"))var i=!0;var j,k=function(){j?this.b=j:j=this.b},l=0,m=this,n=g&&function(){++l==m.length&&g.call(this)};return this.forEach(function(a,c){b.once("snap.animcreated."+a.id,k),i?h[c]&&a.animate.apply(a,h[c]):a.animate(d,e,f,n)})},j.remove=function(){for(;this.length;)this.pop().remove();return this},j.bind=function(a,b,c){var d={};if("function"==typeof b)this.bindings[a]=b;else{var e=c||a;this.bindings[a]=function(a){d[e]=a,b.attr(d)}}return this},j.attr=function(a){var b={};for(var c in a)this.bindings[c]?this.bindings[c](a[c]):b[c]=a[c];for(var d=0,e=this.items.length;e>d;d++)this.items[d].attr(b);return this},j.clear=function(){for(;this.length;)this.pop()},j.splice=function(a,b,c){a=0>a?g(this.length+a,0):a,b=g(0,h(this.length-a,b));var d,e=[],f=[],j=[];for(d=2;dd;d++)f.push(this[a+d]);for(;dd?j[d]:e[d-k];for(d=this.items.length=this.length-=b-k;this[d];)delete this[d++];return new i(f)},j.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0;return!1},j.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},j.getBBox=function(){for(var a=[],b=[],c=[],d=[],e=this.items.length;e--;)if(!this.items[e].removed){var f=this.items[e].getBBox();a.push(f.x),b.push(f.y),c.push(f.x+f.width),d.push(f.y+f.height)}return a=h.apply(0,a),b=h.apply(0,b),c=g.apply(0,c),d=g.apply(0,d),{x:a,y:b,x2:c,y2:d,width:c-a,height:d-b,cx:a+(c-a)/2,cy:b+(d-b)/2}},j.clone=function(a){a=new i;for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},j.toString=function(){return"Snap‘s set"},j.type="set",a.Set=i,a.set=function(){var a=new i;return arguments.length&&a.push.apply(a,Array.prototype.slice.call(arguments,0)),a}}),d.plugin(function(a,c,d,e){function f(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}}function g(b,c,d){b=b||new a.Matrix,c=c||new a.Matrix,b=a.parseTransformString(b.toTransformString())||[],c=a.parseTransformString(c.toTransformString())||[];for(var e,g,h,i,j=Math.max(b.length,c.length),k=[],n=[],o=0;j>o;o++){if(h=b[o]||f(c[o]),i=c[o]||f(h),h[0]!=i[0]||"r"==h[0].toLowerCase()&&(h[2]!=i[2]||h[3]!=i[3])||"s"==h[0].toLowerCase()&&(h[3]!=i[3]||h[4]!=i[4])){b=a._.transform2matrix(b,d()),c=a._.transform2matrix(c,d()),k=[["m",b.a,b.b,b.c,b.d,b.e,b.f]],n=[["m",c.a,c.b,c.c,c.d,c.e,c.f]];break}for(k[o]=[],n[o]=[],e=0,g=Math.max(h.length,i.length);g>e;e++)e in h&&(k[o][e]=h[e]),e in i&&(n[o][e]=i[e])}return{from:m(k),to:m(n),f:l(k)}}function h(a){return a}function i(a){return function(b){return+b.toFixed(3)+a}}function j(a){return a.join(" ")}function k(b){return a.rgb(b[0],b[1],b[2],b[3])}function l(a){var b,c,d,e,f,g,h=0,i=[];for(b=0,c=a.length;c>b;b++){for(f="[",g=['"'+a[b][0]+'"'],d=1,e=a[b].length;e>d;d++)g[d]="val["+h++ +"]";f+=g+"]",i[b]=f}return Function("val","return Snap.path.toString.call(["+i+"])")}function m(a){for(var b=[],c=0,d=a.length;d>c;c++)for(var e=1,f=a[c].length;f>e;e++)b.push(a[c][e]);return b}function n(a){return isFinite(a)}function o(b,c){return a.is(b,"array")&&a.is(c,"array")?b.toString()==c.toString():!1}var p={},q=/[%a-z]+$/i,r=String;p.stroke=p.fill="colour",c.prototype.equal=function(a,c){return b("snap.util.equal",this,a,c).firstDefined()},b.on("snap.util.equal",function(b,c){var d,e,f=r(this.attr(b)||""),s=this;if("colour"==p[b])return d=a.color(f),e=a.color(c),{from:[d.r,d.g,d.b,d.opacity],to:[e.r,e.g,e.b,e.opacity],f:k};if("viewBox"==b)return d=this.attr(b).vb.split(" ").map(Number),e=c.split(" ").map(Number),{from:d,to:e,f:j};if("transform"==b||"gradientTransform"==b||"patternTransform"==b)return"string"==typeof c&&(c=r(c).replace(/\.{3}|\u2026/g,f)),f=this.matrix,c=a._.rgTransform.test(c)?a._.transform2matrix(c,this.getBBox()):a._.transform2matrix(a._.svgTransform2string(c),this.getBBox()),g(f,c,function(){return s.getBBox(1)});if("d"==b||"path"==b)return d=a.path.toCubic(f,c),{from:m(d[0]),to:m(d[1]),f:l(d[0])};if("points"==b)return d=r(f).split(a._.separator),e=r(c).split(a._.separator),{from:d,to:e,f:function(a){return a}};if(n(f)&&n(c))return{from:parseFloat(f),to:parseFloat(c),f:h};var t=f.match(q),u=r(c).match(q);return t&&o(t,u)?{from:parseFloat(f),to:parseFloat(c),f:i(t)}:{from:this.asPX(b),to:this.asPX(b,c),f:h}})}),d.plugin(function(a,c,d,e){for(var f=c.prototype,g="hasOwnProperty",h=("createTouch"in e.doc),i=["click","dblclick","mousedown","mousemove","mouseout","mouseover","mouseup","touchstart","touchmove","touchend","touchcancel"],j={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},k=(function(a,b){var c="y"==a?"scrollTop":"scrollLeft",d=b&&b.node?b.node.ownerDocument:e.doc;return d[c in d.documentElement?"documentElement":"body"][c]}),l=function(){return this.originalEvent.preventDefault()},m=function(){return this.originalEvent.stopPropagation()},n=function(a,b,c,d){var e=h&&j[b]?j[b]:b,f=function(e){var f=k("y",d),i=k("x",d);if(h&&j[g](b))for(var n=0,o=e.targetTouches&&e.targetTouches.length;o>n;n++)if(e.targetTouches[n].target==a||a.contains(e.targetTouches[n].target)){var p=e;e=e.targetTouches[n],e.originalEvent=p,e.preventDefault=l,e.stopPropagation=m;break}var q=e.clientX+i,r=e.clientY+f;return c.call(d,e,q,r)};return b!==e&&a.addEventListener(b,f,!1),a.addEventListener(e,f,!1),function(){return b!==e&&a.removeEventListener(b,f,!1),a.removeEventListener(e,f,!1),!0}},o=[],p=function(a){for(var c,d=a.clientX,e=a.clientY,f=k("y"),g=k("x"),i=o.length;i--;){if(c=o[i],h){for(var j,l=a.touches&&a.touches.length;l--;)if(j=a.touches[l],j.identifier==c.el._drag.id||c.el.node.contains(j.target)){d=j.clientX,e=j.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}else a.preventDefault();var m=c.el.node;m.nextSibling,m.parentNode,m.style.display;d+=g,e+=f,b("snap.drag.move."+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,a)}},q=function(c){a.unmousemove(p).unmouseup(q);for(var d,e=o.length;e--;)d=o[e],d.el._drag={},b("snap.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,c),b.off("snap.drag.*."+d.el.id);o=[]},r=i.length;r--;)!function(b){a[b]=f[b]=function(c,d){if(a.is(c,"function"))this.events=this.events||[],this.events.push({name:b,f:c,unbind:n(this.node||document,b,c,d||this)});else for(var e=0,f=this.events.length;f>e;e++)if(this.events[e].name==b)try{this.events[e].f.call(this)}catch(g){}return this},a["un"+b]=f["un"+b]=function(a){for(var c=this.events||[],d=c.length;d--;)if(c[d].name==b&&(c[d].f==a||!a))return c[d].unbind(),c.splice(d,1),!c.length&&delete this.events,this;return this}}(i[r]);f.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},f.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var s=[];f.drag=function(c,d,e,f,g,h){function i(i,j,l){(i.originalEvent||i).preventDefault(),k._drag.x=j,k._drag.y=l,k._drag.id=i.identifier,!o.length&&a.mousemove(p).mouseup(q),o.push({el:k,move_scope:f,start_scope:g,end_scope:h}),d&&b.on("snap.drag.start."+k.id,d),c&&b.on("snap.drag.move."+k.id,c),e&&b.on("snap.drag.end."+k.id,e),b("snap.drag.start."+k.id,g||f||k,j,l,i)}function j(a,c,d){b("snap.draginit."+k.id,k,a,c,d)}var k=this;if(!arguments.length){var l;return k.drag(function(a,b){this.attr({transform:l+(l?"T":"t")+[a,b]})},function(){l=this.transform().local})}return b.on("snap.draginit."+k.id,i),k._drag={},s.push({el:k,start:i,init:j}),k.mousedown(j),k},f.undrag=function(){for(var c=s.length;c--;)s[c].el==this&&(this.unmousedown(s[c].init),s.splice(c,1),b.unbind("snap.drag.*."+this.id),b.unbind("snap.draginit."+this.id));return!s.length&&a.unmousemove(p).unmouseup(q),this}}),d.plugin(function(a,c,d,e){var f=(c.prototype,d.prototype),g=/^\s*url\((.+)\)/,h=String,i=a._.$;a.filter={},f.filter=function(b){var d=this;"svg"!=d.type&&(d=d.paper);var e=a.parse(h(b)),f=a._.id(),g=(d.node.offsetWidth,d.node.offsetHeight,i("filter"));return i(g,{id:f,filterUnits:"userSpaceOnUse"}),g.appendChild(e.node),d.defs.appendChild(g),new c(g)},b.on("snap.util.getattr.filter",function(){b.stop();var c=i(this.node,"filter");if(c){var d=h(c).match(g);return d&&a.select(d[1])}}),b.on("snap.util.attr.filter",function(d){if(d instanceof c&&"filter"==d.type){b.stop();var e=d.node.id;e||(i(d.node,{id:d.id}),e=d.id),i(this.node,{filter:a.url(e)})}d&&"none"!=d||(b.stop(),this.node.removeAttribute("filter"))}),a.filter.blur=function(b,c){null==b&&(b=2);var d=null==c?b:[b,c];return a.format('',{def:d})},a.filter.blur.toString=function(){return this()},a.filter.shadow=function(b,c,d,e,f){return null==f&&(null==e?(f=d,d=4,e="#000"):(f=e,e=d,d=4)),null==d&&(d=4),null==f&&(f=1),null==b&&(b=0,c=2),null==c&&(c=b),e=a.color(e),a.format('',{color:e,dx:b,dy:c,blur:d,opacity:f})},a.filter.shadow.toString=function(){return this()},a.filter.grayscale=function(b){return null==b&&(b=1),a.format('',{a:.2126+.7874*(1-b),b:.7152-.7152*(1-b),c:.0722-.0722*(1-b),d:.2126-.2126*(1-b),e:.7152+.2848*(1-b),f:.0722-.0722*(1-b),g:.2126-.2126*(1-b),h:.0722+.9278*(1-b)})},a.filter.grayscale.toString=function(){return this()},a.filter.sepia=function(b){return null==b&&(b=1),a.format('',{a:.393+.607*(1-b),b:.769-.769*(1-b),c:.189-.189*(1-b),d:.349-.349*(1-b),e:.686+.314*(1-b),f:.168-.168*(1-b),g:.272-.272*(1-b),h:.534-.534*(1-b),i:.131+.869*(1-b)})},a.filter.sepia.toString=function(){return this()},a.filter.saturate=function(b){return null==b&&(b=1),a.format('',{amount:1-b})},a.filter.saturate.toString=function(){return this()},a.filter.hueRotate=function(b){return b=b||0,a.format('',{angle:b})},a.filter.hueRotate.toString=function(){return this()},a.filter.invert=function(b){return null==b&&(b=1),a.format('',{amount:b,amount2:1-b})},a.filter.invert.toString=function(){return this()},a.filter.brightness=function(b){return null==b&&(b=1),a.format('',{amount:b})},a.filter.brightness.toString=function(){return this()},a.filter.contrast=function(b){return null==b&&(b=1),a.format('',{amount:b,amount2:.5-b/2})},a.filter.contrast.toString=function(){return this()}}),d.plugin(function(a,b,c,d,e){var f=a._.box,g=a.is,h=/^[^a-z]*([tbmlrc])/i,i=function(){return"T"+this.dx+","+this.dy};b.prototype.getAlign=function(a,b){null==b&&g(a,"string")&&(b=a,a=null),a=a||this.paper;var c=a.getBBox?a.getBBox():f(a),d=this.getBBox(),e={};switch(b=b&&b.match(h),b=b?b[1].toLowerCase():"c"){case"t":e.dx=0,e.dy=c.y-d.y;break;case"b":e.dx=0,e.dy=c.y2-d.y2;break;case"m":e.dx=0,e.dy=c.cy-d.cy;break;case"l":e.dx=c.x-d.x,e.dy=0;break;case"r":e.dx=c.x2-d.x2,e.dy=0;break;default:e.dx=c.cx-d.cx,e.dy=0}return e.toString=i,e},b.prototype.align=function(a,b){return this.transform("..."+this.getAlign(a,b))}}),d.plugin(function(b,c,d,e){function f(a){a=a.split(/(?=#)/);var b=new String(a[5]);return b[50]=a[0],b[100]=a[1],b[200]=a[2],b[300]=a[3],b[400]=a[4],b[500]=a[5],b[600]=a[6],b[700]=a[7],b[800]=a[8],b[900]=a[9],a[10]&&(b.A100=a[10],b.A200=a[11],b.A400=a[12],b.A700=a[13]),b}var g="#ffebee#ffcdd2#ef9a9a#e57373#ef5350#f44336#e53935#d32f2f#c62828#b71c1c#ff8a80#ff5252#ff1744#d50000",h="#FCE4EC#F8BBD0#F48FB1#F06292#EC407A#E91E63#D81B60#C2185B#AD1457#880E4F#FF80AB#FF4081#F50057#C51162",i="#F3E5F5#E1BEE7#CE93D8#BA68C8#AB47BC#9C27B0#8E24AA#7B1FA2#6A1B9A#4A148C#EA80FC#E040FB#D500F9#AA00FF",j="#EDE7F6#D1C4E9#B39DDB#9575CD#7E57C2#673AB7#5E35B1#512DA8#4527A0#311B92#B388FF#7C4DFF#651FFF#6200EA",k="#E8EAF6#C5CAE9#9FA8DA#7986CB#5C6BC0#3F51B5#3949AB#303F9F#283593#1A237E#8C9EFF#536DFE#3D5AFE#304FFE",l="#E3F2FD#BBDEFB#90CAF9#64B5F6#64B5F6#2196F3#1E88E5#1976D2#1565C0#0D47A1#82B1FF#448AFF#2979FF#2962FF",m="#E1F5FE#B3E5FC#81D4FA#4FC3F7#29B6F6#03A9F4#039BE5#0288D1#0277BD#01579B#80D8FF#40C4FF#00B0FF#0091EA",n="#E0F7FA#B2EBF2#80DEEA#4DD0E1#26C6DA#00BCD4#00ACC1#0097A7#00838F#006064#84FFFF#18FFFF#00E5FF#00B8D4",o="#E0F2F1#B2DFDB#80CBC4#4DB6AC#26A69A#009688#00897B#00796B#00695C#004D40#A7FFEB#64FFDA#1DE9B6#00BFA5",p="#E8F5E9#C8E6C9#A5D6A7#81C784#66BB6A#4CAF50#43A047#388E3C#2E7D32#1B5E20#B9F6CA#69F0AE#00E676#00C853",q="#F1F8E9#DCEDC8#C5E1A5#AED581#9CCC65#8BC34A#7CB342#689F38#558B2F#33691E#CCFF90#B2FF59#76FF03#64DD17",r="#F9FBE7#F0F4C3#E6EE9C#DCE775#D4E157#CDDC39#C0CA33#AFB42B#9E9D24#827717#F4FF81#EEFF41#C6FF00#AEEA00",s="#FFFDE7#FFF9C4#FFF59D#FFF176#FFEE58#FFEB3B#FDD835#FBC02D#F9A825#F57F17#FFFF8D#FFFF00#FFEA00#FFD600",t="#FFF8E1#FFECB3#FFE082#FFD54F#FFCA28#FFC107#FFB300#FFA000#FF8F00#FF6F00#FFE57F#FFD740#FFC400#FFAB00",u="#FFF3E0#FFE0B2#FFCC80#FFB74D#FFA726#FF9800#FB8C00#F57C00#EF6C00#E65100#FFD180#FFAB40#FF9100#FF6D00",v="#FBE9E7#FFCCBC#FFAB91#FF8A65#FF7043#FF5722#F4511E#E64A19#D84315#BF360C#FF9E80#FF6E40#FF3D00#DD2C00",w="#EFEBE9#D7CCC8#BCAAA4#A1887F#8D6E63#795548#6D4C41#5D4037#4E342E#3E2723",x="#FAFAFA#F5F5F5#EEEEEE#E0E0E0#BDBDBD#9E9E9E#757575#616161#424242#212121",y="#ECEFF1#CFD8DC#B0BEC5#90A4AE#78909C#607D8B#546E7A#455A64#37474F#263238";b.mui={},b.flat={},b.mui.red=f(g),b.mui.pink=f(h),b.mui.purple=f(i),b.mui.deeppurple=f(j),b.mui.indigo=f(k),b.mui.blue=f(l),b.mui.lightblue=f(m),b.mui.cyan=f(n),b.mui.teal=f(o),b.mui.green=f(p),b.mui.lightgreen=f(q),b.mui.lime=f(r),b.mui.yellow=f(s),b.mui.amber=f(t),b.mui.orange=f(u),b.mui.deeporange=f(v),b.mui.brown=f(w),b.mui.grey=f(x),b.mui.bluegrey=f(y),b.flat.turquoise="#1abc9c",b.flat.greensea="#16a085",b.flat.sunflower="#f1c40f",b.flat.orange="#f39c12",b.flat.emerland="#2ecc71",b.flat.nephritis="#27ae60",b.flat.carrot="#e67e22",b.flat.pumpkin="#d35400",b.flat.peterriver="#3498db",b.flat.belizehole="#2980b9",b.flat.alizarin="#e74c3c",b.flat.pomegranate="#c0392b",b.flat.amethyst="#9b59b6",b.flat.wisteria="#8e44ad",b.flat.clouds="#ecf0f1",b.flat.silver="#bdc3c7",b.flat.wetasphalt="#34495e",b.flat.midnightblue="#2c3e50",b.flat.concrete="#95a5a6",b.flat.asbestos="#7f8c8d",b.importMUIColors=function(){for(var c in b.mui)b.mui.hasOwnProperty(c)&&(a[c]=b.mui[c])}}),d}); \ No newline at end of file diff --git a/dist/snap.svg.js b/dist/snap.svg.js index 5475170..86019f6 100644 --- a/dist/snap.svg.js +++ b/dist/snap.svg.js @@ -1,6 +1,6 @@ -// Snap.svg 0.4.1 +// Snap.svg 0.5.0 // -// Copyright (c) 2013 – 2015 Adobe Systems Incorporated. All rights reserved. +// Copyright (c) 2013 – 2017 Adobe Systems Incorporated. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// build: 2015-04-13 +// build: 2017-02-05 // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. // @@ -30,13 +30,13 @@ // See the License for the specific language governing permissions and // limitations under the License. // ┌────────────────────────────────────────────────────────────┐ \\ -// │ Eve 0.4.2 - JavaScript Events Library │ \\ +// │ Eve 0.5.0 - JavaScript Events Library │ \\ // ├────────────────────────────────────────────────────────────┤ \\ // │ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\ // └────────────────────────────────────────────────────────────┘ \\ (function (glob) { - var version = "0.4.2", + var version = "0.5.0", has = "hasOwnProperty", separator = /[\.\/]/, comaseparator = /\s*,\s*/, @@ -63,6 +63,11 @@ } } }, + objtos = Object.prototype.toString, + Str = String, + isArray = Array.isArray || function (ar) { + return ar instanceof Array || objtos.call(ar) == "[object Array]"; + }; /*\ * eve [ method ] @@ -78,7 +83,6 @@ = (object) array of returned values from the listeners. Array has two methods `.firstDefined()` and `.lastDefined()` to get first or last not `undefined` value. \*/ eve = function (name, scope) { - name = String(name); var e = events, oldstop = stop, args = Array.prototype.slice.call(arguments, 2), @@ -155,7 +159,7 @@ = (array) array of event handlers \*/ eve.listeners = function (name) { - var names = name.split(separator), + var names = isArray(name) ? name : name.split(separator), e = events, item, items, @@ -185,7 +189,25 @@ } return out; }; - + /*\ + * eve.separator + [ method ] + + * If for some reasons you don’t like default separators (`.` or `/`) you can specify yours + * here. Be aware that if you pass a string longer than one character it will be treated as + * a list of characters. + + - separator (string) new separator. Empty string resets to default: `.` or `/`. + \*/ + eve.separator = function (sep) { + if (sep) { + sep = Str(sep).replace(/(?=[\.\^\]\[\-])/g, "\\"); + sep = "[" + sep + "]"; + separator = new RegExp(sep); + } else { + separator = /[\.\/]/; + } + }; /*\ * eve.on [ method ] @@ -195,11 +217,12 @@ | eve("mouse.under.floor"); // triggers f * Use @eve to trigger the listener. ** - > Arguments - ** - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards - f (function) event handler function ** + - name (array) if you don’t want to use separators, you can use array of strings + - f (function) event handler function + ** = (function) returned function accepts a single numeric parameter that represents z-index of the handler. It is an optional feature and only used when you need to ensure that some subset of handlers will be invoked in a given order, despite of the order of assignment. > Example: | eve.on("mouse", eatIt)(2); @@ -211,14 +234,13 @@ * Note: I assume most of the time you don’t need to worry about z-index, but it’s nice to have this feature “just in case”. \*/ eve.on = function (name, f) { - name = String(name); if (typeof f != "function") { return function () {}; } - var names = name.split(comaseparator); + var names = isArray(name) ? (isArray(name[0]) ? name : [name]) : Str(name).split(comaseparator); for (var i = 0, ii = names.length; i < ii; i++) { (function (name) { - var names = name.split(separator), + var names = isArray(name) ? name : Str(name).split(separator), e = events, exist; for (var i = 0, ii = names.length; i < ii; i++) { @@ -285,10 +307,11 @@ = (boolean) `true`, if current event’s name contains `subname` \*/ eve.nt = function (subname) { + var cur = isArray(current_event) ? current_event.join(".") : current_event; if (subname) { - return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(current_event); + return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(cur); } - return current_event; + return cur; }; /*\ * eve.nts @@ -300,7 +323,7 @@ = (array) names of the event \*/ eve.nts = function () { - return current_event.split(separator); + return isArray(current_event) ? current_event : current_event.split(separator); }; /*\ * eve.off @@ -325,19 +348,20 @@ eve._events = events = {n: {}}; return; } - var names = name.split(comaseparator); + var names = isArray(name) ? (isArray(name[0]) ? name : [name]) : Str(name).split(comaseparator); if (names.length > 1) { for (var i = 0, ii = names.length; i < ii; i++) { eve.off(names[i], f); } return; } - names = name.split(separator); + names = isArray(name) ? name : Str(name).split(separator); var e, key, splice, i, ii, j, jj, - cur = [events]; + cur = [events], + inodes = []; for (i = 0, ii = names.length; i < ii; i++) { for (j = 0; j < cur.length; j += splice.length - 2) { splice = [j, 1]; @@ -345,10 +369,18 @@ if (names[i] != wildcard) { if (e[names[i]]) { splice.push(e[names[i]]); + inodes.unshift({ + n: e, + name: names[i] + }); } } else { for (key in e) if (e[has](key)) { splice.push(e[key]); + inodes.unshift({ + n: e, + name: key + }); } } cur.splice.apply(cur, splice); @@ -382,6 +414,20 @@ e = e.n; } } + // prune inner nodes in path + prune: for (i = 0, ii = inodes.length; i < ii; i++) { + e = inodes[i]; + for (key in e.n[e.name].f) { + // not empty (has listeners) + continue prune; + } + for (key in e.n[e.name].n) { + // not empty (has children) + continue prune; + } + // is empty + delete e.n[e.name]; + } }; /*\ * eve.once @@ -402,7 +448,7 @@ \*/ eve.once = function (name, f) { var f2 = function () { - eve.unbind(name, f2); + eve.off(name, f2); return f.apply(this, arguments); }; return eve.on(name, f2); @@ -427,9 +473,9 @@ define(["eve"], function (eve) { return factory(glob, eve); }); - } else if (typeof exports != 'undefined') { + } else if (typeof exports != "undefined") { // Next for Node.js or CommonJS - var eve = require('eve'); + var eve = require("eve"); module.exports = factory(glob, eve); } else { // Browser globals (glob is window) @@ -438,14 +484,14 @@ } }(window || this, function (window, eve) { -// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// Copyright (c) 2017 Adobe Systems Incorporated. All rights reserved. +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -459,8 +505,10 @@ var mina = (function (eve) { window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { - setTimeout(callback, 16); + setTimeout(callback, 16, new Date().getTime()); + return true; }, + requestID, isArray = Array.isArray || function (a) { return a instanceof Array || Object.prototype.toString.call(a) == "[object Array]"; @@ -534,6 +582,7 @@ var mina = (function (eve) { a.b = a.get() - a.pdif; delete a.pdif; animations[a.id] = a; + frame(); }, update = function () { var a = this, @@ -549,7 +598,16 @@ var mina = (function (eve) { } a.set(res); }, - frame = function () { + frame = function (timeStamp) { + // Manual invokation? + if (!timeStamp) { + // Frame loop stopped? + if (!requestID) { + // Start frame loop... + requestID = requestAnimFrame(frame); + } + return; + } var len = 0; for (var i in animations) if (animations.hasOwnProperty(i)) { var a = animations[i], @@ -569,7 +627,7 @@ var mina = (function (eve) { } a.update(); } - len && requestAnimFrame(frame); + requestID = len ? requestAnimFrame(frame) : false; }, /*\ * mina @@ -580,7 +638,7 @@ var mina = (function (eve) { - a (number) start _slave_ number - A (number) end _slave_ number - b (number) start _master_ number (start time in general case) - - B (number) end _master_ number (end time in gereal case) + - B (number) end _master_ number (end time in general case) - get (function) getter of _master_ number (see @mina.time) - set (function) setter of _slave_ number - easing (function) #optional easing function, default is @mina.linear @@ -633,7 +691,7 @@ var mina = (function (eve) { break; } } - len == 1 && requestAnimFrame(frame); + len == 1 && frame(); return anim; }; /*\ @@ -773,18 +831,18 @@ var mina = (function (eve) { var s = 7.5625, p = 2.75, l; - if (n < (1 / p)) { + if (n < 1 / p) { l = s * n * n; } else { - if (n < (2 / p)) { - n -= (1.5 / p); + if (n < 2 / p) { + n -= 1.5 / p; l = s * n * n + .75; } else { - if (n < (2.5 / p)) { - n -= (2.25 / p); + if (n < 2.5 / p) { + n -= 2.25 / p; l = s * n * n + .9375; } else { - n -= (2.625 / p); + n -= 2.625 / p; l = s * n * n + .984375; } } @@ -794,14 +852,15 @@ var mina = (function (eve) { window.mina = mina; return mina; })(typeof eve == "undefined" ? function () {} : eve); -// Copyright (c) 2013 - 2015 Adobe Systems Incorporated. All rights reserved. -// + +// Copyright (c) 2013 - 2017 Adobe Systems Incorporated. All rights reserved. +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -809,7 +868,7 @@ var mina = (function (eve) { // limitations under the License. var Snap = (function(root) { -Snap.version = "0.4.0"; +Snap.version = "0.5.0"; /*\ * Snap [ method ] @@ -872,14 +931,13 @@ var has = "hasOwnProperty", ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i, colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i, bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/, - reURLValue = /^url\(#?([^)]+)\)$/, separator = Snap._.separator = /[,\s]+/, whitespace = /[\s]/g, commaSpaces = /[\s]*,[\s]*/, hsrg = {hs: 1, rg: 1}, pathCommand = /([a-z])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/ig, tCommand = /([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/ig, - pathValues = /(-?\d*\.?\d*(?:e[\-+]?\\d+)?)[\s]*,?[\s]*/ig, + pathValues = /(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\s]*,?[\s]*/ig, idgen = 0, idprefix = "S" + (+new Date).toString(36), ID = function (el) { @@ -888,6 +946,14 @@ var has = "hasOwnProperty", xlink = "http://www.w3.org/1999/xlink", xmlns = "http://www.w3.org/2000/svg", hub = {}, + /*\ + * Snap.url + [ method ] + ** + * Wraps path into `"url('')"`. + - value (string) path + = (string) wrapped path + \*/ URL = Snap.url = function (url) { return "url('#" + url + "')"; }; @@ -967,9 +1033,9 @@ function is(o, type) { (o instanceof Array || Array.isArray && Array.isArray(o))) { return true; } - return (type == "null" && o === null) || - (type == typeof o && o !== null) || - (type == "object" && o === Object(o)) || + return type == "null" && o === null || + type == typeof o && o !== null || + type == "object" && o === Object(o) || objectToString.call(o).slice(8, -1).toLowerCase() == type; } /*\ @@ -1175,7 +1241,6 @@ Snap.atan2 = function (num) { [ method ] ** * Returns an angle between two or three points - > Parameters - x1 (number) x coord of first point - y1 (number) y coord of first point - x2 (number) x coord of second point @@ -1190,7 +1255,6 @@ Snap.angle = angle; [ method ] ** * Returns distance between two points - > Parameters - x1 (number) x coord of first point - y1 (number) y coord of first point - x2 (number) x coord of second point @@ -1205,7 +1269,6 @@ Snap.len = function (x1, y1, x2, y2) { [ method ] ** * Returns squared distance between two points - > Parameters - x1 (number) x coord of first point - y1 (number) y coord of first point - x2 (number) x coord of second point @@ -1220,7 +1283,6 @@ Snap.len2 = function (x1, y1, x2, y2) { [ method ] ** * Returns closest point to a given one on a given path. - > Parameters - path (Element) path element - x (number) x coord of a point - y (number) y coord of a point @@ -1249,7 +1311,9 @@ Snap.closestPoint = function (path, x, y) { // linear scan for coarse approximation for (var scan, scanLength = 0, scanDistance; scanLength <= pathLength; scanLength += precision) { if ((scanDistance = distance2(scan = pathNode.getPointAtLength(scanLength))) < bestDistance) { - best = scan, bestLength = scanLength, bestDistance = scanDistance; + best = scan; + bestLength = scanLength; + bestDistance = scanDistance; } } @@ -1263,9 +1327,13 @@ Snap.closestPoint = function (path, x, y) { beforeDistance, afterDistance; if ((beforeLength = bestLength - precision) >= 0 && (beforeDistance = distance2(before = pathNode.getPointAtLength(beforeLength))) < bestDistance) { - best = before, bestLength = beforeLength, bestDistance = beforeDistance; + best = before; + bestLength = beforeLength; + bestDistance = beforeDistance; } else if ((afterLength = bestLength + precision) <= pathLength && (afterDistance = distance2(after = pathNode.getPointAtLength(afterLength))) < bestDistance) { - best = after, bestLength = afterLength, bestDistance = afterDistance; + best = after; + bestLength = afterLength; + bestDistance = afterDistance; } else { precision *= .5; } @@ -1424,7 +1492,7 @@ Snap.getRGB = cacher(function (colour) { blue = mmin(math.round(blue), 255); opacity = mmin(mmax(opacity, 0), 1); rgb = {r: red, g: green, b: blue, toString: rgbtoString}; - rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1); + rgb.hex = "#" + (16777216 | blue | green << 8 | red << 16).toString(16).slice(1); rgb.opacity = is(opacity, "finite") ? opacity : 1; return rgb; } @@ -1471,7 +1539,7 @@ Snap.rgb = cacher(function (r, g, b, o) { var round = math.round; return "rgba(" + [round(r), round(g), round(b), +o.toFixed(2)] + ")"; } - return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1); + return "#" + (16777216 | b | g << 8 | r << 16).toString(16).slice(1); }); var toHex = function (color) { var i = glob.doc.getElementsByTagName("head")[0] || glob.doc.getElementsByTagName("svg")[0], @@ -1515,7 +1583,7 @@ prepareRGB = function (r, g, b) { g /= 255; b /= 255; } - + return [r, g, b]; }, packageRGB = function (r, g, b, o) { @@ -1613,7 +1681,7 @@ Snap.hsb2rgb = function (h, s, v, o) { } h *= 360; var R, G, B, X, C; - h = (h % 360) / 60; + h = h % 360 / 60; C = v * s; X = C * (1 - abs(h % 2 - 1)); R = G = B = v - C; @@ -1653,7 +1721,7 @@ Snap.hsl2rgb = function (h, s, l, o) { } h *= 360; var R, G, B, X, C; - h = (h % 360) / 60; + h = h % 360 / 60; C = 2 * s * (l < .5 ? l : 1 - l); X = C * (1 - abs(h % 2 - 1)); R = G = B = l - C / 2; @@ -1688,12 +1756,11 @@ Snap.rgb2hsb = function (r, g, b) { var H, S, V, C; V = mmax(r, g, b); C = V - mmin(r, g, b); - H = (C == 0 ? null : - V == r ? (g - b) / C : - V == g ? (b - r) / C + 2 : - (r - g) / C + 4 - ); - H = ((H + 360) % 6) * 60 / 360; + H = C == 0 ? null : + V == r ? (g - b) / C : + V == g ? (b - r) / C + 2 : + (r - g) / C + 4; + H = (H + 360) % 6 * 60 / 360; S = C == 0 ? 0 : C / V; return {h: H, s: S, b: V, toString: hsbtoString}; }; @@ -1722,15 +1789,15 @@ Snap.rgb2hsl = function (r, g, b) { M = mmax(r, g, b); m = mmin(r, g, b); C = M - m; - H = (C == 0 ? null : - M == r ? (g - b) / C : - M == g ? (b - r) / C + 2 : - (r - g) / C + 4); - H = ((H + 360) % 6) * 60 / 360; + H = C == 0 ? null : + M == r ? (g - b) / C : + M == g ? (b - r) / C + 2 : + (r - g) / C + 4; + H = (H + 360) % 6 * 60 / 360; L = (M + m) / 2; - S = (C == 0 ? 0 : + S = C == 0 ? 0 : L < .5 ? C / (2 * L) : - C / (2 - 2 * L)); + C / (2 - 2 * L); return {h: H, s: S, l: L, toString: hsltoString}; }; @@ -1753,7 +1820,7 @@ Snap.parsePathString = function (pathString) { if (pth.arr) { return Snap.path.clone(pth.arr); } - + var paramCounts = {a: 7, c: 6, o: 2, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, u: 3, z: 0}, data = []; if (is(pathString, "array") && is(pathString[0], "array")) { // rough assumption @@ -1942,8 +2009,8 @@ var contains = glob.doc.contains || glob.doc.compareDocumentPosition ? return false; }; function getSomeDefs(el) { - var p = (el.node.ownerSVGElement && wrap(el.node.ownerSVGElement)) || - (el.node.parentNode && wrap(el.node.parentNode)) || + var p = el.node.ownerSVGElement && wrap(el.node.ownerSVGElement) || + el.node.parentNode && wrap(el.node.parentNode) || Snap.select("svg") || Snap(0, 0), pdefs = p.select("defs"), @@ -2288,7 +2355,7 @@ function Paper(w, h) { desc, defs, proto = Paper.prototype; - if (w && w.tagName == "svg") { + if (w && w.tagName && w.tagName.toLowerCase() == "svg") { if (w.snap in hub) { return hub[w.snap]; } @@ -2540,7 +2607,7 @@ Snap.ajax = function (url, postData, callback, scope){ } postData = pd.join("&"); } - req.open((postData ? "POST" : "GET"), url, true); + req.open(postData ? "POST" : "GET", url, true); if (postData) { req.setRequestHeader("X-Requested-With", "XMLHttpRequest"); req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); @@ -2693,6 +2760,9 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { o } \*/ elproto.getBBox = function (isWithoutTransform) { + if (this.type == "tspan") { + return Snap._.box(this.node.getClientRects().item(0)); + } if (!Snap.Matrix || !Snap.path) { return this.node.getBBox(); } @@ -3133,7 +3203,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { if (val) { uses[val] = (uses[val] || []).concat(function (id) { var attr = {}; - attr[name] = URL(id); + attr[name] = Snap.url(id); $(it.node, attr); }); } @@ -3297,7 +3367,165 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { p.node.appendChild(this.node); return p; }; - // animation + var eldata = {}; + /*\ + * Element.data + [ method ] + ** + * Adds or retrieves given value associated with given key. (Don’t confuse + * with `data-` attributes) + * + * See also @Element.removeData + - key (string) key to store data + - value (any) #optional value to store + = (object) @Element + * or, if value is not specified: + = (any) value + > Usage + | for (var i = 0, i < 5, i++) { + | paper.circle(10 + 15 * i, 10, 10) + | .attr({fill: "#000"}) + | .data("i", i) + | .click(function () { + | alert(this.data("i")); + | }); + | } + \*/ + elproto.data = function (key, value) { + var data = eldata[this.id] = eldata[this.id] || {}; + if (arguments.length == 0){ + eve("snap.data.get." + this.id, this, data, null); + return data; + } + if (arguments.length == 1) { + if (Snap.is(key, "object")) { + for (var i in key) if (key[has](i)) { + this.data(i, key[i]); + } + return this; + } + eve("snap.data.get." + this.id, this, data[key], key); + return data[key]; + } + data[key] = value; + eve("snap.data.set." + this.id, this, value, key); + return this; + }; + /*\ + * Element.removeData + [ method ] + ** + * Removes value associated with an element by given key. + * If key is not provided, removes all the data of the element. + - key (string) #optional key + = (object) @Element + \*/ + elproto.removeData = function (key) { + if (key == null) { + eldata[this.id] = {}; + } else { + eldata[this.id] && delete eldata[this.id][key]; + } + return this; + }; + /*\ + * Element.outerSVG + [ method ] + ** + * Returns SVG code for the element, equivalent to HTML's `outerHTML`. + * + * See also @Element.innerSVG + = (string) SVG code for the element + \*/ + /*\ + * Element.toString + [ method ] + ** + * See @Element.outerSVG + \*/ + elproto.outerSVG = elproto.toString = toString(1); + /*\ + * Element.innerSVG + [ method ] + ** + * Returns SVG code for the element's contents, equivalent to HTML's `innerHTML` + = (string) SVG code for the element + \*/ + elproto.innerSVG = toString(); + function toString(type) { + return function () { + var res = type ? "<" + this.type : "", + attr = this.node.attributes, + chld = this.node.childNodes; + if (type) { + for (var i = 0, ii = attr.length; i < ii; i++) { + res += " " + attr[i].name + '="' + + attr[i].value.replace(/"/g, '\\"') + '"'; + } + } + if (chld.length) { + type && (res += ">"); + for (i = 0, ii = chld.length; i < ii; i++) { + if (chld[i].nodeType == 3) { + res += chld[i].nodeValue; + } else if (chld[i].nodeType == 1) { + res += wrap(chld[i]).toString(); + } + } + type && (res += ""); + } else { + type && (res += "/>"); + } + return res; + }; + } + elproto.toDataURL = function () { + if (window && window.btoa) { + var bb = this.getBBox(), + svg = Snap.format('{contents}', { + x: +bb.x.toFixed(3), + y: +bb.y.toFixed(3), + width: +bb.width.toFixed(3), + height: +bb.height.toFixed(3), + contents: this.outerSVG() + }); + return "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svg))); + } + }; + /*\ + * Fragment.select + [ method ] + ** + * See @Element.select + \*/ + Fragment.prototype.select = elproto.select; + /*\ + * Fragment.selectAll + [ method ] + ** + * See @Element.selectAll + \*/ + Fragment.prototype.selectAll = elproto.selectAll; +}); + +// Copyright (c) 2016 Adobe Systems Incorporated. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { + var elproto = Element.prototype, + is = Snap.is, + Str = String, + has = "hasOwnProperty"; function slice(from, to, f) { return function (arr) { var res = arr.slice(from, to); @@ -3476,163 +3704,26 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { anim._callback = callback; eve("snap.animcreated." + el.id, anim); eve.once("mina.finish." + anim.id, function () { + eve.off("mina.*." + anim.id); delete el.anims[anim.id]; callback && callback.call(el); }); eve.once("mina.stop." + anim.id, function () { + eve.off("mina.*." + anim.id); delete el.anims[anim.id]; }); return el; }; - var eldata = {}; - /*\ - * Element.data - [ method ] - ** - * Adds or retrieves given value associated with given key. (Don’t confuse - * with `data-` attributes) - * - * See also @Element.removeData - - key (string) key to store data - - value (any) #optional value to store - = (object) @Element - * or, if value is not specified: - = (any) value - > Usage - | for (var i = 0, i < 5, i++) { - | paper.circle(10 + 15 * i, 10, 10) - | .attr({fill: "#000"}) - | .data("i", i) - | .click(function () { - | alert(this.data("i")); - | }); - | } - \*/ - elproto.data = function (key, value) { - var data = eldata[this.id] = eldata[this.id] || {}; - if (arguments.length == 0){ - eve("snap.data.get." + this.id, this, data, null); - return data; - } - if (arguments.length == 1) { - if (Snap.is(key, "object")) { - for (var i in key) if (key[has](i)) { - this.data(i, key[i]); - } - return this; - } - eve("snap.data.get." + this.id, this, data[key], key); - return data[key]; - } - data[key] = value; - eve("snap.data.set." + this.id, this, value, key); - return this; - }; - /*\ - * Element.removeData - [ method ] - ** - * Removes value associated with an element by given key. - * If key is not provided, removes all the data of the element. - - key (string) #optional key - = (object) @Element - \*/ - elproto.removeData = function (key) { - if (key == null) { - eldata[this.id] = {}; - } else { - eldata[this.id] && delete eldata[this.id][key]; - } - return this; - }; - /*\ - * Element.outerSVG - [ method ] - ** - * Returns SVG code for the element, equivalent to HTML's `outerHTML`. - * - * See also @Element.innerSVG - = (string) SVG code for the element - \*/ - /*\ - * Element.toString - [ method ] - ** - * See @Element.outerSVG - \*/ - elproto.outerSVG = elproto.toString = toString(1); - /*\ - * Element.innerSVG - [ method ] - ** - * Returns SVG code for the element's contents, equivalent to HTML's `innerHTML` - = (string) SVG code for the element - \*/ - elproto.innerSVG = toString(); - function toString(type) { - return function () { - var res = type ? "<" + this.type : "", - attr = this.node.attributes, - chld = this.node.childNodes; - if (type) { - for (var i = 0, ii = attr.length; i < ii; i++) { - res += " " + attr[i].name + '="' + - attr[i].value.replace(/"/g, '\\"') + '"'; - } - } - if (chld.length) { - type && (res += ">"); - for (i = 0, ii = chld.length; i < ii; i++) { - if (chld[i].nodeType == 3) { - res += chld[i].nodeValue; - } else if (chld[i].nodeType == 1) { - res += wrap(chld[i]).toString(); - } - } - type && (res += ""); - } else { - type && (res += "/>"); - } - return res; - }; - } - elproto.toDataURL = function () { - if (window && window.btoa) { - var bb = this.getBBox(), - svg = Snap.format('{contents}', { - x: +bb.x.toFixed(3), - y: +bb.y.toFixed(3), - width: +bb.width.toFixed(3), - height: +bb.height.toFixed(3), - contents: this.outerSVG() - }); - return "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svg))); - } - }; - /*\ - * Fragment.select - [ method ] - ** - * See @Element.select - \*/ - Fragment.prototype.select = elproto.select; - /*\ - * Fragment.selectAll - [ method ] - ** - * See @Element.selectAll - \*/ - Fragment.prototype.selectAll = elproto.selectAll; }); // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -3685,30 +3776,48 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { - matrix (object) @Matrix \*/ matrixproto.add = function (a, b, c, d, e, f) { - var out = [[], [], []], - m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]], - matrix = [[a, c, e], [b, d, f], [0, 0, 1]], - x, y, z, res; - if (a && a instanceof Matrix) { - matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]]; + return this.add(a.a, a.b, a.c, a.d, a.e, a.f); } + var aNew = a * this.a + b * this.c, + bNew = a * this.b + b * this.d; + this.e += e * this.a + f * this.c; + this.f += e * this.b + f * this.d; + this.c = c * this.a + d * this.c; + this.d = c * this.b + d * this.d; - for (x = 0; x < 3; x++) { - for (y = 0; y < 3; y++) { - res = 0; - for (z = 0; z < 3; z++) { - res += m[x][z] * matrix[z][y]; - } - out[x][y] = res; - } + this.a = aNew; + this.b = bNew; + return this; + }; + /*\ + * Matrix.multLeft + [ method ] + ** + * Multiplies a passed affine transform to the left: M * this. + - a (number) + - b (number) + - c (number) + - d (number) + - e (number) + - f (number) + * or + - matrix (object) @Matrix + \*/ + Matrix.prototype.multLeft = function (a, b, c, d, e, f) { + if (a && a instanceof Matrix) { + return this.multLeft(a.a, a.b, a.c, a.d, a.e, a.f); } - this.a = out[0][0]; - this.b = out[1][0]; - this.c = out[0][1]; - this.d = out[1][1]; - this.e = out[0][2]; - this.f = out[1][2]; + var aNew = a * this.a + c * this.b, + cNew = a * this.c + c * this.d, + eNew = a * this.e + c * this.f + e; + this.b = b * this.a + d * this.b; + this.d = b * this.c + d * this.d; + this.f = b * this.e + d * this.f + f; + + this.a = aNew; + this.c = cNew; + this.e = eNew; return this; }; /*\ @@ -3742,7 +3851,9 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { - y (number) vertical offset distance \*/ matrixproto.translate = function (x, y) { - return this.add(1, 0, 0, 1, x, y); + this.e += x * this.a + y * this.c; + this.f += x * this.b + y * this.d; + return this; }; /*\ * Matrix.scale @@ -3757,9 +3868,12 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { \*/ matrixproto.scale = function (x, y, cx, cy) { y == null && (y = x); - (cx || cy) && this.add(1, 0, 0, 1, cx, cy); - this.add(x, 0, 0, y, 0, 0); - (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy); + (cx || cy) && this.translate(cx, cy); + this.a *= x; + this.b *= x; + this.c *= y; + this.d *= y; + (cx || cy) && this.translate(-cx, -cy); return this; }; /*\ @@ -3780,6 +3894,43 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { this.add(cos, sin, -sin, cos, x, y); return this.add(1, 0, 0, 1, -x, -y); }; + /*\ + * Matrix.skewX + [ method ] + ** + * Skews the matrix along the x-axis + - x (number) Angle to skew along the x-axis (in degrees). + \*/ + matrixproto.skewX = function (x) { + return this.skew(x, 0); + }; + /*\ + * Matrix.skewY + [ method ] + ** + * Skews the matrix along the y-axis + - y (number) Angle to skew along the y-axis (in degrees). + \*/ + matrixproto.skewY = function (y) { + return this.skew(0, y); + }; + /*\ + * Matrix.skew + [ method ] + ** + * Skews the matrix + - y (number) Angle to skew along the y-axis (in degrees). + - x (number) Angle to skew along the x-axis (in degrees). + \*/ + matrixproto.skew = function (x, y) { + x = x || 0; + y = y || 0; + x = Snap.rad(x); + y = Snap.rad(y); + var c = math.tan(x).toFixed(9); + var b = math.tan(y).toFixed(9); + return this.add(1, b, c, 1, 0, 0); + }; /*\ * Matrix.x [ method ] @@ -3852,7 +4003,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { out.dy = this.f; // scale and shear - var row = [[this.a, this.c], [this.b, this.d]]; + var row = [[this.a, this.b], [this.c, this.d]]; out.scalex = math.sqrt(norm(row[0])); normalize(row[0]); @@ -3868,7 +4019,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { } // rotation - var sin = -row[0][1], + var sin = row[0][1], cos = row[1][1]; if (cos < 0) { out.rotate = Snap.deg(math.acos(cos)); @@ -3897,9 +4048,9 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { s.scalex = +s.scalex.toFixed(4); s.scaley = +s.scaley.toFixed(4); s.rotate = +s.rotate.toFixed(4); - return (s.dx || s.dy ? "t" + [+s.dx.toFixed(4), +s.dy.toFixed(4)] : E) + - (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) + - (s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E); + return (s.dx || s.dy ? "t" + [+s.dx.toFixed(4), +s.dy.toFixed(4)] : E) + + (s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E) + + (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E); } else { return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)]; } @@ -3934,14 +4085,15 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { return new Matrix(a, b, c, d, e, f); }; }); + // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -3953,12 +4105,23 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { wrap = Snap._.wrap, is = Snap.is, getSomeDefs = Snap._.getSomeDefs, - reURLValue = /^url\(#?([^)]+)\)$/, + reURLValue = /^url\((['"]?)([^)]+)\1\)$/, $ = Snap._.$, URL = Snap.url, Str = String, separator = Snap._.separator, E = ""; + /*\ + * Snap.deurl + [ method ] + ** + * Unwraps path from `"url()"`. + - value (string) url path + = (string) unwrapped path + \*/ + Snap.deurl = function (value) { + return String(value).match(reURLValue)[2]; + } // Attributes event handlers eve.on("snap.util.attr.mask", function (value) { if (value instanceof Element || value instanceof Fragment) { @@ -3989,9 +4152,20 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { }(function (value) { if (value instanceof Element || value instanceof Fragment) { eve.stop(); - if (value.type == "clipPath") { - var clip = value; - } else { + var clip, + node = value.node; + while (node) { + if (node.nodeName === "clipPath") { + clip = new Element(node); + break; + } + if (node.nodeName === "svg") { + clip = undefined; + break; + } + node = node.parentNode; + } + if (!clip) { clip = make("clipPath", getSomeDefs(this)); clip.node.appendChild(value.node); !clip.node.id && $(clip.node, { @@ -4079,6 +4253,23 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { } return out; }); + var len = stops.length, + start = 0, + j = 0; + function seed(i, end) { + var step = (end - start) / (i - j); + for (var k = j; k < i; k++) { + stops[k].offset = +(+start + step * (k - j)).toFixed(2); + } + j = i; + start = end; + } + len--; + for (var i = 0; i < len; i++) if ("offset" in stops[i]) { + seed(i, stops[i].offset); + } + stops[len].offset = stops[len].offset || 100; + seed(len, stops[len].offset); return { type: type, params: params, @@ -4311,6 +4502,22 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { eve.on("snap.util.getattr.#text", function () { return this.node.textContent; })(-1); + eve.on("snap.util.getattr.fill", function (internal) { + if (internal) { + return; + } + eve.stop(); + var value = eve("snap.util.getattr.fill", this, true).firstDefined(); + return Snap(Snap.deurl(value)) || value; + })(-1); + eve.on("snap.util.getattr.stroke", function (internal) { + if (internal) { + return; + } + eve.stop(); + var value = eve("snap.util.getattr.stroke", this, true).firstDefined(); + return Snap(Snap.deurl(value)) || value; + })(-1); eve.on("snap.util.getattr.viewBox", function () { eve.stop(); var vb = $(this.node, "viewBox"); @@ -4386,7 +4593,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { if (classes.length) { j = 0; - while ((clazz = classes[j++])) { + while (clazz = classes[j++]) { pos = curClasses.indexOf(clazz); if (!~pos) { curClasses.push(clazz); @@ -4420,7 +4627,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { finalValue; if (curClasses.length) { j = 0; - while ((clazz = classes[j++])) { + while (clazz = classes[j++]) { pos = curClasses.indexOf(clazz); if (~pos) { curClasses.splice(pos, 1); @@ -4477,7 +4684,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { clazz, finalValue; j = 0; - while ((clazz = classes[j++])) { + while (clazz = classes[j++]) { pos = curClasses.indexOf(clazz); if (~pos) { curClasses.splice(pos, 1); @@ -4495,13 +4702,13 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { }); // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -4583,14 +4790,15 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { } })(-10); }); + // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -5097,9 +5305,27 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { (function () { var $ = Snap._.$; // gradients' helpers + /*\ + * Element.stops + [ method ] + ** + * Only for gradients! + * Returns array of gradient stops elements. + = (array) the stops array. + \*/ function Gstops() { return this.selectAll("stop"); } + /*\ + * Element.addStop + [ method ] + ** + * Only for gradients! + * Adds another stop to the gradient. + - color (string) stops color + - offset (number) stops offset 0..100 + = (object) gradient element + \*/ function GaddStop(color, offset) { var stop = $("stop"), attr = { @@ -5111,7 +5337,19 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { attr["stop-opacity"] = color.opacity; } $(stop, attr); - this.node.appendChild(stop); + var stops = this.stops(), + inserted; + for (var i = 0; i < stops.length; i++) { + var stopOffset = parseFloat(stops[i].attr("offset")); + if (stopOffset > offset) { + this.node.insertBefore(stop, stops[i].node); + inserted = true; + break; + } + } + if (!inserted) { + this.node.appendChild(stop); + } return this; } function GgetBBox() { @@ -5128,6 +5366,44 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { return Snap._.box(cx - r, cy - r, r * 2, r * 2); } } + /*\ + * Element.setStops + [ method ] + ** + * Only for gradients! + * Updates stops of the gradient based on passed gradient descriptor. See @Ppaer.gradient + - str (string) gradient descriptor part after `()`. + = (object) gradient element + | var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff"); + | g.setStops("#fff-#000-#f00-#fc0"); + \*/ + function GsetStops(str) { + var grad = str, + stops = this.stops(); + if (typeof str == "string") { + grad = eve("snap.util.grad.parse", null, "l(0,0,0,1)" + str).firstDefined().stops; + } + if (!Snap.is(grad, "array")) { + return; + } + for (var i = 0; i < stops.length; i++) { + if (grad[i]) { + var color = Snap.color(grad[i].color), + attr = {"offset": grad[i].offset + "%"}; + attr["stop-color"] = color.hex; + if (color.opacity < 1) { + attr["stop-opacity"] = color.opacity; + } + stops[i].attr(attr); + } else { + stops[i].remove(); + } + } + for (i = stops.length; i < grad.length; i++) { + this.addStop(grad[i].color, grad[i].offset); + } + return this; + } function gradient(defs, str) { var grad = eve("snap.util.grad.parse", null, str).firstDefined(), el; @@ -5146,24 +5422,8 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { }); } var stops = grad.stops, - len = stops.length, - start = 0, - j = 0; - function seed(i, end) { - var step = (end - start) / (i - j); - for (var k = j; k < i; k++) { - stops[k].offset = +(+start + step * (k - j)).toFixed(2); - } - j = i; - start = end; - } - len--; - for (var i = 0; i < len; i++) if ("offset" in stops[i]) { - seed(i, stops[i].offset); - } - stops[len].offset = stops[len].offset || 100; - seed(len, stops[len].offset); - for (i = 0; i <= len; i++) { + len = stops.length; + for (var i = 0; i < len; i++) { var stop = stops[i]; el.addStop(stop.color, stop.offset); } @@ -5174,6 +5434,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { el.stops = Gstops; el.addStop = GaddStop; el.getBBox = GgetBBox; + el.setStops = GsetStops; if (x1 != null) { $(el.node, { x1: x1, @@ -5305,13 +5566,13 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { }); // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -5471,7 +5732,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { ay = t1 * p1y + t * c1y, cx = t1 * c2x + t * p2x, cy = t1 * c2y + t * p2y, - alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI); + alpha = 90 - math.atan2(mx - nx, my - ny) * 180 / PI; // (mx > nx || my < ny) && (alpha += 180); return { x: x, @@ -5726,7 +5987,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { return box(); } path = path2curve(path); - var x = 0, + var x = 0, y = 0, X = [], Y = [], @@ -5757,7 +6018,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { function rectPath(x, y, w, h, r) { if (r) { return [ - ["M", +x + (+r), y], + ["M", +x + +r, y], ["l", w - r * 2, 0], ["a", r, r, 0, 0, 1, r, r], ["l", 0, h - r * 2], @@ -5881,7 +6142,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { my = pa[2]; default: for (var j = 1, jj = pa.length; j < jj; j++) { - r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3); + r[j] = +(pa[j] - (j % 2 ? x : y)).toFixed(3); } } } else { @@ -5992,7 +6253,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { my = +pa[2] + y; default: for (j = 1, jj = pa.length; j < jj; j++) { - r[j] = +pa[j] + ((j % 2) ? x : y); + r[j] = +pa[j] + (j % 2 ? x : y); } } } else if (pa0 == "R") { @@ -6067,6 +6328,9 @@ Snap.plugin(function (Snap, Element, Paper, glob) { Y = x * math.sin(rad) + y * math.cos(rad); return {x: X, y: Y}; }); + if (!rx || !ry) { + return [x1, y1, x2, y2, x2, y2]; + } if (!recursive) { xy = rotate(x1, y1, -rad); x1 = xy.x; @@ -6078,7 +6342,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { sin = math.sin(PI / 180 * angle), x = (x1 - x2) / 2, y = (y1 - y2) / 2; - var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); + var h = x * x / (rx * rx) + y * y / (ry * ry); if (h > 1) { h = math.sqrt(h); rx = h * rx; @@ -6151,7 +6415,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y }; } - + // Returns bounding box of cubic bezier curve. // Source: http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html // Original version: NISHIO Hirokazu @@ -6201,8 +6465,8 @@ Snap.plugin(function (Snap, Element, Paper, glob) { while (j--) { t = tvalues[j]; mt = 1 - t; - bounds[0][j] = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3); - bounds[1][j] = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3); + bounds[0][j] = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3; + bounds[1][j] = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3; } bounds[0][jlen] = x0; @@ -6760,13 +7024,13 @@ Snap.plugin(function (Snap, Element, Paper, glob) { }); // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -6903,6 +7167,14 @@ Snap.plugin(function (Snap, Element, Paper, glob) { } }); }; + /*\ + * Set.remove + [ method ] + ** + * Removes all children of the set. + * + = (object) Set object + \*/ setproto.remove = function () { while (this.length) { this.pop().remove(); @@ -6941,6 +7213,13 @@ Snap.plugin(function (Snap, Element, Paper, glob) { } return this; }; + /*\ + * Set.attr + [ method ] + ** + * Equivalent of @Element.attr. + = (object) Set object + \*/ setproto.attr = function (value) { var unbound = {}; for (var k in value) { @@ -7019,6 +7298,15 @@ Snap.plugin(function (Snap, Element, Paper, glob) { } return false; }; + /*\ + * Set.insertAfter + [ method ] + ** + * Inserts set elements after given element. + ** + - element (object) set will be inserted after this element + = (object) Set object + \*/ setproto.insertAfter = function (el) { var i = this.items.length; while (i--) { @@ -7026,6 +7314,13 @@ Snap.plugin(function (Snap, Element, Paper, glob) { } return this; }; + /*\ + * Set.getBBox + [ method ] + ** + * Union of all bboxes of the set. See @Element.getBBox. + = (object) bounding box descriptor. See @Element.getBBox. + \*/ setproto.getBBox = function () { var x = [], y = [], @@ -7053,6 +7348,14 @@ Snap.plugin(function (Snap, Element, Paper, glob) { cy: y + (y2 - y) / 2 }; }; + /*\ + * Set.insertAfter + [ method ] + ** + * Creates a clone of the set. + ** + = (object) New Set object + \*/ setproto.clone = function (s) { s = new Set; for (var i = 0, ii = this.items.length; i < ii; i++) { @@ -7065,7 +7368,24 @@ Snap.plugin(function (Snap, Element, Paper, glob) { }; setproto.type = "set"; // export + /*\ + * Snap.Set + [ property ] + ** + * Set constructor. + \*/ Snap.Set = Set; + /*\ + * Snap.set + [ method ] + ** + * Creates a set and fills it with list of arguments. + ** + = (object) New Set object + | var r = paper.rect(0, 0, 10, 10), + | s1 = Snap.set(), // empty set + | s2 = Snap.set(r, paper.circle(100, 100, 20)); // prefilled set + \*/ Snap.set = function () { var set = new Set; if (arguments.length) { @@ -7076,13 +7396,13 @@ Snap.plugin(function (Snap, Element, Paper, glob) { }); // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -7090,7 +7410,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { // limitations under the License. Snap.plugin(function (Snap, Element, Paper, glob) { var names = {}, - reUnit = /[a-z]+$/i, + reUnit = /[%a-z]+$/i, Str = String; names.stroke = names.fill = "colour"; function getEmpty(item) { @@ -7113,9 +7433,10 @@ Snap.plugin(function (Snap, Element, Paper, glob) { } } function equaliseTransform(t1, t2, getBBox) { - t2 = Str(t2).replace(/\.{3}|\u2026/g, t1); - t1 = Snap.parseTransformString(t1) || []; - t2 = Snap.parseTransformString(t2) || []; + t1 = t1 || new Snap.Matrix; + t2 = t2 || new Snap.Matrix; + t1 = Snap.parseTransformString(t1.toTransformString()) || []; + t2 = Snap.parseTransformString(t2.toTransformString()) || []; var maxlength = Math.max(t1.length, t2.length), from = [], to = [], @@ -7124,9 +7445,9 @@ Snap.plugin(function (Snap, Element, Paper, glob) { for (; i < maxlength; i++) { tt1 = t1[i] || getEmpty(t2[i]); tt2 = t2[i] || getEmpty(tt1); - if ((tt1[0] != tt2[0]) || - (tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) || - (tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4])) + if (tt1[0] != tt2[0] || + tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3]) || + tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4]) ) { t1 = Snap._.transform2matrix(t1, getBBox()); t2 = Snap._.transform2matrix(t2, getBBox()); @@ -7159,7 +7480,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { return val.join(" "); } function getColour(clr) { - return Snap.rgb(clr[0], clr[1], clr[2]); + return Snap.rgb(clr[0], clr[1], clr[2], clr[3]); } function getPath(path) { var k = 0, i, ii, j, jj, out, a, b = []; @@ -7167,7 +7488,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { out = "["; a = ['"' + path[i][0] + '"']; for (j = 1, jj = path[i].length; j < jj; j++) { - a[j] = "val[" + (k++) + "]"; + a[j] = "val[" + k++ + "]"; } out += a + "]"; b[i] = out; @@ -7184,7 +7505,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { return out; } function isNumeric(obj) { - return isFinite(parseFloat(obj)); + return isFinite(obj); } function arrayEqual(arr1, arr2) { if (!Snap.is(arr1, "array") || !Snap.is(arr2, "array")) { @@ -7198,13 +7519,6 @@ Snap.plugin(function (Snap, Element, Paper, glob) { eve.on("snap.util.equal", function (name, b) { var A, B, a = Str(this.attr(name) || ""), el = this; - if (isNumeric(a) && isNumeric(b)) { - return { - from: parseFloat(a), - to: parseFloat(b), - f: getNumber - }; - } if (names[name] == "colour") { A = Snap.color(a); B = Snap.color(b); @@ -7224,11 +7538,14 @@ Snap.plugin(function (Snap, Element, Paper, glob) { }; } if (name == "transform" || name == "gradientTransform" || name == "patternTransform") { - if (b instanceof Snap.Matrix) { - b = b.toTransformString(); + if (typeof b == "string") { + b = Str(b).replace(/\.{3}|\u2026/g, a); } + a = this.matrix; if (!Snap._.rgTransform.test(b)) { - b = Snap._.svgTransform2string(b); + b = Snap._.transform2matrix(Snap._.svgTransform2string(b), this.getBBox()); + } else { + b = Snap._.transform2matrix(b, this.getBBox()); } return equaliseTransform(a, b, function () { return el.getBBox(1); @@ -7251,6 +7568,13 @@ Snap.plugin(function (Snap, Element, Paper, glob) { f: function (val) { return val; } }; } + if (isNumeric(a) && isNumeric(b)) { + return { + from: parseFloat(a), + to: parseFloat(b), + f: getNumber + }; + } var aUnit = a.match(reUnit), bUnit = Str(b).match(reUnit); if (aUnit && arrayEqual(aUnit, bUnit)) { @@ -7747,13 +8071,13 @@ Snap.plugin(function (Snap, Element, Paper, glob) { }); // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -7799,7 +8123,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { paper.defs.appendChild(filter); return new Element(filter); }; - + eve.on("snap.util.getattr.filter", function () { eve.stop(); var p = $(this.node, "filter"); @@ -7874,22 +8198,23 @@ Snap.plugin(function (Snap, Element, Paper, glob) { - opacity (number) #optional `0..1` opacity of the shadow = (string) filter representation > Usage - | var f = paper.filter(Snap.filter.shadow(0, 2, 3)), + | var f = paper.filter(Snap.filter.shadow(0, 2, .3)), | c = paper.circle(10, 10, 10).attr({ | filter: f | }); \*/ Snap.filter.shadow = function (dx, dy, blur, color, opacity) { - if (typeof blur == "string") { - color = blur; - opacity = color; - blur = 4; + if (opacity == null) { + if (color == null) { + opacity = blur; + blur = 4; + color = "#000"; + } else { + opacity = color; + color = blur; + blur = 4; + } } - if (typeof color != "string") { - opacity = color; - color = "#000"; - } - color = color || "#000"; if (blur == null) { blur = 4; } @@ -8166,5 +8491,135 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { }; }); +// Copyright (c) 2017 Adobe Systems Incorporated. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +Snap.plugin(function (Snap, Element, Paper, glob) { + // Colours are from https://www.materialui.co + var red = "#ffebee#ffcdd2#ef9a9a#e57373#ef5350#f44336#e53935#d32f2f#c62828#b71c1c#ff8a80#ff5252#ff1744#d50000", + pink = "#FCE4EC#F8BBD0#F48FB1#F06292#EC407A#E91E63#D81B60#C2185B#AD1457#880E4F#FF80AB#FF4081#F50057#C51162", + purple = "#F3E5F5#E1BEE7#CE93D8#BA68C8#AB47BC#9C27B0#8E24AA#7B1FA2#6A1B9A#4A148C#EA80FC#E040FB#D500F9#AA00FF", + deeppurple = "#EDE7F6#D1C4E9#B39DDB#9575CD#7E57C2#673AB7#5E35B1#512DA8#4527A0#311B92#B388FF#7C4DFF#651FFF#6200EA", + indigo = "#E8EAF6#C5CAE9#9FA8DA#7986CB#5C6BC0#3F51B5#3949AB#303F9F#283593#1A237E#8C9EFF#536DFE#3D5AFE#304FFE", + blue = "#E3F2FD#BBDEFB#90CAF9#64B5F6#64B5F6#2196F3#1E88E5#1976D2#1565C0#0D47A1#82B1FF#448AFF#2979FF#2962FF", + lightblue = "#E1F5FE#B3E5FC#81D4FA#4FC3F7#29B6F6#03A9F4#039BE5#0288D1#0277BD#01579B#80D8FF#40C4FF#00B0FF#0091EA", + cyan = "#E0F7FA#B2EBF2#80DEEA#4DD0E1#26C6DA#00BCD4#00ACC1#0097A7#00838F#006064#84FFFF#18FFFF#00E5FF#00B8D4", + teal = "#E0F2F1#B2DFDB#80CBC4#4DB6AC#26A69A#009688#00897B#00796B#00695C#004D40#A7FFEB#64FFDA#1DE9B6#00BFA5", + green = "#E8F5E9#C8E6C9#A5D6A7#81C784#66BB6A#4CAF50#43A047#388E3C#2E7D32#1B5E20#B9F6CA#69F0AE#00E676#00C853", + lightgreen = "#F1F8E9#DCEDC8#C5E1A5#AED581#9CCC65#8BC34A#7CB342#689F38#558B2F#33691E#CCFF90#B2FF59#76FF03#64DD17", + lime = "#F9FBE7#F0F4C3#E6EE9C#DCE775#D4E157#CDDC39#C0CA33#AFB42B#9E9D24#827717#F4FF81#EEFF41#C6FF00#AEEA00", + yellow = "#FFFDE7#FFF9C4#FFF59D#FFF176#FFEE58#FFEB3B#FDD835#FBC02D#F9A825#F57F17#FFFF8D#FFFF00#FFEA00#FFD600", + amber = "#FFF8E1#FFECB3#FFE082#FFD54F#FFCA28#FFC107#FFB300#FFA000#FF8F00#FF6F00#FFE57F#FFD740#FFC400#FFAB00", + orange = "#FFF3E0#FFE0B2#FFCC80#FFB74D#FFA726#FF9800#FB8C00#F57C00#EF6C00#E65100#FFD180#FFAB40#FF9100#FF6D00", + deeporange = "#FBE9E7#FFCCBC#FFAB91#FF8A65#FF7043#FF5722#F4511E#E64A19#D84315#BF360C#FF9E80#FF6E40#FF3D00#DD2C00", + brown = "#EFEBE9#D7CCC8#BCAAA4#A1887F#8D6E63#795548#6D4C41#5D4037#4E342E#3E2723", + grey = "#FAFAFA#F5F5F5#EEEEEE#E0E0E0#BDBDBD#9E9E9E#757575#616161#424242#212121", + bluegrey = "#ECEFF1#CFD8DC#B0BEC5#90A4AE#78909C#607D8B#546E7A#455A64#37474F#263238"; + /*\ + * Snap.mui + [ property ] + ** + * Contain Material UI colours. + | Snap().rect(0, 0, 10, 10).attr({fill: Snap.mui.deeppurple, stroke: Snap.mui.amber[600]}); + # For colour reference: https://www.materialui.co. + \*/ + Snap.mui = {}; + /*\ + * Snap.flat + [ property ] + ** + * Contain Flat UI colours. + | Snap().rect(0, 0, 10, 10).attr({fill: Snap.flat.carrot, stroke: Snap.flat.wetasphalt}); + # For colour reference: https://www.materialui.co. + \*/ + Snap.flat = {}; + function saveColor(colors) { + colors = colors.split(/(?=#)/); + var color = new String(colors[5]); + color[50] = colors[0]; + color[100] = colors[1]; + color[200] = colors[2]; + color[300] = colors[3]; + color[400] = colors[4]; + color[500] = colors[5]; + color[600] = colors[6]; + color[700] = colors[7]; + color[800] = colors[8]; + color[900] = colors[9]; + if (colors[10]) { + color.A100 = colors[10]; + color.A200 = colors[11]; + color.A400 = colors[12]; + color.A700 = colors[13]; + } + return color; + } + Snap.mui.red = saveColor(red); + Snap.mui.pink = saveColor(pink); + Snap.mui.purple = saveColor(purple); + Snap.mui.deeppurple = saveColor(deeppurple); + Snap.mui.indigo = saveColor(indigo); + Snap.mui.blue = saveColor(blue); + Snap.mui.lightblue = saveColor(lightblue); + Snap.mui.cyan = saveColor(cyan); + Snap.mui.teal = saveColor(teal); + Snap.mui.green = saveColor(green); + Snap.mui.lightgreen = saveColor(lightgreen); + Snap.mui.lime = saveColor(lime); + Snap.mui.yellow = saveColor(yellow); + Snap.mui.amber = saveColor(amber); + Snap.mui.orange = saveColor(orange); + Snap.mui.deeporange = saveColor(deeporange); + Snap.mui.brown = saveColor(brown); + Snap.mui.grey = saveColor(grey); + Snap.mui.bluegrey = saveColor(bluegrey); + Snap.flat.turquoise = "#1abc9c"; + Snap.flat.greensea = "#16a085"; + Snap.flat.sunflower = "#f1c40f"; + Snap.flat.orange = "#f39c12"; + Snap.flat.emerland = "#2ecc71"; + Snap.flat.nephritis = "#27ae60"; + Snap.flat.carrot = "#e67e22"; + Snap.flat.pumpkin = "#d35400"; + Snap.flat.peterriver = "#3498db"; + Snap.flat.belizehole = "#2980b9"; + Snap.flat.alizarin = "#e74c3c"; + Snap.flat.pomegranate = "#c0392b"; + Snap.flat.amethyst = "#9b59b6"; + Snap.flat.wisteria = "#8e44ad"; + Snap.flat.clouds = "#ecf0f1"; + Snap.flat.silver = "#bdc3c7"; + Snap.flat.wetasphalt = "#34495e"; + Snap.flat.midnightblue = "#2c3e50"; + Snap.flat.concrete = "#95a5a6"; + Snap.flat.asbestos = "#7f8c8d"; + /*\ + * Snap.importMUIColors + [ method ] + ** + * Imports Material UI colours into global object. + | Snap.importMUIColors(); + | Snap().rect(0, 0, 10, 10).attr({fill: deeppurple, stroke: amber[600]}); + # For colour reference: https://www.materialui.co. + \*/ + Snap.importMUIColors = function () { + for (var color in Snap.mui) { + if (Snap.mui.hasOwnProperty(color)) { + window[color] = Snap.mui[color]; + } + } + }; +}); + return Snap; -})); +})); \ No newline at end of file diff --git a/doc/reference.html b/doc/reference.html index eed4bdd..9f08b41 100644 --- a/doc/reference.html +++ b/doc/reference.html @@ -8,7 +8,6 @@ - @@ -17,18 +16,15 @@ var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-44948757-1']); _gaq.push(['_trackPageview']); - (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); - - function trackOutboundLink(link, category, action) { - try { - _gaq.push(['_trackEvent', category , action]); + function trackOutboundLink(link, category, action) { + try { + _gaq.push(['_trackEvent', category , action]); } catch(err){} - setTimeout(function() { document.location.href = link.href; }, 100); @@ -36,11 +32,10 @@ - - - -
-
-
- -
- -
-
-
-
- -
-
-

Snap(…)

-
-
-
-
- - - - -

Creates a drawing surface or wraps existing SVG element. -

- - - - - - - - - - -
-

Parameters

-
    -
  1. width - number string - width of surface
  2. -
  3. height - number string - height of surface
  4. - -
-
- - - - - - - - -

or -

- - - - - - - - - - -
-

Parameters

-
    -
  1. DOM - SVGElement - element to be wrapped into Snap structure
  2. - -
-
- - - - - - - - -

or -

- - - - - - - - - - -
-

Parameters

-
    -
  1. array - array - array of elements (will return set of elements)
  2. - -
-
- - - - - - - - -

or -

- - - - - - - - - - -
-

Parameters

-
    -
  1. query - string - CSS query selector
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - Element -

- - - - -
-
-
- -
-
-

Snap.format(token, json)

-
-
-
-
- - - - -

Replaces construction of type {<name>} to the corresponding argument -

- - - - - - - - - - -
-

Parameters

-
    -
  1. token - string - string to format
  2. -
  3. json - object - object which properties are used as a replacement
  4. - -
-
- - - - - - - - - - - - - -

- Returns: - - string - - formatted string -

- - - - - - - - -

Usage

- - - - - - - - - - - -
// this draws a rectangular shape equivalent to "M10,20h40v50h-40z"
+                
+
+ +
+ +
+
+
+
+
+
+

Snap(…) + + +

+
+
+
+
+

Creates a drawing surface or wraps existing SVG element. +

+
+

Parameters

+
    +
  1. + width + + number + string + + width of surface +
  2. +
  3. + height + + number + string + + height of surface +
  4. +
+
+

or +

+
+

Parameters

+
    +
  1. + DOM + + SVGElement + + element to be wrapped into Snap structure +
  2. +
+
+

or +

+
+

Parameters

+
    +
  1. + array + + array + + array of elements (will return set of + elements) +
  2. +
+
+

or +

+
+

Parameters

+
    +
  1. + query + + string + + CSS query selector +
  2. +
+
+

+ Returns: + object + + Element + +

+
+
+
+
+
+

Snap.url(value) + + +

+
+
+
+
+

Wraps path into "url('<path>')". +

+
+

Parameters

+
    +
  1. + value + + string + + path +
  2. +
+
+

+ Returns: + string + wrapped path +

+
+
+
+
+
+

Snap.format(token, json) + + +

+
+
+
+
+

Replaces construction of type {<name>} to the corresponding argument +

+
+

Parameters

+
    +
  1. + token + + string + + string to format +
  2. +
  3. + json + + object + + object which properties are used as a + replacement +
  4. +
+
+

+ Returns: + string + formatted string +

+

Usage

+
// this draws a rectangular shape equivalent to "M10,20h40v50h-40z"
 paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']}z", {
     x: 10,
     y: 20,
@@ -1073,2596 +1281,1567 @@ paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']
         "negative width": -40
     }
 }));
- - - - - -
-
-
- -
-
-

Snap.rad(deg)

-
-
-
-
- - - - -

Transform angle to radians -

- - - - - - - - - - -
-

Parameters

-
    -
  1. deg - number - angle in degrees
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - angle in radians -

- - - - -
-
-
- -
-
-

Snap.deg(rad)

-
-
-
-
- - - - -

Transform angle to degrees -

- - - - - - - - - - -
-

Parameters

-
    -
  1. rad - number - angle in radians
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - angle in degrees -

- - - - -
-
-
- -
-
-

Snap.sin(angle)

-
-
-
-
- - - - -

Equivalent to Math.sin() only works with degrees, not radians. -

- - - - - - - - - - -
-

Parameters

-
    -
  1. angle - number - angle in degrees
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - sin -

- - - - -
-
-
- -
-
-

Snap.tan(angle)

-
-
-
-
- - - - -

Equivalent to Math.tan() only works with degrees, not radians. -

- - - - - - - - - - -
-

Parameters

-
    -
  1. angle - number - angle in degrees
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - tan -

- - - - -
-
-
- -
-
-

Snap.cos(angle)

-
-
-
-
- - - - -

Equivalent to Math.cos() only works with degrees, not radians. -

- - - - - - - - - - -
-

Parameters

-
    -
  1. angle - number - angle in degrees
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - cos -

- - - - -
-
-
- -
-
-

Snap.asin(num)

-
-
-
-
- - - - -

Equivalent to Math.asin() only works with degrees, not radians. -

- - - - - - - - - - -
-

Parameters

-
    -
  1. num - number - value
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - asin in degrees -

- - - - -
-
-
- -
-
-

Snap.acos(num)

-
-
-
-
- - - - -

Equivalent to Math.acos() only works with degrees, not radians. -

- - - - - - - - - - -
-

Parameters

-
    -
  1. num - number - value
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - acos in degrees -

- - - - -
-
-
- -
-
-

Snap.atan(num)

-
-
-
-
- - - - -

Equivalent to Math.atan() only works with degrees, not radians. -

- - - - - - - - - - -
-

Parameters

-
    -
  1. num - number - value
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - atan in degrees -

- - - - -
-
-
- -
-
-

Snap.atan2(num)

-
-
-
-
- - - - -

Equivalent to Math.atan2() only works with degrees, not radians. -

- - - - - - - - - - -
-

Parameters

-
    -
  1. num - number - value
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - atan2 in degrees -

- - - - -
-
-
- -
-
-

Snap.angle(x1, y1, x2, y2, [x3], [y3])

-
-
-
-
- - - - -

Returns an angle between two or three points -

- - - - - - - - - - - - -

Parameters

- - - - - - - - -
-

Parameters

-
    -
  1. x1 - number - x coord of first point
  2. -
  3. y1 - number - y coord of first point
  4. -
  5. x2 - number - x coord of second point
  6. -
  7. y2 - number - y coord of second point
  8. -
  9. x3 - number - x coord of third point
  10. -
  11. y3 - number - y coord of third point
  12. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - angle in degrees -

- - - - -
-
-
- -
-
-

Snap.len(x1, y1, x2, y2)

-
-
-
-
- - - - -

Returns distance between two points -

- - - - - - - - - - - - -

Parameters

- - - - - - - - -
-

Parameters

-
    -
  1. x1 - number - x coord of first point
  2. -
  3. y1 - number - y coord of first point
  4. -
  5. x2 - number - x coord of second point
  6. -
  7. y2 - number - y coord of second point
  8. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - distance -

- - - - -
-
-
- -
-
-

Snap.len2(x1, y1, x2, y2)

-
-
-
-
- - - - -

Returns squared distance between two points -

- - - - - - - - - - - - -

Parameters

- - - - - - - - -
-

Parameters

-
    -
  1. x1 - number - x coord of first point
  2. -
  3. y1 - number - y coord of first point
  4. -
  5. x2 - number - x coord of second point
  6. -
  7. y2 - number - y coord of second point
  8. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - distance -

- - - - -
-
-
- -
-
-

Snap.closestPoint(path, x, y)

-
-
-
-
- - - - -

Returns closest point to a given one on a given path. -

- - - - - - - - - - - - -

Parameters

- - - - - - - - -
-

Parameters

-
    -
  1. path - Element - path element
  2. -
  3. x - number - x coord of a point
  4. -
  5. y - number - y coord of a point
  6. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - in format -

- - - - -
-
-
- -
-
-

Snap.is(o, type)

-
-
-
-
- - - - -

Handy replacement for the typeof operator -

- - - - - - - - - - -
-

Parameters

-
    -
  1. o - - any object or primitive
  2. -
  3. type - string - name of the type, e.g., string, function, number, etc.
  4. - -
-
- - - - - - - - - - - - - -

- Returns: - - boolean - - true if given value is of given type -

- - - - -
-
-
- -
-
-

Snap.snapTo(values, value, [tolerance])

-
-
-
-
- - - - -

Snaps given value to given grid -

- - - - - - - - - - -
-

Parameters

-
    -
  1. values - array number - given array of values or step of the grid
  2. -
  3. value - number - value to adjust
  4. -
  5. tolerance - number - maximum distance to the target value that would trigger the snap. Default is 10.
  6. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - adjusted value -

- - - - -
-
-
- -
-
-

Snap.getRGB(color)

-
-
-
-
- - - - -

Parses color string as RGB object -

- - - - - - - - - - -
-

Parameters

-
    -
  1. color - string - color string in one of the following formats:
  2. - -
-
- - - - - - - - - - -
    - - - - - - - - - - - -
  • Color name (red, green, cornflowerblue, etc)
  • - - - - - - - - - - - -
  • #••• — shortened HTML color: (#000, #fc0, etc.)
  • - - - - - - - - - - - -
  • #•••••• — full length HTML color: (#000000, #bd2300)
  • - - - - - - - - - - - -
  • rgb(•••, •••, •••) — red, green and blue channels values: (rgb(200, 100, 0))
  • - - - - - - - - - - - -
  • rgba(•••, •••, •••, •••) — also with opacity
  • - - - - - - - - - - - -
  • rgb(•••%, •••%, •••%) — same as above, but in %: (rgb(100%, 175%, 0%))
  • - - - - - - - - - - - -
  • rgba(•••%, •••%, •••%, •••%) — also with opacity
  • - - - - - - - - - - - -
  • hsb(•••, •••, •••) — hue, saturation and brightness values: (hsb(0.5, 0.25, 1))
  • - - - - - - - - - - - -
  • hsba(•••, •••, •••, •••) — also with opacity
  • - - - - - - - - - - - -
  • hsb(•••%, •••%, •••%) — same as above, but in %
  • - - - - - - - - - - - -
  • hsba(•••%, •••%, •••%, •••%) — also with opacity
  • - - - - - - - - - - - -
  • hsl(•••, •••, •••) — hue, saturation and luminosity values: (hsb(0.5, 0.25, 0.5))
  • - - - - - - - - - - - -
  • hsla(•••, •••, •••, •••) — also with opacity
  • - - - - - - - - - - - -
  • hsl(•••%, •••%, •••%) — same as above, but in %
  • - - - - - - - - - - - -
  • hsla(•••%, •••%, •••%, •••%) — also with opacity
  • - - - - - - - - - - - -
- - - - - - - - - -

Note that % can be used any time: rgb(20%, 255, 50%). -

- - - - - - - - - - - - - - -

- Returns: - - object - - RGB object in the following format: -

- - - - - - - - - - - -
    - - -
  1. {
      - - - -
    1. - r - number - red, -
    2. - - - -
    3. - g - number - green, -
    4. - - - -
    5. - b - number - blue, -
    6. - - - -
    7. - hex - string - color in HTML/CSS format: #••••••, -
    8. - - - -
    9. - error - boolean - true if string can't be parsed -
    10. - - - -
  2. }
  3. - - -
- - -
-
-
- -
-
-

Snap.hsb(h, s, b)

-
-
-
-
- - - - -

Converts HSB values to a hex representation of the color -

- - - - - - - - - - -
-

Parameters

-
    -
  1. h - number - hue
  2. -
  3. s - number - saturation
  4. -
  5. b - number - value or brightness
  6. - -
-
- - - - - - - - - - - - - -

- Returns: - - string - - hex representation of the color -

- - - - -
-
-
- -
-
-

Snap.hsl(h, s, l)

-
-
-
-
- - - - -

Converts HSL values to a hex representation of the color -

- - - - - - - - - - -
-

Parameters

-
    -
  1. h - number - hue
  2. -
  3. s - number - saturation
  4. -
  5. l - number - luminosity
  6. - -
-
- - - - - - - - - - - - - -

- Returns: - - string - - hex representation of the color -

- - - - -
-
-
- -
-
-

Snap.rgb(r, g, b)

-
-
-
-
- - - - -

Converts RGB values to a hex representation of the color -

- - - - - - - - - - -
-

Parameters

-
    -
  1. r - number - red
  2. -
  3. g - number - green
  4. -
  5. b - number - blue
  6. - -
-
- - - - - - - - - - - - - -

- Returns: - - string - - hex representation of the color -

- - - - -
-
-
- -
-
-

Snap.color(clr)

-
-
-
-
- - - - -

Parses the color string and returns an object featuring the color's component values -

- - - - - - - - - - -
-

Parameters

-
    -
  1. clr - string - color string in one of the supported formats (see Snap.getRGB)
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - Combined RGB/HSB object in the following format: -

- - - - - - - - - - - -
    - - -
  1. {
      - - - -
    1. - r - number - red, -
    2. - - - -
    3. - g - number - green, -
    4. - - - -
    5. - b - number - blue, -
    6. - - - -
    7. - hex - string - color in HTML/CSS format: #••••••, -
    8. - - - -
    9. - error - boolean - true if string can't be parsed, -
    10. - - - -
    11. - h - number - hue, -
    12. - - - -
    13. - s - number - saturation, -
    14. - - - -
    15. - v - number - value (brightness), -
    16. - - - -
    17. - l - number - lightness -
    18. - - - -
  2. }
  3. - - -
- - -
-
-
- -
-
-

Snap.hsb2rgb(h, s, v)

-
-
-
-
- - - - -

Converts HSB values to an RGB object -

- - - - - - - - - - -
-

Parameters

-
    -
  1. h - number - hue
  2. -
  3. s - number - saturation
  4. -
  5. v - number - value or brightness
  6. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - RGB object in the following format: -

- - - - - - - - - - - -
    - - -
  1. {
      - - - -
    1. - r - number - red, -
    2. - - - -
    3. - g - number - green, -
    4. - - - -
    5. - b - number - blue, -
    6. - - - -
    7. - hex - string - color in HTML/CSS format: #•••••• -
    8. - - - -
  2. }
  3. - - -
- - -
-
-
- -
-
-

Snap.hsl2rgb(h, s, l)

-
-
-
-
- - - - -

Converts HSL values to an RGB object -

- - - - - - - - - - -
-

Parameters

-
    -
  1. h - number - hue
  2. -
  3. s - number - saturation
  4. -
  5. l - number - luminosity
  6. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - RGB object in the following format: -

- - - - - - - - - - - -
    - - -
  1. {
      - - - -
    1. - r - number - red, -
    2. - - - -
    3. - g - number - green, -
    4. - - - -
    5. - b - number - blue, -
    6. - - - -
    7. - hex - string - color in HTML/CSS format: #•••••• -
    8. - - - -
  2. }
  3. - - -
- - -
-
-
- -
-
-

Snap.rgb2hsb(r, g, b)

-
-
-
-
- - - - -

Converts RGB values to an HSB object -

- - - - - - - - - - -
-

Parameters

-
    -
  1. r - number - red
  2. -
  3. g - number - green
  4. -
  5. b - number - blue
  6. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - HSB object in the following format: -

- - - - - - - - - - - -
    - - -
  1. {
      - - - -
    1. - h - number - hue, -
    2. - - - -
    3. - s - number - saturation, -
    4. - - - -
    5. - b - number - brightness -
    6. - - - -
  2. }
  3. - - -
- - -
-
-
- -
-
-

Snap.rgb2hsl(r, g, b)

-
-
-
-
- - - - -

Converts RGB values to an HSL object -

- - - - - - - - - - -
-

Parameters

-
    -
  1. r - number - red
  2. -
  3. g - number - green
  4. -
  5. b - number - blue
  6. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - HSL object in the following format: -

- - - - - - - - - - - -
    - - -
  1. {
      - - - -
    1. - h - number - hue, -
    2. - - - -
    3. - s - number - saturation, -
    4. - - - -
    5. - l - number - luminosity -
    6. - - - -
  2. }
  3. - - -
- - -
-
-
- -
-
-

Snap.parsePathString(pathString)

-
-
-
-
- - - - -

Utility method -Parses given path string into an array of arrays of path segments -

- - - - - - - - - - -
-

Parameters

-
    -
  1. pathString - string array - path string or array of segments (in the last case it is returned straight away)
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - array - - array of segments -

- - - - -
-
-
- -
-
-

Snap.parseTransformString(TString)

-
-
-
-
- - - - -

Utility method -Parses given transform string into an array of transformations -

- - - - - - - - - - -
-

Parameters

-
    -
  1. TString - string array - transform string or array of transformations (in the last case it is returned straight away)
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - array - - array of transformations -

- - - - -
-
-
- -
-
-

Snap.select(query)

-
-
-
-
- - - - -

Wraps a DOM element specified by CSS selector as Element -

- - - - - - - - - - -
-

Parameters

-
    -
  1. query - string - CSS selector of the element
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the current element -

- - - - -
-
-
- -
-
-

Snap.selectAll(query)

-
-
-
-
- - - - -

Wraps DOM elements specified by CSS selector as set or array of Element -

- - - - - - - - - - -
-

Parameters

-
    -
  1. query - string - CSS selector of the element
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the current element -

- - - - -
-
-
- -
-
-

Element.node()

-
-
-
-
- - - - -

Gives you a reference to the DOM object, so you can assign event handlers or just mess around. -

- - - - - - - - - - - - -

Usage

- - - - - - - - - - - -
// draw a circle at coordinate 10,10 with radius of 10
+                            
+
+
+
+
+

Snap.rad(deg) + + +

+
+
+
+
+

Transform angle to radians +

+
+

Parameters

+
    +
  1. + deg + + number + + angle in degrees +
  2. +
+
+

+ Returns: + number + angle in radians +

+
+
+
+
+
+

Snap.deg(rad) + + +

+
+
+
+
+

Transform angle to degrees +

+
+

Parameters

+
    +
  1. + rad + + number + + angle in radians +
  2. +
+
+

+ Returns: + number + angle in degrees +

+
+
+
+
+
+

Snap.sin(angle) + + +

+
+
+
+
+

Equivalent to Math.sin() only works + with degrees, not radians. +

+
+

Parameters

+
    +
  1. + angle + + number + + angle in degrees +
  2. +
+
+

+ Returns: + number + sin +

+
+
+
+
+
+

Snap.tan(angle) + + +

+
+
+
+
+

Equivalent to Math.tan() only works + with degrees, not radians. +

+
+

Parameters

+
    +
  1. + angle + + number + + angle in degrees +
  2. +
+
+

+ Returns: + number + tan +

+
+
+
+
+
+

Snap.cos(angle) + + +

+
+
+
+
+

Equivalent to Math.cos() only works + with degrees, not radians. +

+
+

Parameters

+
    +
  1. + angle + + number + + angle in degrees +
  2. +
+
+

+ Returns: + number + cos +

+
+
+
+
+
+

Snap.asin(num) + + +

+
+
+
+
+

Equivalent to Math.asin() only works + with degrees, not radians. +

+
+

Parameters

+
    +
  1. + num + + number + + value +
  2. +
+
+

+ Returns: + number + asin in degrees +

+
+
+
+
+
+

Snap.acos(num) + + +

+
+
+
+
+

Equivalent to Math.acos() only works + with degrees, not radians. +

+
+

Parameters

+
    +
  1. + num + + number + + value +
  2. +
+
+

+ Returns: + number + acos in degrees +

+
+
+
+
+
+

Snap.atan(num) + + +

+
+
+
+
+

Equivalent to Math.atan() only works + with degrees, not radians. +

+
+

Parameters

+
    +
  1. + num + + number + + value +
  2. +
+
+

+ Returns: + number + atan in degrees +

+
+
+
+
+
+

Snap.atan2(num) + + +

+
+
+
+
+

Equivalent to Math.atan2() only works + with degrees, not radians. +

+
+

Parameters

+
    +
  1. + num + + number + + value +
  2. +
+
+

+ Returns: + number + atan2 in degrees +

+
+
+
+
+
+

Snap.angle(x1, y1, x2, y2, [x3], [y3]) + + +

+
+
+
+
+

Returns an angle between two or three points +

+
+

Parameters

+
    +
  1. + x1 + + number + + x coord of first point +
  2. +
  3. + y1 + + number + + y coord of first point +
  4. +
  5. + x2 + + number + + x coord of second point +
  6. +
  7. + y2 + + number + + y coord of second point +
  8. +
  9. + x3 + + number + + x coord of third point +
  10. +
  11. + y3 + + number + + y coord of third point +
  12. +
+
+

+ Returns: + number + angle in degrees +

+
+
+
+
+
+

Snap.len(x1, y1, x2, y2) + + +

+
+
+
+
+

Returns distance between two points +

+
+

Parameters

+
    +
  1. + x1 + + number + + x coord of first point +
  2. +
  3. + y1 + + number + + y coord of first point +
  4. +
  5. + x2 + + number + + x coord of second point +
  6. +
  7. + y2 + + number + + y coord of second point +
  8. +
+
+

+ Returns: + number + distance +

+
+
+
+
+
+

Snap.len2(x1, y1, x2, y2) + + +

+
+
+
+
+

Returns squared distance between two points +

+
+

Parameters

+
    +
  1. + x1 + + number + + x coord of first point +
  2. +
  3. + y1 + + number + + y coord of first point +
  4. +
  5. + x2 + + number + + x coord of second point +
  6. +
  7. + y2 + + number + + y coord of second point +
  8. +
+
+

+ Returns: + number + distance +

+
+
+
+
+
+

Snap.closestPoint(path, x, y) + + +

+
+
+
+
+

Returns closest point to a given one on a given path. +

+
+

Parameters

+
    +
  1. + path + + Element + + path element +
  2. +
  3. + x + + number + + x coord of a point +
  4. +
  5. + y + + number + + y coord of a point +
  6. +
+
+

+ Returns: + object + in format +

+
+
+
+
+
+

Snap.is(o, type) + + +

+
+
+
+
+

Handy replacement for the typeof operator +

+
+

Parameters

+
    +
  1. + o + + + + any object or primitive +
  2. +
  3. + type + + string + + name of the type, e.g., string, + function, number, + etc. +
  4. +
+
+

+ Returns: + boolean + true if given value is of given + type +

+
+
+
+
+
+

Snap.snapTo(values, value, [tolerance]) + + +

+
+
+
+
+

Snaps given value to given grid +

+
+

Parameters

+
    +
  1. + values + + array + number + + given array of values or step of the + grid +
  2. +
  3. + value + + number + + value to adjust +
  4. +
  5. + tolerance + + number + + maximum distance to the target value + that would trigger the snap. Default + is 10. +
  6. +
+
+

+ Returns: + number + adjusted value +

+
+
+
+
+
+

Snap.getRGB(color) + + +

+
+
+
+
+

Parses color string as RGB object +

+
+

Parameters

+
    +
  1. + color + + string + + color string in one of the following + formats: +
  2. +
+
+
    +
  • Color name (red, green, + cornflowerblue, etc)
  • +
  • #••• — shortened HTML color: (#000, + #fc0, etc.)
  • +
  • #•••••• — full length HTML color: (#000000, + #bd2300)
  • +
  • rgb(•••, •••, •••) — red, green and blue channels + values: (rgb(200, 100, 0))
  • +
  • rgba(•••, •••, •••, •••) — also with opacity
  • +
  • rgb(•••%, •••%, •••%) — same as above, but in + %: (rgb(100%, 175%, 0%))
  • +
  • rgba(•••%, •••%, •••%, •••%) — also with opacity
  • +
  • hsb(•••, •••, •••) — hue, saturation and brightness + values: (hsb(0.5, 0.25, 1))
  • +
  • hsba(•••, •••, •••, •••) — also with opacity
  • +
  • hsb(•••%, •••%, •••%) — same as above, but in + %
  • +
  • hsba(•••%, •••%, •••%, •••%) — also with opacity
  • +
  • hsl(•••, •••, •••) — hue, saturation and luminosity + values: (hsb(0.5, 0.25, 0.5))
  • +
  • hsla(•••, •••, •••, •••) — also with opacity
  • +
  • hsl(•••%, •••%, •••%) — same as above, but in + %
  • +
  • hsla(•••%, •••%, •••%, •••%) — also with opacity
  • +
+

Note that % can be used any time: rgb(20%, 255, 50%). +

+

+ Returns: + object + RGB object in the following format: +

+
    +
  1. { +
      +
    1. + r + + number + + red, +
    2. +
    3. + g + + number + + green, +
    4. +
    5. + b + + number + + blue, +
    6. +
    7. + hex + + string + + color in HTML/CSS format: #••••••, +
    8. +
    9. + error + + boolean + + true if string can't be parsed +
    10. +
    +
  2. +
  3. }
  4. +
+
+
+
+
+
+

Snap.hsb(h, s, b) + + +

+
+
+
+
+

Converts HSB values to a hex representation of the + color +

+
+

Parameters

+
    +
  1. + h + + number + + hue +
  2. +
  3. + s + + number + + saturation +
  4. +
  5. + b + + number + + value or brightness +
  6. +
+
+

+ Returns: + string + hex representation of the color +

+
+
+
+
+
+

Snap.hsl(h, s, l) + + +

+
+
+
+
+

Converts HSL values to a hex representation of the + color +

+
+

Parameters

+
    +
  1. + h + + number + + hue +
  2. +
  3. + s + + number + + saturation +
  4. +
  5. + l + + number + + luminosity +
  6. +
+
+

+ Returns: + string + hex representation of the color +

+
+
+
+
+
+

Snap.rgb(r, g, b) + + +

+
+
+
+
+

Converts RGB values to a hex representation of the + color +

+
+

Parameters

+
    +
  1. + r + + number + + red +
  2. +
  3. + g + + number + + green +
  4. +
  5. + b + + number + + blue +
  6. +
+
+

+ Returns: + string + hex representation of the color +

+
+
+
+
+
+

Snap.color(clr) + + +

+
+
+
+
+

Parses the color string and returns an object featuring + the color's component values +

+
+

Parameters

+
    +
  1. + clr + + string + + color string in one of the supported + formats (see + Snap.getRGB) +
  2. +
+
+

+ Returns: + object + Combined RGB/HSB object in the following format: +

+
    +
  1. { +
      +
    1. + r + + number + + red, +
    2. +
    3. + g + + number + + green, +
    4. +
    5. + b + + number + + blue, +
    6. +
    7. + hex + + string + + color in HTML/CSS format: #••••••, +
    8. +
    9. + error + + boolean + + true if string can't + be parsed, +
    10. +
    11. + h + + number + + hue, +
    12. +
    13. + s + + number + + saturation, +
    14. +
    15. + v + + number + + value (brightness), +
    16. +
    17. + l + + number + + lightness +
    18. +
    +
  2. +
  3. }
  4. +
+
+
+
+
+
+

Snap.hsb2rgb(h, s, v) + + +

+
+
+
+
+

Converts HSB values to an RGB object +

+
+

Parameters

+
    +
  1. + h + + number + + hue +
  2. +
  3. + s + + number + + saturation +
  4. +
  5. + v + + number + + value or brightness +
  6. +
+
+

+ Returns: + object + RGB object in the following format: +

+
    +
  1. { +
      +
    1. + r + + number + + red, +
    2. +
    3. + g + + number + + green, +
    4. +
    5. + b + + number + + blue, +
    6. +
    7. + hex + + string + + color in HTML/CSS format: #•••••• +
    8. +
    +
  2. +
  3. }
  4. +
+
+
+
+
+
+

Snap.hsl2rgb(h, s, l) + + +

+
+
+
+
+

Converts HSL values to an RGB object +

+
+

Parameters

+
    +
  1. + h + + number + + hue +
  2. +
  3. + s + + number + + saturation +
  4. +
  5. + l + + number + + luminosity +
  6. +
+
+

+ Returns: + object + RGB object in the following format: +

+
    +
  1. { +
      +
    1. + r + + number + + red, +
    2. +
    3. + g + + number + + green, +
    4. +
    5. + b + + number + + blue, +
    6. +
    7. + hex + + string + + color in HTML/CSS format: #•••••• +
    8. +
    +
  2. +
  3. }
  4. +
+
+
+
+
+
+

Snap.rgb2hsb(r, g, b) + + +

+
+
+
+
+

Converts RGB values to an HSB object +

+
+

Parameters

+
    +
  1. + r + + number + + red +
  2. +
  3. + g + + number + + green +
  4. +
  5. + b + + number + + blue +
  6. +
+
+

+ Returns: + object + HSB object in the following format: +

+
    +
  1. { +
      +
    1. + h + + number + + hue, +
    2. +
    3. + s + + number + + saturation, +
    4. +
    5. + b + + number + + brightness +
    6. +
    +
  2. +
  3. }
  4. +
+
+
+
+
+
+

Snap.rgb2hsl(r, g, b) + + +

+
+
+
+
+

Converts RGB values to an HSL object +

+
+

Parameters

+
    +
  1. + r + + number + + red +
  2. +
  3. + g + + number + + green +
  4. +
  5. + b + + number + + blue +
  6. +
+
+

+ Returns: + object + HSL object in the following format: +

+
    +
  1. { +
      +
    1. + h + + number + + hue, +
    2. +
    3. + s + + number + + saturation, +
    4. +
    5. + l + + number + + luminosity +
    6. +
    +
  2. +
  3. }
  4. +
+
+
+
+
+
+

Snap.parsePathString(pathString) + + +

+
+
+
+
+

Utility method Parses given path string into an array + of arrays of path segments +

+
+

Parameters

+
    +
  1. + pathString + + string + array + + path string or array of segments (in + the last case it is returned straight + away) +
  2. +
+
+

+ Returns: + array + array of segments +

+
+
+
+
+
+

Snap.parseTransformString(TString) + + +

+
+
+
+
+

Utility method Parses given transform string into + an array of transformations +

+
+

Parameters

+
    +
  1. + TString + + string + array + + transform string or array of transformations + (in the last case it is returned + straight away) +
  2. +
+
+

+ Returns: + array + array of transformations +

+
+
+
+
+
+

Snap.select(query) + + +

+
+
+
+
+

Wraps a DOM element specified by CSS selector as + Element +

+
+

Parameters

+
    +
  1. + query + + string + + CSS selector of the element +
  2. +
+
+

+ Returns: + Element + the current element +

+
+
+
+
+
+

Snap.selectAll(query) + + +

+
+
+
+
+

Wraps DOM elements specified by CSS selector as set + or array of + Element +

+
+

Parameters

+
    +
  1. + query + + string + + CSS selector of the element +
  2. +
+
+

+ Returns: + Element + the current element +

+
+
+
+
+
+

Element.node() + + +

+
+
+
+
+

Gives you a reference to the DOM object, so you can + assign event handlers or just mess around. +

+

Usage

+
// draw a circle at coordinate 10,10 with radius of 10
 var c = paper.circle(10, 10, 10);
 c.node.onclick = function () {
     c.attr("fill", "red");
 };
- - - - - -
-
-
- -
-
-

Element.type()

-
-
-
-
- - - - -

SVG tag name of the given element. -

- - - - - - - - -
-
-
- -
-
-

Element.attr(…)

-
-
-
-
- - - - -

Gets or sets given attributes of the element. -

- - - - - - - - - - -
-

Parameters

-
    -
  1. params - object - contains key-value pairs of attributes you want to set
  2. - -
-
- - - - - - - - -

or -

- - - - - - - - - - -
-

Parameters

-
    -
  1. param - string - name of the attribute
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the current element -

- - - - - -

or -

- - - - - - - - - - - - - - -

- Returns: - - string - - value of attribute -

- - - - - - - - -

Usage

- - - - - - - - - - - -
el.attr({
+                            
+
+
+
+
+

Element.type() + + +

+
+
+
+
+

SVG tag name of the given element. +

+
+
+
+
+
+

Element.attr(…) + + +

+
+
+
+
+

Gets or sets given attributes of the element. +

+
+

Parameters

+
    +
  1. + params + + object + + contains key-value pairs of attributes + you want to set +
  2. +
+
+

or +

+
+

Parameters

+
    +
  1. + param + + string + + name of the attribute +
  2. +
+
+

+ Returns: + Element + the current element +

+

or +

+

+ Returns: + string + value of attribute +

+

Usage

+
el.attr({
     fill: "#fc0",
     stroke: "#000",
     strokeWidth: 2, // CamelCase...
@@ -3670,224 +2849,130 @@ c.node.onclick = function () {
     width: "*=2" // prefixed values
 });
 console.log(el.attr("fill")); // #fc0
- - - - - - -

Prefixed values in format "+=10" supported. All four operations -(+, -, * and /) could be used. Optionally you can use units for + -and -: "+=2em". -

- - - - - - - - -
-
-
- -
-
-

Snap.parse(svg)

-
-
-
-
- - - - -

Parses SVG fragment and converts it into a Fragment -

- - - - - - - - - - -
-

Parameters

-
    -
  1. svg - string - SVG string
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Fragment - - the Fragment -

- - - - -
-
-
- -
-
-

Snap.fragment(varargs)

-
-
-
-
- - - - -

Creates a DOM fragment from a given list of elements or strings -

- - - - - - - - - - -
-

Parameters

-
    -
  1. varargs - - SVG string
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Fragment - - the Fragment -

- - - - -
-
-
- -
-
-

Paper.el(name, attr)

-
-
-
-
- - - - -

Creates an element on paper with a given name and no attributes -

- - - - - - - - - - -
-

Parameters

-
    -
  1. name - string - tag name
  2. -
  3. attr - object - attributes
  4. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the current element -

- - - - - - - - -

Usage

- - - - - - - - - - - -
var c = paper.circle(10, 10, 10); // is the same as...
+                                

Prefixed values in format "+=10" supported. All four operations ( + +, -, * and /) could be used. Optionally + you can use units for + and -: + "+=2em". +

+
+
+
+
+
+

Snap.parse(svg) + + +

+
+
+
+
+

Parses SVG fragment and converts it into a + Fragment +

+
+

Parameters

+
    +
  1. + svg + + string + + SVG string +
  2. +
+
+

+ Returns: + Fragment + the + Fragment + +

+
+
+
+
+
+

Snap.fragment(varargs) + + +

+
+
+
+
+

Creates a DOM fragment from a given list of elements + or strings +

+
+

Parameters

+
    +
  1. + varargs + + + + SVG string +
  2. +
+
+

+ Returns: + Fragment + the + Fragment + +

+
+
+
+
+
+

Paper.el(name, attr) + + +

+
+
+
+
+

Creates an element on paper with a given name and + no attributes +

+
+

Parameters

+
    +
  1. + name + + string + + tag name +
  2. +
  3. + attr + + object + + attributes +
  4. +
+
+

+ Returns: + Element + the current element +

+

Usage

+
var c = paper.circle(10, 10, 10); // is the same as...
 var c = paper.el("circle").attr({
     cx: 10,
     cy: 10,
@@ -3899,1780 +2984,1112 @@ var c = paper.el("circle", {
     cy: 10,
     r: 10
 });
- - - - - -
-
-
- -
-
-

Element.children()

-
-
-
-
- - - - -

Returns array of all the children of the element. -

- - - - - - - - - - - - - - -

- Returns: - - array - - array of Elements -

- - - - -
-
-
- -
-
-

Element.toJSON()

-
-
-
-
- - - - -

Returns object representation of the given element and all its children. -

- - - - - - - - - - - - - - -

- Returns: - - object - - in format -

- - - - - - - - - - - -
    - - -
  1. {
      - - - -
    1. - type - string - this.type, -
    2. - - - -
    3. - attr - object - attributes map, -
    4. - - - -
    5. - childNodes - array - optional array of children in the same format -
    6. - - - -
  2. }
  3. - - -
- - -
-
-
- -
-
-

Snap.ajax(…)

-
-
-
-
- - - - -

Simple implementation of Ajax -

- - - - - - - - - - -
-

Parameters

-
    -
  1. url - string - URL
  2. -
  3. postData - object string - data for post request
  4. -
  5. callback - function - callback
  6. -
  7. scope - object - scope of callback
  8. - -
-
- - - - - - - - -

or -

- - - - - - - - - - -
-

Parameters

-
    -
  1. url - string - URL
  2. -
  3. callback - function - callback
  4. -
  5. scope - object - scope of callback
  6. - -
-
- - - - - - - - - - - - - -

- Returns: - - XMLHttpRequest - - the XMLHttpRequest object, just in case -

- - - - -
-
-
- -
-
-

Snap.load(url, callback, [scope])

-
-
-
-
- - - - -

Loads external SVG file as a Fragment (see Snap.ajax for more advanced AJAX) -

- - - - - - - - - - -
-

Parameters

-
    -
  1. url - string - URL
  2. -
  3. callback - function - callback
  4. -
  5. scope - object - scope of callback
  6. - -
-
- - - - - - - -
-
-
- -
-
-

Snap.getElementByPoint(x, y)

-
-
-
-
- - - - -

Returns you topmost element under given point. -

- - - - - - - - - - - - - - -

- Returns: - - object - - Snap element object -

- - - - - - -
-

Parameters

-
    -
  1. x - number - x coordinate from the top left corner of the window
  2. -
  3. y - number - y coordinate from the top left corner of the window
  4. - -
-
- - - - - - - - - - - -

Usage

- - - - - - - - - - - -
Snap.getElementByPoint(mouseX, mouseY).attr({stroke: "#f00"});
- - - - - -
-
-
- -
-
-

Snap.plugin(f)

-
-
-
-
- - - - -

Let you write plugins. You pass in a function with five arguments, like this: -

- - - - - - - - - - - - - -
Snap.plugin(function (Snap, Element, Paper, global, Fragment) {
+                            
+
+
+
+
+

Element.children() + + +

+
+
+
+
+

Returns array of all the children of the element. +

+

+ Returns: + array + array of Elements +

+
+
+
+
+
+

Element.toJSON() + + +

+
+
+
+
+

Returns object representation of the given element + and all its children. +

+

+ Returns: + object + in format +

+
    +
  1. { +
      +
    1. + type + + string + + this.type, +
    2. +
    3. + attr + + object + + attributes map, +
    4. +
    5. + childNodes + + array + + optional array of children in the + same format +
    6. +
    +
  2. +
  3. }
  4. +
+
+
+
+
+
+

Snap.ajax(…) + + +

+
+
+
+
+

Simple implementation of Ajax +

+
+

Parameters

+
    +
  1. + url + + string + + URL +
  2. +
  3. + postData + + object + string + + data for post request +
  4. +
  5. + callback + + function + + callback +
  6. +
  7. + scope + + object + + scope of callback +
  8. +
+
+

or +

+
+

Parameters

+
    +
  1. + url + + string + + URL +
  2. +
  3. + callback + + function + + callback +
  4. +
  5. + scope + + object + + scope of callback +
  6. +
+
+

+ Returns: + XMLHttpRequest + the XMLHttpRequest object, just in case +

+
+
+
+
+
+

Snap.load(url, callback, [scope]) + + +

+
+
+
+
+

Loads external SVG file as a + Fragment (see + Snap.ajax for more advanced AJAX) +

+
+

Parameters

+
    +
  1. + url + + string + + URL +
  2. +
  3. + callback + + function + + callback +
  4. +
  5. + scope + + object + + scope of callback +
  6. +
+
+
+
+
+
+
+

Snap.getElementByPoint(x, y) + + +

+
+
+
+
+

Returns you topmost element under given point. +

+

+ Returns: + object + Snap element object +

+
+

Parameters

+
    +
  1. + x + + number + + x coordinate from the top left corner + of the window +
  2. +
  3. + y + + number + + y coordinate from the top left corner + of the window +
  4. +
+
+

Usage

+
Snap.getElementByPoint(mouseX, mouseY).attr({stroke: "#f00"});
+
+
+
+
+
+

Snap.plugin(f) + + +

+
+
+
+
+

Let you write plugins. You pass in a function with + five arguments, like this: +

+
Snap.plugin(function (Snap, Element, Paper, global, Fragment) {
     Snap.newmethod = function () {};
     Element.prototype.newmethod = function () {};
     Paper.prototype.newmethod = function () {};
 });
- - - - - - -

Inside the function you have access to all main objects (and their -prototypes). This allow you to extend anything you want. -

- - - - - - - - - - -
-

Parameters

-
    -
  1. f - function - your plugin body
  2. - -
-
- - - - - - - -
-
-
- -
-
-

Element.getBBox()

-
-
-
-
- - - - -

Returns the bounding box descriptor for the given element -

- - - - - - - - - - - - - - -

- Returns: - - object - - bounding box descriptor: -

- - - - - - - - - - - -
    - - -
  1. {
      - - - -
    1. - cx: - number - x of the center, -
    2. - - - -
    3. - cy: - number - x of the center, -
    4. - - - -
    5. - h: - number - height, -
    6. - - - -
    7. - height: - number - height, -
    8. - - - -
    9. - path: - string - path command for the box, -
    10. - - - -
    11. - r0: - number - radius of a circle that fully encloses the box, -
    12. - - - -
    13. - r1: - number - radius of the smallest circle that can be enclosed, -
    14. - - - -
    15. - r2: - number - radius of the largest circle that can be enclosed, -
    16. - - - -
    17. - vb: - string - box as a viewbox command, -
    18. - - - -
    19. - w: - number - width, -
    20. - - - -
    21. - width: - number - width, -
    22. - - - -
    23. - x2: - number - x of the right side, -
    24. - - - -
    25. - x: - number - x of the left side, -
    26. - - - -
    27. - y2: - number - y of the bottom edge, -
    28. - - - -
    29. - y: - number - y of the top edge -
    30. - - - -
  2. }
  3. - - -
- - -
-
-
- -
-
-

Element.transform(tstr)

-
-
-
-
- - - - -

Gets or sets transformation of the element -

- - - - - - - - - - -
-

Parameters

-
    -
  1. tstr - string - transform string in Snap or SVG format
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the current element -

- - - - - -

or -

- - - - - - - - - - - - - - -

- Returns: - - object - - transformation descriptor: -

- - - - - - - - - - - -
    - - -
  1. {
      - - - -
    1. - string - string - transform string, -
    2. - - - -
    3. - globalMatrix - Matrix - matrix of all transformations applied to element or its parents, -
    4. - - - -
    5. - localMatrix - Matrix - matrix of transformations applied only to the element, -
    6. - - - -
    7. - diffMatrix - Matrix - matrix of difference between global and local transformations, -
    8. - - - -
    9. - global - string - global transformation as string, -
    10. - - - -
    11. - local - string - local transformation as string, -
    12. - - - -
    13. - toString - function - returns string property -
    14. - - - -
  2. }
  3. - - -
- - -
-
-
- -
-
-

Element.parent()

-
-
-
-
- - - - -

Returns the element's parent -

- - - - - - - - - - - - - - -

- Returns: - - Element - - the parent element -

- - - - -
-
-
- -
-
-

Element.append(el)

-
-
-
-
- - - - -

Appends the given element to current one -

- - - - - - - - - - -
-

Parameters

-
    -
  1. el - Element Set - element to append
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the parent element -

- - - - -
-
-
- - - -
-
-

Element.appendTo(el)

-
-
-
-
- - - - -

Appends the current element to the given one -

- - - - - - - - - - -
-

Parameters

-
    -
  1. el - Element - parent element to append to
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the child element -

- - - - -
-
-
- -
-
-

Element.prepend(el)

-
-
-
-
- - - - -

Prepends the given element to the current one -

- - - - - - - - - - -
-

Parameters

-
    -
  1. el - Element - element to prepend
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the parent element -

- - - - -
-
-
- -
-
-

Element.prependTo(el)

-
-
-
-
- - - - -

Prepends the current element to the given one -

- - - - - - - - - - -
-

Parameters

-
    -
  1. el - Element - parent element to prepend to
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the child element -

- - - - -
-
-
- -
-
-

Element.before(el)

-
-
-
-
- - - - -

Inserts given element before the current one -

- - - - - - - - - - -
-

Parameters

-
    -
  1. el - Element - element to insert
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the parent element -

- - - - -
-
-
- -
-
-

Element.after(el)

-
-
-
-
- - - - -

Inserts given element after the current one -

- - - - - - - - - - -
-

Parameters

-
    -
  1. el - Element - element to insert
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the parent element -

- - - - -
-
-
- -
-
-

Element.insertBefore(el)

-
-
-
-
- - - - -

Inserts the element after the given one -

- - - - - - - - - - -
-

Parameters

-
    -
  1. el - Element - element next to whom insert to
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the parent element -

- - - - -
-
-
- -
-
-

Element.insertAfter(el)

-
-
-
-
- - - - -

Inserts the element after the given one -

- - - - - - - - - - -
-

Parameters

-
    -
  1. el - Element - element next to whom insert to
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the parent element -

- - - - -
-
-
- -
-
-

Element.remove()

-
-
-
-
- - - - -

Removes element from the DOM -

- - - - - - - - - - - - - - -

- Returns: - - Element - - the detached element -

- - - - -
-
-
- -
-
-

Element.select(query)

-
-
-
-
- - - - -

Gathers the nested Element matching the given set of CSS selectors -

- - - - - - - - - - -
-

Parameters

-
    -
  1. query - string - CSS selector
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - result of query selection -

- - - - -
-
-
- -
-
-

Element.selectAll(query)

-
-
-
-
- - - - -

Gathers nested Element objects matching the given set of CSS selectors -

- - - - - - - - - - -
-

Parameters

-
    -
  1. query - string - CSS selector
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - Set - - array - - result of query selection -

- - - - -
-
-
- -
-
-

Element.asPX(attr, [value])

-
-
-
-
- - - - -

Returns given attribute of the element as a px value (not %, em, etc.) -

- - - - - - - - - - -
-

Parameters

-
    -
  1. attr - string - attribute name
  2. -
  3. value - string - attribute value
  4. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - result of query selection -

- - - - -
-
-
- -
-
-

Element.use()

-
-
-
-
- - - - -

Creates a <use> element linked to the current element -

- - - - - - - - - - - - - - -

- Returns: - - Element - - the <use> element -

- - - - -
-
-
- -
-
-

Element.clone()

-
-
-
-
- - - - -

Creates a clone of the element and inserts it after the element -

- - - - - - - - - - - - - - -

- Returns: - - Element - - the clone -

- - - - -
-
-
- -
-
-

Element.toDefs()

-
-
-
-
- - - - -

Moves element to the shared <defs> area -

- - - - - - - - - - - - - - -

- Returns: - - Element - - the element -

- - - - -
-
-
- -
-
-

Element.toPattern(x, y, width, height)

-
-
-
-
- - - - -

Creates a <pattern> element from the current element -To create a pattern you have to specify the pattern rect: -

- - - - - - - - - - -
-

Parameters

-
    -
  1. x - string number -
  2. -
  3. y - string number -
  4. -
  5. width - string number -
  6. -
  7. height - string number -
  8. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the <pattern> element -

- - - - - -

You can use pattern later on as an argument for fill attribute: -

- - - - - - - - - - - - - -
var p = paper.path("M10-5-10,15M15,0,0,15M0-5-20,15").attr({
+                                

Inside the function you have access to all main objects + (and their prototypes). This allow you to extend + anything you want. +

+
+

Parameters

+
    +
  1. + f + + function + + your plugin body +
  2. +
+
+
+
+
+
+
+

Element.getBBox() + + +

+
+
+
+
+

Returns the bounding box descriptor for the given + element +

+

+ Returns: + object + bounding box descriptor: +

+
    +
  1. { +
      +
    1. + cx: + + number + + x of the center, +
    2. +
    3. + cy: + + number + + x of the center, +
    4. +
    5. + h: + + number + + height, +
    6. +
    7. + height: + + number + + height, +
    8. +
    9. + path: + + string + + path command for the box, +
    10. +
    11. + r0: + + number + + radius of a circle that fully encloses + the box, +
    12. +
    13. + r1: + + number + + radius of the smallest circle that + can be enclosed, +
    14. +
    15. + r2: + + number + + radius of the largest circle that + can be enclosed, +
    16. +
    17. + vb: + + string + + box as a viewbox command, +
    18. +
    19. + w: + + number + + width, +
    20. +
    21. + width: + + number + + width, +
    22. +
    23. + x2: + + number + + x of the right side, +
    24. +
    25. + x: + + number + + x of the left side, +
    26. +
    27. + y2: + + number + + y of the bottom edge, +
    28. +
    29. + y: + + number + + y of the top edge +
    30. +
    +
  2. +
  3. }
  4. +
+
+
+
+
+
+

Element.transform(tstr) + + +

+
+
+
+
+

Gets or sets transformation of the element +

+
+

Parameters

+
    +
  1. + tstr + + string + + transform string in Snap or SVG format +
  2. +
+
+

+ Returns: + Element + the current element +

+

or +

+

+ Returns: + object + transformation descriptor: +

+
    +
  1. { +
      +
    1. + string + + string + + transform string, +
    2. +
    3. + globalMatrix + + Matrix + + matrix of all transformations applied + to element or its parents, +
    4. +
    5. + localMatrix + + Matrix + + matrix of transformations applied + only to the element, +
    6. +
    7. + diffMatrix + + Matrix + + matrix of difference between global + and local transformations, +
    8. +
    9. + global + + string + + global transformation as string, +
    10. +
    11. + local + + string + + local transformation as string, +
    12. +
    13. + toString + + function + + returns string property +
    14. +
    +
  2. +
  3. }
  4. +
+
+
+
+
+
+

Element.parent() + + +

+
+
+
+
+

Returns the element's parent +

+

+ Returns: + Element + the parent element +

+
+
+
+
+
+

Element.append(el) + + +

+
+
+
+
+

Appends the given element to current one +

+
+

Parameters

+
    +
  1. + el + + Element + Set + + element to append +
  2. +
+
+

+ Returns: + Element + the parent element +

+
+
+
+ +
+
+

Element.appendTo(el) + + +

+
+
+
+
+

Appends the current element to the given one +

+
+

Parameters

+
    +
  1. + el + + Element + + parent element to append to +
  2. +
+
+

+ Returns: + Element + the child element +

+
+
+
+
+
+

Element.prepend(el) + + +

+
+
+
+
+

Prepends the given element to the current one +

+
+

Parameters

+
    +
  1. + el + + Element + + element to prepend +
  2. +
+
+

+ Returns: + Element + the parent element +

+
+
+
+
+
+

Element.prependTo(el) + + +

+
+
+
+
+

Prepends the current element to the given one +

+
+

Parameters

+
    +
  1. + el + + Element + + parent element to prepend to +
  2. +
+
+

+ Returns: + Element + the child element +

+
+
+
+
+
+

Element.before(el) + + +

+
+
+
+
+

Inserts given element before the current one +

+
+

Parameters

+
    +
  1. + el + + Element + + element to insert +
  2. +
+
+

+ Returns: + Element + the parent element +

+
+
+
+
+
+

Element.after(el) + + +

+
+
+
+
+

Inserts given element after the current one +

+
+

Parameters

+
    +
  1. + el + + Element + + element to insert +
  2. +
+
+

+ Returns: + Element + the parent element +

+
+
+
+
+
+

Element.insertBefore(el) + + +

+
+
+
+
+

Inserts the element after the given one +

+
+

Parameters

+
    +
  1. + el + + Element + + element next to whom insert to +
  2. +
+
+

+ Returns: + Element + the parent element +

+
+
+
+
+
+

Element.insertAfter(el) + + +

+
+
+
+
+

Inserts the element after the given one +

+
+

Parameters

+
    +
  1. + el + + Element + + element next to whom insert to +
  2. +
+
+

+ Returns: + Element + the parent element +

+
+
+
+
+
+

Element.remove() + + +

+
+
+
+
+

Removes element from the DOM +

+

+ Returns: + Element + the detached element +

+
+
+
+
+
+

Element.select(query) + + +

+
+
+
+
+

Gathers the nested + Element matching the given set of CSS selectors +

+
+

Parameters

+
    +
  1. + query + + string + + CSS selector +
  2. +
+
+

+ Returns: + Element + result of query selection +

+
+
+
+
+
+

Element.selectAll(query) + + +

+
+
+
+
+

Gathers nested + Element objects matching the given set of + CSS selectors +

+
+

Parameters

+
    +
  1. + query + + string + + CSS selector +
  2. +
+
+

+ Returns: + Set + array + result of query selection +

+
+
+
+
+
+

Element.asPX(attr, [value]) + + +

+
+
+
+
+

Returns given attribute of the element as a px value (not %, em, etc.) +

+
+

Parameters

+
    +
  1. + attr + + string + + attribute name +
  2. +
  3. + value + + string + + attribute value +
  4. +
+
+

+ Returns: + Element + result of query selection +

+
+
+
+
+
+

Element.use() + + +

+
+
+
+
+

Creates a <use> element linked + to the current element +

+

+ Returns: + Element + the <use> element +

+
+
+
+
+
+

Element.clone() + + +

+
+
+
+
+

Creates a clone of the element and inserts it after + the element +

+

+ Returns: + Element + the clone +

+
+
+
+
+
+

Element.toDefs() + + +

+
+
+
+
+

Moves element to the shared <defs> area +

+

+ Returns: + Element + the element +

+
+
+
+
+
+

Element.toPattern(x, y, width, height) + + +

+
+
+
+
+

Creates a <pattern> element from + the current element To create a pattern you have + to specify the pattern rect: +

+
+

Parameters

+
    +
  1. + x + + string + number + + +
  2. +
  3. + y + + string + number + + +
  4. +
  5. + width + + string + number + + +
  6. +
  7. + height + + string + number + + +
  8. +
+
+

+ Returns: + Element + the <pattern> element +

+

You can use pattern later on as an argument for fill attribute: +

+
var p = paper.path("M10-5-10,15M15,0,0,15M0-5-20,15").attr({
         fill: "none",
         stroke: "#bada55",
         strokeWidth: 5
@@ -5681,651 +4098,140 @@ To create a pattern you have to specify the pattern rect:
 c.attr({
     fill: p
 });
- - - - - -
-
-
- -
-
-

Element.marker(x, y, width, height, refX, refY)

-
-
-
-
- - - - -

Creates a <marker> element from the current element -To create a marker you have to specify the bounding rect and reference point: -

- - - - - - - - - - -
-

Parameters

-
    -
  1. x - number -
  2. -
  3. y - number -
  4. -
  5. width - number -
  6. -
  7. height - number -
  8. -
  9. refX - number -
  10. -
  11. refY - number -
  12. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the <marker> element -

- - - - - -

You can specify the marker later as an argument for marker-start, marker-end, marker-mid, and marker attributes. The marker attribute places the marker at every point along the path, and marker-mid places them at every point except the start and end. -

- - - - - - - - -
-
-
- -
-
-

Snap.animation(attr, duration, [easing], [callback])

-
-
-
-
- - - - -

Creates an animation object -

- - - - - - - - - - -
-

Parameters

-
    -
  1. attr - object - attributes of final destination
  2. -
  3. duration - number - duration of the animation, in milliseconds
  4. -
  5. easing - function - one of easing functions of mina or custom one
  6. -
  7. callback - function - callback function that fires when animation ends
  8. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - animation object -

- - - - -
-
-
- -
-
-

Element.inAnim()

-
-
-
-
- - - - -

Returns a set of animations that may be able to manipulate the current element -

- - - - - - - - - - - - - - -

- Returns: - - object - - in format: -

- - - - - - - - - - - -
    - - -
  1. {
      - - - -
    1. - anim - object - animation object, -
    2. - - - -
    3. - mina - object - mina object, -
    4. - - - -
    5. - curStatus - number - 0..1 — status of the animation: 0 — just started, 1 — just finished, -
    6. - - - -
    7. - status - function - gets or sets the status of the animation, -
    8. - - - -
    9. - stop - function - stops the animation -
    10. - - - -
  2. }
  3. - - -
- - -
-
-
- -
-
-

Snap.animate(from, to, setter, duration, [easing], [callback])

-
-
-
-
- - - - -

Runs generic animation of one number into another with a caring function -

- - - - - - - - - - -
-

Parameters

-
    -
  1. from - number array - number or array of numbers
  2. -
  3. to - number array - number or array of numbers
  4. -
  5. setter - function - caring function that accepts one number argument
  6. -
  7. duration - number - duration, in milliseconds
  8. -
  9. easing - function - easing function from mina or custom
  10. -
  11. callback - function - callback function to execute when animation ends
  12. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - animation object in mina format -

- - - - - - - - - - - -
    - - -
  1. {
      - - - -
    1. - id - string - animation id, consider it read-only, -
    2. - - - -
    3. - duration - function - gets or sets the duration of the animation, -
    4. - - - -
    5. - easing - function - easing, -
    6. - - - -
    7. - speed - function - gets or sets the speed of the animation, -
    8. - - - -
    9. - status - function - gets or sets the status of the animation, -
    10. - - - -
    11. - stop - function - stops the animation -
    12. - - - -
  2. }
  3. - - -
- - - - - - - -
var rect = Snap().rect(0, 0, 10, 10);
-Snap.animate(0, 10, function (val) {
-    rect.attr({
-        x: val
-    });
-}, 1000);
-// in given context is equivalent to
-rect.animate({x: 10}, 1000);
- - - - - -
-
-
- -
-
-

Element.stop()

-
-
-
-
- - - - -

Stops all the animations for the current element -

- - - - - - - - - - - - - - -

- Returns: - - Element - - the current element -

- - - - -
-
-
- -
-
-

Element.animate(attrs, duration, [easing], [callback])

-
-
-
-
- - - - -

Animates the given attributes of the element -

- - - - - - - - - - -
-

Parameters

-
    -
  1. attrs - object - key-value pairs of destination attributes
  2. -
  3. duration - number - duration of the animation in milliseconds
  4. -
  5. easing - function - easing function from mina or custom
  6. -
  7. callback - function - callback function that executes when the animation ends
  8. - -
-
- - - - - - - - - - - - - -

- Returns: - - Element - - the current element -

- - - - -
-
-
- -
-
-

Element.data(key, [value])

-
-
-
-
- - - - -

Adds or retrieves given value associated with given key. (Don’t confuse -with data- attributes) -

See also Element.removeData -

- - - - - - - - - - -
-

Parameters

-
    -
  1. key - string - key to store data
  2. -
  3. value - any - value to store
  4. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - Element -

- - - - - -

or, if value is not specified: -

- - - - - - - - - - - - - - -

- Returns: - - any - - value -

- - - - - - - - -

Usage

- - - - - - - - - - - -
for (var i = 0, i < 5, i++) {
+                            
+
+
+
+
+

Element.marker(x, y, width, height, refX, refY) + + +

+
+
+
+
+

Creates a <marker> element from + the current element To create a marker you have + to specify the bounding rect and reference point: +

+
+

Parameters

+
    +
  1. + x + + number + + +
  2. +
  3. + y + + number + + +
  4. +
  5. + width + + number + + +
  6. +
  7. + height + + number + + +
  8. +
  9. + refX + + number + + +
  10. +
  11. + refY + + number + + +
  12. +
+
+

+ Returns: + Element + the <marker> element +

+

You can specify the marker later as an argument for + marker-start, marker-end, + marker-mid, and marker attributes. The marker attribute + places the marker at every point along the path, + and marker-mid places them at every + point except the start and end. +

+
+
+
+
+
+

Element.data(key, [value]) + + +

+
+
+
+
+

Adds or retrieves given value associated with given + key. (Don’t confuse with data- attributes) +

+

See also + Element.removeData +

+
+

Parameters

+
    +
  1. + key + + string + + key to store data +
  2. +
  3. + value + + any + + value to store +
  4. +
+
+

+ Returns: + object + + Element + +

+

or, if value is not specified: +

+

+ Returns: + any + value +

+

Usage

+
for (var i = 0, i < 5, i++) {
     paper.circle(10 + 15 * i, 10, 10)
          .attr({fill: "#000"})
          .data("i", i)
@@ -6333,8473 +4239,6426 @@ with data- attributes)
             alert(this.data("i"));
          });
 }
- - - - - -
-
-
- -
-
-

Element.removeData([key])

-
-
-
-
- - - - -

Removes value associated with an element by given key. -If key is not provided, removes all the data of the element. -

- - - - - - - - - - -
-

Parameters

-
    -
  1. key - string - key
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - Element -

- - - - -
-
-
- -
-
-

Element.outerSVG()

-
-
-
-
- - - - -

Returns SVG code for the element, equivalent to HTML's outerHTML. -

See also Element.innerSVG -

- - - - - - - - - - - - - - -

- Returns: - - string - - SVG code for the element -

- - - - -
-
-
- - - -
-
-

Element.innerSVG()

-
-
-
-
- - - - -

Returns SVG code for the element's contents, equivalent to HTML's innerHTML -

- - - - - - - - - - - - - - -

- Returns: - - string - - SVG code for the element -

- - - - -
-
-
- - - - - -
-
-

Matrix.add(…)

-
-
-
-
- - - - -

Adds the given matrix to existing one -

- - - - - - - - - - -
-

Parameters

-
    -
  1. a - number -
  2. -
  3. b - number -
  4. -
  5. c - number -
  6. -
  7. d - number -
  8. -
  9. e - number -
  10. -
  11. f - number -
  12. - -
-
- - - - - - - - -

or -

- - - - - - - - - - -
-

Parameters

-
    -
  1. matrix - object - Matrix
  2. - -
-
- - - - - - - -
-
-
- -
-
-

Matrix.invert()

-
-
-
-
- - - - -

Returns an inverted version of the matrix -

- - - - - - - - - - - - - - -

- Returns: - - object - - Matrix -

- - - - -
-
-
- -
-
-

Matrix.clone()

-
-
-
-
- - - - -

Returns a copy of the matrix -

- - - - - - - - - - - - - - -

- Returns: - - object - - Matrix -

- - - - -
-
-
- -
-
-

Matrix.translate(x, y)

-
-
-
-
- - - - -

Translate the matrix -

- - - - - - - - - - -
-

Parameters

-
    -
  1. x - number - horizontal offset distance
  2. -
  3. y - number - vertical offset distance
  4. - -
-
- - - - - - - -
-
-
- -
-
-

Matrix.scale(x, [y], [cx], [cy])

-
-
-
-
- - - - -

Scales the matrix -

- - - - - - - - - - -
-

Parameters

-
    -
  1. x - number - amount to be scaled, with 1 resulting in no change
  2. -
  3. y - number - amount to scale along the vertical axis. (Otherwise x applies to both axes.)
  4. -
  5. cx - number - horizontal origin point from which to scale
  6. -
  7. cy - number - vertical origin point from which to scale
  8. - -
-
- - - - - - - - -

Default cx, cy is the middle point of the element. -

- - - - - - - - -
-
-
- -
-
-

Matrix.rotate(a, x, y)

-
-
-
-
- - - - -

Rotates the matrix -

- - - - - - - - - - -
-

Parameters

-
    -
  1. a - number - angle of rotation, in degrees
  2. -
  3. x - number - horizontal origin point from which to rotate
  4. -
  5. y - number - vertical origin point from which to rotate
  6. - -
-
- - - - - - - -
-
-
- -
-
-

Matrix.x(x, y)

-
-
-
-
- - - - -

Returns x coordinate for given point after transformation described by the matrix. See also Matrix.y -

- - - - - - - - - - -
-

Parameters

-
    -
  1. x - number -
  2. -
  3. y - number -
  4. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - x -

- - - - -
-
-
- -
-
-

Matrix.y(x, y)

-
-
-
-
- - - - -

Returns y coordinate for given point after transformation described by the matrix. See also Matrix.x -

- - - - - - - - - - -
-

Parameters

-
    -
  1. x - number -
  2. -
  3. y - number -
  4. - -
-
- - - - - - - - - - - - - -

- Returns: - - number - - y -

- - - - -
-
-
- -
-
-

Matrix.determinant()

-
-
-
-
- - - - -

Finds determinant of the given matrix. -

- - - - - - - - - - - - - - -

- Returns: - - number - - determinant -

- - - - -
-
-
- -
-
-

Matrix.split()

-
-
-
-
- - - - -

Splits matrix into primitive transformations -

- - - - - - - - - - - - - - -

- Returns: - - object - - in format: -

- - - - - - - - - - - -
    - - -
  1. - dx - number - translation by x -
  2. - - - -
  3. - dy - number - translation by y -
  4. - - - -
  5. - scalex - number - scale by x -
  6. - - - -
  7. - scaley - number - scale by y -
  8. - - - -
  9. - shear - number - shear -
  10. - - - -
  11. - rotate - number - rotation in deg -
  12. - - - -
  13. - isSimple - boolean - could it be represented via simple transformations -
  14. - - -
- - -
-
-
- -
-
-

Matrix.toTransformString()

-
-
-
-
- - - - -

Returns transform string that represents given matrix -

- - - - - - - - - - - - - - -

- Returns: - - string - - transform string -

- - - - -
-
-
- -
-
-

Snap.Matrix()

-
-
-
-
- - - - -

Matrix constructor, extend on your own risk. -To create matrices use Snap.matrix. -

- - - - - - - - -
-
-
- -
-
-

Snap.matrix(…)

-
-
-
-
- - - - -

Utility method -Returns a matrix based on the given parameters -

- - - - - - - - - - -
-

Parameters

-
    -
  1. a - number -
  2. -
  3. b - number -
  4. -
  5. c - number -
  6. -
  7. d - number -
  8. -
  9. e - number -
  10. -
  11. f - number -
  12. - -
-
- - - - - - - - -

or -

- - - - - - - - - - -
-

Parameters

-
    -
  1. svgMatrix - SVGMatrix -
  2. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - Matrix -

- - - - -
-
-
- -
-
-

Paper.rect(x, y, width, height, [rx], [ry])

-
-
-
-
- - - - -

Draws a rectangle -

- - - - - - - - - - -
-

Parameters

-
    -
  1. x - number - x coordinate of the top left corner
  2. -
  3. y - number - y coordinate of the top left corner
  4. -
  5. width - number - width
  6. -
  7. height - number - height
  8. -
  9. rx - number - horizontal radius for rounded corners, default is 0
  10. -
  11. ry - number - vertical radius for rounded corners, default is rx or 0
  12. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - the rect element -

- - - - - - - - -

Usage

- - - - - - - - - - - -
// regular rectangle
+                            
+
+
+
+
+

Element.removeData([key]) + + +

+
+
+
+
+

Removes value associated with an element by given + key. If key is not provided, removes all the + data of the element. +

+
+

Parameters

+
    +
  1. + key + + string + + key +
  2. +
+
+

+ Returns: + object + + Element + +

+
+
+
+
+
+

Element.outerSVG() + + +

+
+
+
+
+

Returns SVG code for the element, equivalent to HTML's + outerHTML. +

+

See also + Element.innerSVG +

+

+ Returns: + string + SVG code for the element +

+
+
+
+ +
+
+

Element.innerSVG() + + +

+
+
+
+
+

Returns SVG code for the element's contents, + equivalent to HTML's innerHTML +

+

+ Returns: + string + SVG code for the element +

+
+
+
+ + +
+
+

Snap.deurl(value) + + +

+
+
+
+
+

Unwraps path from "url(<path>)". +

+
+

Parameters

+
    +
  1. + value + + string + + url path +
  2. +
+
+

+ Returns: + string + unwrapped path +

+
+
+
+
+
+

Snap.animation(attr, duration, [easing], [callback]) + + +

+
+
+
+
+

Creates an animation object +

+
+

Parameters

+
    +
  1. + attr + + object + + attributes of final destination +
  2. +
  3. + duration + + number + + duration of the animation, in milliseconds +
  4. +
  5. + easing + + function + + one of easing functions of + mina or custom one +
  6. +
  7. + callback + + function + + callback function that fires when animation + ends +
  8. +
+
+

+ Returns: + object + animation object +

+
+
+
+
+
+

Element.inAnim() + + +

+
+
+
+
+

Returns a set of animations that may be able to manipulate + the current element +

+

+ Returns: + object + in format: +

+
    +
  1. { +
      +
    1. + anim + + object + + animation object, +
    2. +
    3. + mina + + object + + + mina object, +
    4. +
    5. + curStatus + + number + + 0..1 — status of the animation: 0 + — just started, 1 — just finished, +
    6. +
    7. + status + + function + + gets or sets the status of the animation, +
    8. +
    9. + stop + + function + + stops the animation +
    10. +
    +
  2. +
  3. }
  4. +
+
+
+
+
+
+

Snap.animate(from, to, setter, duration, [easing], [callback]) + + +

+
+
+
+
+

Runs generic animation of one number into another + with a caring function +

+
+

Parameters

+
    +
  1. + from + + number + array + + number or array of numbers +
  2. +
  3. + to + + number + array + + number or array of numbers +
  4. +
  5. + setter + + function + + caring function that accepts one number + argument +
  6. +
  7. + duration + + number + + duration, in milliseconds +
  8. +
  9. + easing + + function + + easing function from + mina or custom +
  10. +
  11. + callback + + function + + callback function to execute when animation + ends +
  12. +
+
+

+ Returns: + object + animation object in + mina format +

+
    +
  1. { +
      +
    1. + id + + string + + animation id, consider it read-only, +
    2. +
    3. + duration + + function + + gets or sets the duration of the + animation, +
    4. +
    5. + easing + + function + + easing, +
    6. +
    7. + speed + + function + + gets or sets the speed of the animation, +
    8. +
    9. + status + + function + + gets or sets the status of the animation, +
    10. +
    11. + stop + + function + + stops the animation +
    12. +
    +
  2. +
  3. }
  4. +
+
var rect = Snap().rect(0, 0, 10, 10);
+Snap.animate(0, 10, function (val) {
+    rect.attr({
+        x: val
+    });
+}, 1000);
+// in given context is equivalent to
+rect.animate({x: 10}, 1000);
+
+
+
+
+
+

Element.stop() + + +

+
+
+
+
+

Stops all the animations for the current element +

+

+ Returns: + Element + the current element +

+
+
+
+
+
+

Element.animate(attrs, duration, [easing], [callback]) + + +

+
+
+
+
+

Animates the given attributes of the element +

+
+

Parameters

+
    +
  1. + attrs + + object + + key-value pairs of destination attributes +
  2. +
  3. + duration + + number + + duration of the animation in milliseconds +
  4. +
  5. + easing + + function + + easing function from + mina or custom +
  6. +
  7. + callback + + function + + callback function that executes when + the animation ends +
  8. +
+
+

+ Returns: + Element + the current element +

+
+
+
+
+
+

Matrix.add(…) + + +

+
+
+
+
+

Adds the given matrix to existing one +

+
+

Parameters

+
    +
  1. + a + + number + + +
  2. +
  3. + b + + number + + +
  4. +
  5. + c + + number + + +
  6. +
  7. + d + + number + + +
  8. +
  9. + e + + number + + +
  10. +
  11. + f + + number + + +
  12. +
+
+

or +

+
+

Parameters

+
    +
  1. + matrix + + object + + + Matrix + +
  2. +
+
+
+
+
+
+
+

Matrix.multLeft(…) + + +

+
+
+
+
+

Multiplies a passed affine transform to the left: + M * this. +

+
+

Parameters

+
    +
  1. + a + + number + + +
  2. +
  3. + b + + number + + +
  4. +
  5. + c + + number + + +
  6. +
  7. + d + + number + + +
  8. +
  9. + e + + number + + +
  10. +
  11. + f + + number + + +
  12. +
+
+

or +

+
+

Parameters

+
    +
  1. + matrix + + object + + + Matrix + +
  2. +
+
+
+
+
+
+
+

Matrix.invert() + + +

+
+
+
+
+

Returns an inverted version of the matrix +

+

+ Returns: + object + + Matrix + +

+
+
+
+
+
+

Matrix.clone() + + +

+
+
+
+
+

Returns a copy of the matrix +

+

+ Returns: + object + + Matrix + +

+
+
+
+
+
+

Matrix.translate(x, y) + + +

+
+
+
+
+

Translate the matrix +

+
+

Parameters

+
    +
  1. + x + + number + + horizontal offset distance +
  2. +
  3. + y + + number + + vertical offset distance +
  4. +
+
+
+
+
+
+
+

Matrix.scale(x, [y], [cx], [cy]) + + +

+
+
+
+
+

Scales the matrix +

+
+

Parameters

+
    +
  1. + x + + number + + amount to be scaled, with 1 resulting in no change +
  2. +
  3. + y + + number + + amount to scale along the vertical axis. + (Otherwise x applies + to both axes.) +
  4. +
  5. + cx + + number + + horizontal origin point from which to + scale +
  6. +
  7. + cy + + number + + vertical origin point from which to scale +
  8. +
+
+

Default cx, cy is the middle point of the element. +

+
+
+
+
+
+

Matrix.rotate(a, x, y) + + +

+
+
+
+
+

Rotates the matrix +

+
+

Parameters

+
    +
  1. + a + + number + + angle of rotation, in degrees +
  2. +
  3. + x + + number + + horizontal origin point from which to + rotate +
  4. +
  5. + y + + number + + vertical origin point from which to rotate +
  6. +
+
+
+
+
+
+
+

Matrix.skewX(x) + + +

+
+
+
+
+

Skews the matrix along the x-axis +

+
+

Parameters

+
    +
  1. + x + + number + + Angle to skew along the x-axis (in degrees). +
  2. +
+
+
+
+
+
+
+

Matrix.skewY(y) + + +

+
+
+
+
+

Skews the matrix along the y-axis +

+
+

Parameters

+
    +
  1. + y + + number + + Angle to skew along the y-axis (in degrees). +
  2. +
+
+
+
+
+
+
+

Matrix.skew(y, x) + + +

+
+
+
+
+

Skews the matrix +

+
+

Parameters

+
    +
  1. + y + + number + + Angle to skew along the y-axis (in degrees). +
  2. +
  3. + x + + number + + Angle to skew along the x-axis (in degrees). +
  4. +
+
+
+
+
+
+
+

Matrix.x(x, y) + + +

+
+
+
+
+

Returns x coordinate for given point after transformation + described by the matrix. See also + Matrix.y +

+
+

Parameters

+
    +
  1. + x + + number + + +
  2. +
  3. + y + + number + + +
  4. +
+
+

+ Returns: + number + x +

+
+
+
+
+
+

Matrix.y(x, y) + + +

+
+
+
+
+

Returns y coordinate for given point after transformation + described by the matrix. See also + Matrix.x +

+
+

Parameters

+
    +
  1. + x + + number + + +
  2. +
  3. + y + + number + + +
  4. +
+
+

+ Returns: + number + y +

+
+
+
+
+
+

Matrix.determinant() + + +

+
+
+
+
+

Finds determinant of the given matrix. +

+

+ Returns: + number + determinant +

+
+
+
+
+
+

Matrix.split() + + +

+
+
+
+
+

Splits matrix into primitive transformations +

+

+ Returns: + object + in format: +

+
    +
  1. + dx + + number + + translation by x +
  2. +
  3. + dy + + number + + translation by y +
  4. +
  5. + scalex + + number + + scale by x +
  6. +
  7. + scaley + + number + + scale by y +
  8. +
  9. + shear + + number + + shear +
  10. +
  11. + rotate + + number + + rotation in deg +
  12. +
  13. + isSimple + + boolean + + could it be represented via simple transformations +
  14. +
+
+
+
+
+
+

Matrix.toTransformString() + + +

+
+
+
+
+

Returns transform string that represents given matrix +

+

+ Returns: + string + transform string +

+
+
+
+
+
+

Snap.Matrix() + + +

+
+
+
+
+

Matrix constructor, extend on your own risk. To create + matrices use + Snap.matrix. +

+
+
+
+
+
+

Snap.matrix(…) + + +

+
+
+
+
+

Utility method Returns a matrix based on the given + parameters +

+
+

Parameters

+
    +
  1. + a + + number + + +
  2. +
  3. + b + + number + + +
  4. +
  5. + c + + number + + +
  6. +
  7. + d + + number + + +
  8. +
  9. + e + + number + + +
  10. +
  11. + f + + number + + +
  12. +
+
+

or +

+
+

Parameters

+
    +
  1. + svgMatrix + + SVGMatrix + + +
  2. +
+
+

+ Returns: + object + + Matrix + +

+
+
+
+
+
+

Paper.rect(x, y, width, height, [rx], [ry]) + + +

+
+
+
+
+

+

Draws a rectangle +

+
+

Parameters

+
    +
  1. + x + + number + + x coordinate of the top left corner +
  2. +
  3. + y + + number + + y coordinate of the top left corner +
  4. +
  5. + width + + number + + width +
  6. +
  7. + height + + number + + height +
  8. +
  9. + rx + + number + + horizontal radius for rounded corners, + default is 0 +
  10. +
  11. + ry + + number + + vertical radius for rounded corners, + default is rx or 0 +
  12. +
+
+

+ Returns: + object + the rect element +

+

Usage

+
// regular rectangle
 var c = paper.rect(10, 10, 50, 50);
 // rectangle with rounded corners
 var c = paper.rect(40, 40, 50, 50, 10);
- - - - - -
-
-
- -
-
-

Paper.circle(x, y, r)

-
-
-
-
- - - - -

Draws a circle -

- - - - - - - - - - -
-

Parameters

-
    -
  1. x - number - x coordinate of the centre
  2. -
  3. y - number - y coordinate of the centre
  4. -
  5. r - number - radius
  6. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - the circle element -

- - - - - - - - -

Usage

- - - - - - - - - - - -
var c = paper.circle(50, 50, 40);
- - - - - -
-
-
- -
-
-

Paper.image(src, x, y, width, height)

-
-
-
-
- - - - -

Places an image on the surface -

- - - - - - - - - - -
-

Parameters

-
    -
  1. src - string - URI of the source image
  2. -
  3. x - number - x offset position
  4. -
  5. y - number - y offset position
  6. -
  7. width - number - width of the image
  8. -
  9. height - number - height of the image
  10. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - the image element -

- - - - - -

or -

- - - - - - - - - - - - - - -

- Returns: - - object - - Snap element object with type image -

- - - - - - - - -

Usage

- - - - - - - - - - - -
var c = paper.image("apple.png", 10, 10, 80, 80);
- - - - - -
-
-
- -
-
-

Paper.ellipse(x, y, rx, ry)

-
-
-
-
- - - - -

Draws an ellipse -

- - - - - - - - - - -
-

Parameters

-
    -
  1. x - number - x coordinate of the centre
  2. -
  3. y - number - y coordinate of the centre
  4. -
  5. rx - number - horizontal radius
  6. -
  7. ry - number - vertical radius
  8. - -
-
- - - - - - - - - - - - - -

- Returns: - - object - - the ellipse element -

- - - - - - - - -

Usage

- - - - - - - - - - - -
var c = paper.ellipse(50, 50, 40, 20);
- - - - - -
-
-
- -
-
-

Paper.path([pathString])

-
-
-
-
- - - - -

Creates a <path> element using the given string as the path's definition -

- - - - - - - - - - -
-

Parameters

-
    -
  1. pathString - string - path string in SVG format
  2. - -
-
- - - - - - - - -

Path string consists of one-letter commands, followed by comma seprarated arguments in numerical form. Example: -

- - - - - - - - - - - - - -
"M10,20L30,40"
- - - - - - -

This example features two commands: M, with arguments (10, 20) and L with arguments (30, 40). Uppercase letter commands express coordinates in absolute terms, while lowercase commands express them in relative terms from the most recently declared coordinates. -

- - - - - - - - - - - -

Here is short list of commands available, for more details see SVG path string format or article about path strings at MDN.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CommandNameParameters
Mmoveto(x y)+
Zclosepath(none)
Llineto(x y)+
Hhorizontal linetox+
Vvertical linetoy+
Ccurveto(x1 y1 x2 y2 x y)+
Ssmooth curveto(x2 y2 x y)+
Qquadratic Bézier curveto(x1 y1 x y)+
Tsmooth quadratic Bézier curveto(x y)+
Aelliptical arc(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+
RCatmull-Rom curveto*x1 y1 (x y)+
- - - - - - - - - -

  • Catmull-Rom curveto is a not standard SVG command and added to make life easier.
  • -Note: there is a special case when a path consists of only three commands: M10,10R…z. In this case the path connects back to its starting point. -

    - - - - - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var c = paper.path("M10 10L90 90");
    +                            
    +
    +
    +
    +
    +

    Paper.circle(x, y, r) + + +

    +
    +
    +
    +
    +

    Draws a circle +

    +
    +

    Parameters

    +
      +
    1. + x + + number + + x coordinate of the centre +
    2. +
    3. + y + + number + + y coordinate of the centre +
    4. +
    5. + r + + number + + radius +
    6. +
    +
    +

    + Returns: + object + the circle element +

    +

    Usage

    +
    var c = paper.circle(50, 50, 40);
    +
    +
    +
    +
    +
    +

    Paper.image(src, x, y, width, height) + + +

    +
    +
    +
    +
    +

    Places an image on the surface +

    +
    +

    Parameters

    +
      +
    1. + src + + string + + URI of the source image +
    2. +
    3. + x + + number + + x offset position +
    4. +
    5. + y + + number + + y offset position +
    6. +
    7. + width + + number + + width of the image +
    8. +
    9. + height + + number + + height of the image +
    10. +
    +
    +

    + Returns: + object + the image element +

    +

    or +

    +

    + Returns: + object + Snap element object with type image +

    +

    Usage

    +
    var c = paper.image("apple.png", 10, 10, 80, 80);
    +
    +
    +
    +
    +
    +

    Paper.ellipse(x, y, rx, ry) + + +

    +
    +
    +
    +
    +

    Draws an ellipse +

    +
    +

    Parameters

    +
      +
    1. + x + + number + + x coordinate of the centre +
    2. +
    3. + y + + number + + y coordinate of the centre +
    4. +
    5. + rx + + number + + horizontal radius +
    6. +
    7. + ry + + number + + vertical radius +
    8. +
    +
    +

    + Returns: + object + the ellipse element +

    +

    Usage

    +
    var c = paper.ellipse(50, 50, 40, 20);
    +
    +
    +
    +
    +
    +

    Paper.path([pathString]) + + +

    +
    +
    +
    +
    +

    Creates a <path> element using + the given string as the path's definition +

    +
    +

    Parameters

    +
      +
    1. + pathString + + string + + path string in SVG format +
    2. +
    +
    +

    Path string consists of one-letter commands, followed + by comma seprarated arguments in numerical form. + Example: +

    +
    "M10,20L30,40"
    +

    This example features two commands: M, + with arguments (10, 20) and L with arguments (30, 40). Uppercase + letter commands express coordinates in absolute + terms, while lowercase commands express them + in relative terms from the most recently declared + coordinates. +

    +

    +

    Here is short list of commands available, for more + details see + SVG path string format or + article about path strings at MDN.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CommandNameParameters
    Mmoveto(x y)+
    Zclosepath(none)
    Llineto(x y)+
    Hhorizontal linetox+
    Vvertical linetoy+
    Ccurveto(x1 y1 x2 y2 x y)+
    Ssmooth curveto(x2 y2 x y)+
    Qquadratic Bézier curveto(x1 y1 x y)+
    Tsmooth quadratic Bézier curveto(x y)+
    Aelliptical arc(rx ry x-axis-rotation large-arc-flag + sweep-flag x y)+
    R + Catmull-Rom curveto*x1 y1 (x y)+
    +

    +

  • + Catmull-Rom curveto is a not standard + SVG command and added to make life easier.
  • + Note: there is a special case when a path consists of only three commands: M10,10R…z. + In this case the path connects back to its starting + point. +

    +

    Usage

    +
    var c = paper.path("M10 10L90 90");
     // draw a diagonal line:
     // move to 10,10, line to 90,90
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.g([varargs])

    -
    -
    -
    -
    - - - - -

    Creates a group element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. varargs - - elements to nest within the group
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the g element -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var c1 = paper.circle(),
    +                            
    +
    +
    +
    +
    +

    Paper.g([varargs]) + + +

    +
    +
    +
    +
    +

    Creates a group element +

    +
    +

    Parameters

    +
      +
    1. + varargs + + + + elements to nest within the group +
    2. +
    +
    +

    + Returns: + object + the g element +

    +

    Usage

    +
    var c1 = paper.circle(),
         c2 = paper.rect(),
         g = paper.g(c2, c1); // note that the order of elements is different
    - - - - - - -

    or -

    - - - - - - - - - - - - - -
    var c1 = paper.circle(),
    +                                

    or +

    +
    var c1 = paper.circle(),
         c2 = paper.rect(),
         g = paper.g();
     g.add(c2, c1);
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.group()

    -
    -
    -
    -
    - - - - -

    See Paper.g -

    - - - - - - - - -
    -
    -
    - -
    -
    -

    Paper.svg(x, y, width, height, vbx, vby, vbw, vbh)

    -
    -
    -
    -
    - - - - -

    Creates a nested SVG element. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number - optional X of the element
    2. -
    3. y - number - optional Y of the element
    4. -
    5. width - number - optional width of the element
    6. -
    7. height - number - optional height of the element
    8. -
    9. vbx - number - optional viewbox X
    10. -
    11. vby - number - optional viewbox Y
    12. -
    13. vbw - number - optional viewbox width
    14. -
    15. vbh - number - optional viewbox height
    16. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the svg element -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.mask()

    -
    -
    -
    -
    - - - - -

    Equivalent in behaviour to Paper.g, except it’s a mask. -

    - - - - - - - - - - - - - - -

    - Returns: - - object - - the mask element -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.ptrn(x, y, width, height, vbx, vby, vbw, vbh)

    -
    -
    -
    -
    - - - - -

    Equivalent in behaviour to Paper.g, except it’s a pattern. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number - optional X of the element
    2. -
    3. y - number - optional Y of the element
    4. -
    5. width - number - optional width of the element
    6. -
    7. height - number - optional height of the element
    8. -
    9. vbx - number - optional viewbox X
    10. -
    11. vby - number - optional viewbox Y
    12. -
    13. vbw - number - optional viewbox width
    14. -
    15. vbh - number - optional viewbox height
    16. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the pattern element -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.use(…)

    -
    -
    -
    -
    - - - - -

    Creates a <use> element. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. id - string - optional id of element to link
    2. - -
    -
    - - - - - - - - -

    or -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. id - Element - optional element to link
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the use element -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.symbol(vbx, vby, vbw, vbh)

    -
    -
    -
    -
    - - - - -

    Creates a <symbol> element. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. vbx - number - optional viewbox X
    2. -
    3. vby - number - optional viewbox Y
    4. -
    5. vbw - number - optional viewbox width
    6. -
    7. vbh - number - optional viewbox height
    8. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the symbol element -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.text(x, y, text)

    -
    -
    -
    -
    - - - - -

    Draws a text string -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number - x coordinate position
    2. -
    3. y - number - y coordinate position
    4. -
    5. text - string array - The text string to draw or array of strings to nest within separate <tspan> elements
    6. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the text element -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var t1 = paper.text(50, 50, "Snap");
    +                            
    +
    +
    +
    +
    +

    Paper.group() + + +

    +
    +
    +
    +
    +

    See + Paper.g +

    +
    +
    +
    +
    +
    +

    Paper.svg(x, y, width, height, vbx, vby, vbw, vbh) + + +

    +
    +
    +
    +
    +

    Creates a nested SVG element. +

    +
    +

    Parameters

    +
      +
    1. + x + + number + + + optional X of the element +
    2. +
    3. + y + + number + + + optional Y of the element +
    4. +
    5. + width + + number + + + optional width of the element +
    6. +
    7. + height + + number + + + optional height of the element +
    8. +
    9. + vbx + + number + + + optional viewbox X +
    10. +
    11. + vby + + number + + + optional viewbox Y +
    12. +
    13. + vbw + + number + + + optional viewbox width +
    14. +
    15. + vbh + + number + + + optional viewbox height +
    16. +
    +
    +

    + Returns: + object + the svg element +

    +
    +
    +
    +
    +
    +

    Paper.mask() + + +

    +
    +
    +
    +
    +

    Equivalent in behaviour to + Paper.g, except it’s a mask. +

    +

    + Returns: + object + the mask element +

    +
    +
    +
    +
    +
    +

    Paper.ptrn(x, y, width, height, vbx, vby, vbw, vbh) + + +

    +
    +
    +
    +
    +

    Equivalent in behaviour to + Paper.g, except it’s a pattern. +

    +
    +

    Parameters

    +
      +
    1. + x + + number + + + optional X of the element +
    2. +
    3. + y + + number + + + optional Y of the element +
    4. +
    5. + width + + number + + + optional width of the element +
    6. +
    7. + height + + number + + + optional height of the element +
    8. +
    9. + vbx + + number + + + optional viewbox X +
    10. +
    11. + vby + + number + + + optional viewbox Y +
    12. +
    13. + vbw + + number + + + optional viewbox width +
    14. +
    15. + vbh + + number + + + optional viewbox height +
    16. +
    +
    +

    + Returns: + object + the pattern element +

    +
    +
    +
    +
    +
    +

    Paper.use(…) + + +

    +
    +
    +
    +
    +

    Creates a <use> element. +

    +
    +

    Parameters

    +
      +
    1. + id + + string + + + optional id of element to link +
    2. +
    +
    +

    or +

    +
    +

    Parameters

    +
      +
    1. + id + + Element + + + optional element to link +
    2. +
    +
    +

    + Returns: + object + the use element +

    +
    +
    +
    +
    +
    +

    Paper.symbol(vbx, vby, vbw, vbh) + + +

    +
    +
    +
    +
    +

    Creates a <symbol> element. +

    +
    +

    Parameters

    +
      +
    1. + vbx + + number + + + optional viewbox X +
    2. +
    3. + vby + + number + + + optional viewbox Y +
    4. +
    5. + vbw + + number + + + optional viewbox width +
    6. +
    7. + vbh + + number + + + optional viewbox height +
    8. +
    +
    +

    + Returns: + object + the symbol element +

    +
    +
    +
    +
    +
    +

    Paper.text(x, y, text) + + +

    +
    +
    +
    +
    +

    Draws a text string +

    +
    +

    Parameters

    +
      +
    1. + x + + number + + x coordinate position +
    2. +
    3. + y + + number + + y coordinate position +
    4. +
    5. + text + + string + array + + The text string to draw or array of strings + to nest within separate <tspan> elements +
    6. +
    +
    +

    + Returns: + object + the text element +

    +

    Usage

    +
    var t1 = paper.text(50, 50, "Snap");
     var t2 = paper.text(50, 50, ["S","n","a","p"]);
     // Text path usage
     t1.attr({textpath: "M10,10L100,100"});
     // or
     var pth = paper.path("M10,10L100,100");
     t1.attr({textpath: pth});
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.line(x1, y1, x2, y2)

    -
    -
    -
    -
    - - - - -

    Draws a line -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x1 - number - x coordinate position of the start
    2. -
    3. y1 - number - y coordinate position of the start
    4. -
    5. x2 - number - x coordinate position of the end
    6. -
    7. y2 - number - y coordinate position of the end
    8. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the line element -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var t1 = paper.line(50, 50, 100, 100);
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.polyline(…)

    -
    -
    -
    -
    - - - - -

    Draws a polyline -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. points - array - array of points
    2. - -
    -
    - - - - - - - - -

    or -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. varargs - - points
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - the polyline element -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var p1 = paper.polyline([10, 10, 100, 100]);
    +                            
    +
    +
    +
    +
    +

    Paper.line(x1, y1, x2, y2) + + +

    +
    +
    +
    +
    +

    Draws a line +

    +
    +

    Parameters

    +
      +
    1. + x1 + + number + + x coordinate position of the start +
    2. +
    3. + y1 + + number + + y coordinate position of the start +
    4. +
    5. + x2 + + number + + x coordinate position of the end +
    6. +
    7. + y2 + + number + + y coordinate position of the end +
    8. +
    +
    +

    + Returns: + object + the line element +

    +

    Usage

    +
    var t1 = paper.line(50, 50, 100, 100);
    +
    +
    +
    +
    +
    +

    Paper.polyline(…) + + +

    +
    +
    +
    +
    +

    Draws a polyline +

    +
    +

    Parameters

    +
      +
    1. + points + + array + + array of points +
    2. +
    +
    +

    or +

    +
    +

    Parameters

    +
      +
    1. + varargs + + + + points +
    2. +
    +
    +

    + Returns: + object + the polyline element +

    +

    Usage

    +
    var p1 = paper.polyline([10, 10, 100, 100]);
     var p2 = paper.polyline(10, 10, 100, 100);
    - - - - - -
    -
    -
    - -
    -
    -

    Paper.polygon()

    -
    -
    -
    -
    - - - - -

    Draws a polygon. See Paper.polyline -

    - - - - - - - - -
    -
    -
    - -
    -
    -

    Paper.gradient(gradient)

    -
    -
    -
    -
    - - - - -

    Creates a gradient element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. gradient - string - gradient descriptor
    2. - -
    -
    - - - - - - - - - - - -

    Gradient Descriptor

    - - - - - - - -

    The gradient descriptor is an expression formatted as -follows: <type>(<coords>)<colors>. The <type> can be -either linear or radial. The uppercase L or R letters -indicate absolute coordinates offset from the SVG surface. -Lowercase l or r letters indicate coordinates -calculated relative to the element to which the gradient is -applied. Coordinates specify a linear gradient vector as -x1, y1, x2, y2, or a radial gradient as cx, cy, -r and optional fx, fy specifying a focal point away -from the center of the circle. Specify <colors> as a list -of dash-separated CSS color values. Each color may be -followed by a custom offset value, separated with a colon -character. -

    - - - - - - - - - - - - -

    Examples

    - - - - - - - -

    Linear gradient, relative from top-left corner to bottom-right -corner, from black through red to white: -

    - - - - - - - - - - - - - -
    var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff");
    - - - - - - -

    Linear gradient, absolute from (0, 0) to (100, 100), from black -through red at 25% to white: -

    - - - - - - - - - - - - - -
    var g = paper.gradient("L(0, 0, 100, 100)#000-#f00:25-#fff");
    - - - - - - -

    Radial gradient, relative from the center of the element with radius -half the width, from black to white: -

    - - - - - - - - - - - - - -
    var g = paper.gradient("r(0.5, 0.5, 0.5)#000-#fff");
    - - - - - - -

    To apply the gradient: -

    - - - - - - - - - - - - - -
    paper.circle(50, 50, 40).attr({
    +                            
    +
    +
    + +
    +
    +

    Element.stops() + + +

    +
    +
    +
    +
    +

    Only for gradients! Returns array of gradient stops + elements. +

    +

    + Returns: + array + the stops array. +

    +
    +
    +
    +
    +
    +

    Element.addStop(color, offset) + + +

    +
    +
    +
    +
    +

    Only for gradients! Adds another stop to the gradient. +

    +
    +

    Parameters

    +
      +
    1. + color + + string + + stops color +
    2. +
    3. + offset + + number + + stops offset 0..100 +
    4. +
    +
    +

    + Returns: + object + gradient element +

    +
    +
    +
    +
    +
    +

    Element.setStops(str) + + +

    +
    +
    +
    +
    +

    Only for gradients! Updates stops of the gradient + based on passed gradient descriptor. See + Ppaer.gradient +

    +
    +

    Parameters

    +
      +
    1. + str + + string + + gradient descriptor part after (). +
    2. +
    +
    +

    + Returns: + object + gradient element +

    +
    var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff");
    +g.setStops("#fff-#000-#f00-#fc0");
    +
    +
    +
    +
    +
    +

    Paper.gradient(gradient) + + +

    +
    +
    +
    +
    +

    Creates a gradient element +

    +
    +

    Parameters

    +
      +
    1. + gradient + + string + + gradient descriptor +
    2. +
    +
    +

    Gradient Descriptor

    +

    The gradient descriptor is an expression formatted + as follows: <type>(<coords>)<colors>. + The <type> can be either linear + or radial. The uppercase L or R letters indicate absolute coordinates offset + from the SVG surface. Lowercase l or r letters indicate coordinates + calculated relative to the element to which the + gradient is applied. Coordinates specify a linear + gradient vector as + x1, y1, x2, + y2, or a radial gradient as cx, + cy, + r and optional fx, + fy specifying a focal point away + from the center of the circle. Specify <colors> as a list of dash-separated CSS color values. + Each color may be followed by a custom offset + value, separated with a colon character. +

    +

    Examples

    +

    Linear gradient, relative from top-left corner to + bottom-right corner, from black through red to + white: +

    +
    var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff");
    +

    Linear gradient, absolute from (0, 0) to (100, 100), + from black through red at 25% to white: +

    +
    var g = paper.gradient("L(0, 0, 100, 100)#000-#f00:25-#fff");
    +

    Radial gradient, relative from the center of the + element with radius half the width, from black + to white: +

    +
    var g = paper.gradient("r(0.5, 0.5, 0.5)#000-#fff");
    +

    To apply the gradient: +

    +
    paper.circle(50, 50, 40).attr({
         fill: g
     });
    - - - - - - - - - - - -

    - Returns: - - object - - the gradient element -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.toString()

    -
    -
    -
    -
    - - - - -

    Returns SVG code for the Paper -

    - - - - - - - - - - - - - - -

    - Returns: - - string - - SVG code for the Paper -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.toDataURL()

    -
    -
    -
    -
    - - - - -

    Returns SVG code for the Paper as Data URI string. -

    - - - - - - - - - - - - - - -

    - Returns: - - string - - Data URI string -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.clear()

    -
    -
    -
    -
    - - - - -

    Removes all child nodes of the paper, except <defs>. -

    - - - - - - - - -
    -
    -
    - -
    -
    -

    Element.addClass(value)

    -
    -
    -
    -
    - - - - -

    Adds given class name or list of class names to the element. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. value - string - class name or space separated list of class names
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - Element - - original element. -

    - - - - -
    -
    -
    - -
    -
    -

    Element.removeClass(value)

    -
    -
    -
    -
    - - - - -

    Removes given class name or list of class names from the element. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. value - string - class name or space separated list of class names
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - Element - - original element. -

    - - - - -
    -
    -
    - -
    -
    -

    Element.hasClass(value)

    -
    -
    -
    -
    - - - - -

    Checks if the element has a given class name in the list of class names applied to it. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. value - string - class name
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - boolean - - true if the element has given class -

    - - - - -
    -
    -
    - -
    -
    -

    Element.toggleClass(value, flag)

    -
    -
    -
    -
    - - - - -

    Add or remove one or more classes from the element, depending on either -the class’s presence or the value of the flag argument. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. value - string - class name or space separated list of class names
    2. -
    3. flag - boolean - value to determine whether the class should be added or removed
    4. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - Element - - original element. -

    - - - - -
    -
    -
    - -
    -
    -

    mina(a, A, b, B, get, set, [easing])

    -
    -
    -
    -
    - - - - -

    Generic animation of numbers -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. a - number - start slave number
    2. -
    3. A - number - end slave number
    4. -
    5. b - number - start master number (start time in general case)
    6. -
    7. B - number - end master number (end time in gereal case)
    8. -
    9. get - function - getter of master number (see mina.time)
    10. -
    11. set - function - setter of slave number
    12. -
    13. easing - function - easing function, default is mina.linear
    14. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - animation descriptor -

    - - - - - - - - - - - -
      - - -
    1. {
        - - - -
      1. - id - string - animation id, -
      2. - - - -
      3. - start - number - start slave number, -
      4. - - - -
      5. - end - number - end slave number, -
      6. - - - -
      7. - b - number - start master number, -
      8. - - - -
      9. - s - number - animation status (0..1), -
      10. - - - -
      11. - dur - number - animation duration, -
      12. - - - -
      13. - spd - number - animation speed, -
      14. - - - -
      15. - get - function - getter of master number (see mina.time), -
      16. - - - -
      17. - set - function - setter of slave number, -
      18. - - - -
      19. - easing - function - easing function, default is mina.linear, -
      20. - - - -
      21. - status - function - status getter/setter, -
      22. - - - -
      23. - speed - function - speed getter/setter, -
      24. - - - -
      25. - duration - function - duration getter/setter, -
      26. - - - -
      27. - stop - function - animation stopper -
      28. - - - -
      29. - pause - function - pauses the animation -
      30. - - - -
      31. - resume - function - resumes the animation -
      32. - - - -
      33. - update - function - calles setter with the right value of the animation -
      34. - - - -
    2. }
    3. - - -
    - - -
    -
    -
    - -
    -
    -

    mina.time()

    -
    -
    -
    -
    - - - - -

    Returns the current time. Equivalent to: -

    - - - - - - - - - - - - - -
    function () {
    +                                

    + Returns: + object + the gradient element +

    +
    +
    +
    +
    +
    +

    Paper.toString() + + +

    +
    +
    +
    +
    +

    Returns SVG code for the + Paper +

    +

    + Returns: + string + SVG code for the + Paper + +

    +
    +
    +
    +
    +
    +

    Paper.toDataURL() + + +

    +
    +
    +
    +
    +

    Returns SVG code for the + Paper as Data URI string. +

    +

    + Returns: + string + Data URI string +

    +
    +
    +
    +
    +
    +

    Paper.clear() + + +

    +
    +
    +
    +
    +

    Removes all child nodes of the paper, except <defs>. +

    +
    +
    +
    +
    +
    +

    Element.addClass(value) + + +

    +
    +
    +
    +
    +

    Adds given class name or list of class names to the + element. +

    +
    +

    Parameters

    +
      +
    1. + value + + string + + class name or space separated list of + class names +
    2. +
    +
    +

    + Returns: + Element + original element. +

    +
    +
    +
    +
    +
    +

    Element.removeClass(value) + + +

    +
    +
    +
    +
    +

    Removes given class name or list of class names from + the element. +

    +
    +

    Parameters

    +
      +
    1. + value + + string + + class name or space separated list of + class names +
    2. +
    +
    +

    + Returns: + Element + original element. +

    +
    +
    +
    +
    +
    +

    Element.hasClass(value) + + +

    +
    +
    +
    +
    +

    Checks if the element has a given class name in the + list of class names applied to it. +

    +
    +

    Parameters

    +
      +
    1. + value + + string + + class name +
    2. +
    +
    +

    + Returns: + boolean + true if the element has given class +

    +
    +
    +
    +
    +
    +

    Element.toggleClass(value, flag) + + +

    +
    +
    +
    +
    +

    Add or remove one or more classes from the element, + depending on either the class’s presence or the + value of the flag argument. +

    +
    +

    Parameters

    +
      +
    1. + value + + string + + class name or space separated list of + class names +
    2. +
    3. + flag + + boolean + + value to determine whether the class + should be added or removed +
    4. +
    +
    +

    + Returns: + Element + original element. +

    +
    +
    +
    +
    +
    +

    mina(a, A, b, B, get, set, [easing]) + + +

    +
    +
    +
    +
    +

    Generic animation of numbers +

    +
    +

    Parameters

    +
      +
    1. + a + + number + + start + slave number +
    2. +
    3. + A + + number + + end + slave number +
    4. +
    5. + b + + number + + start + master number (start time in + general case) +
    6. +
    7. + B + + number + + end + master number (end time in general + case) +
    8. +
    9. + get + + function + + getter of + master number (see + mina.time) +
    10. +
    11. + set + + function + + setter of + slave number +
    12. +
    13. + easing + + function + + easing function, default is + mina.linear + +
    14. +
    +
    +

    + Returns: + object + animation descriptor +

    +
      +
    1. { +
        +
      1. + id + + string + + animation id, +
      2. +
      3. + start + + number + + start + slave number, +
      4. +
      5. + end + + number + + end + slave number, +
      6. +
      7. + b + + number + + start + master number, +
      8. +
      9. + s + + number + + animation status (0..1), +
      10. +
      11. + dur + + number + + animation duration, +
      12. +
      13. + spd + + number + + animation speed, +
      14. +
      15. + get + + function + + getter of + master number (see + mina.time), +
      16. +
      17. + set + + function + + setter of + slave number, +
      18. +
      19. + easing + + function + + easing function, default is + mina.linear, +
      20. +
      21. + status + + function + + status getter/setter, +
      22. +
      23. + speed + + function + + speed getter/setter, +
      24. +
      25. + duration + + function + + duration getter/setter, +
      26. +
      27. + stop + + function + + animation stopper +
      28. +
      29. + pause + + function + + pauses the animation +
      30. +
      31. + resume + + function + + resumes the animation +
      32. +
      33. + update + + function + + calles setter with the right value + of the animation +
      34. +
      +
    2. +
    3. }
    4. +
    +
    +
    +
    +
    +
    +

    mina.time() + + +

    +
    +
    +
    +
    +

    Returns the current time. Equivalent to: +

    +
    function () {
         return (new Date).getTime();
     }
    - - - - - -
    -
    -
    - -
    -
    -

    mina.getById(id)

    -
    -
    -
    -
    - - - - -

    Returns an animation by its id -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. id - string - animation's id
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - See mina -

    - - - - -
    -
    -
    - -
    -
    -

    mina.linear(n)

    -
    -
    -
    -
    - - - - -

    Default linear easing -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. n - number - input 0..1
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - number - - output 0..1 -

    - - - - -
    -
    -
    - -
    -
    -

    mina.easeout(n)

    -
    -
    -
    -
    - - - - -

    Easeout easing -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. n - number - input 0..1
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - number - - output 0..1 -

    - - - - -
    -
    -
    - -
    -
    -

    mina.easein(n)

    -
    -
    -
    -
    - - - - -

    Easein easing -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. n - number - input 0..1
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - number - - output 0..1 -

    - - - - -
    -
    -
    - -
    -
    -

    mina.easeinout(n)

    -
    -
    -
    -
    - - - - -

    Easeinout easing -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. n - number - input 0..1
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - number - - output 0..1 -

    - - - - -
    -
    -
    - -
    -
    -

    mina.backin(n)

    -
    -
    -
    -
    - - - - -

    Backin easing -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. n - number - input 0..1
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - number - - output 0..1 -

    - - - - -
    -
    -
    - -
    -
    -

    mina.backout(n)

    -
    -
    -
    -
    - - - - -

    Backout easing -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. n - number - input 0..1
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - number - - output 0..1 -

    - - - - -
    -
    -
    - -
    -
    -

    mina.elastic(n)

    -
    -
    -
    -
    - - - - -

    Elastic easing -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. n - number - input 0..1
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - number - - output 0..1 -

    - - - - -
    -
    -
    - -
    -
    -

    mina.bounce(n)

    -
    -
    -
    -
    - - - - -

    Bounce easing -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. n - number - input 0..1
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - number - - output 0..1 -

    - - - - -
    -
    -
    - -
    -
    -

    Paper.filter(filstr)

    -
    -
    -
    -
    - - - - -

    Creates a <filter> element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. filstr - string - SVG fragment of filter provided as a string
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - - -

    Note: It is recommended to use filters embedded into the page inside an empty SVG element. -

    - - - - - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var f = paper.filter(''),
    +                            
    +
    +
    +
    +
    +

    mina.getById(id) + + +

    +
    +
    +
    +
    +

    Returns an animation by its id +

    +
    +

    Parameters

    +
      +
    1. + id + + string + + animation's id +
    2. +
    +
    +

    + Returns: + object + See + mina + +

    +
    +
    +
    +
    +
    +

    mina.linear(n) + + +

    +
    +
    +
    +
    +

    Default linear easing +

    +
    +

    Parameters

    +
      +
    1. + n + + number + + input 0..1 +
    2. +
    +
    +

    + Returns: + number + output 0..1 +

    +
    +
    +
    +
    +
    +

    mina.easeout(n) + + +

    +
    +
    +
    +
    +

    Easeout easing +

    +
    +

    Parameters

    +
      +
    1. + n + + number + + input 0..1 +
    2. +
    +
    +

    + Returns: + number + output 0..1 +

    +
    +
    +
    +
    +
    +

    mina.easein(n) + + +

    +
    +
    +
    +
    +

    Easein easing +

    +
    +

    Parameters

    +
      +
    1. + n + + number + + input 0..1 +
    2. +
    +
    +

    + Returns: + number + output 0..1 +

    +
    +
    +
    +
    +
    +

    mina.easeinout(n) + + +

    +
    +
    +
    +
    +

    Easeinout easing +

    +
    +

    Parameters

    +
      +
    1. + n + + number + + input 0..1 +
    2. +
    +
    +

    + Returns: + number + output 0..1 +

    +
    +
    +
    +
    +
    +

    mina.backin(n) + + +

    +
    +
    +
    +
    +

    Backin easing +

    +
    +

    Parameters

    +
      +
    1. + n + + number + + input 0..1 +
    2. +
    +
    +

    + Returns: + number + output 0..1 +

    +
    +
    +
    +
    +
    +

    mina.backout(n) + + +

    +
    +
    +
    +
    +

    Backout easing +

    +
    +

    Parameters

    +
      +
    1. + n + + number + + input 0..1 +
    2. +
    +
    +

    + Returns: + number + output 0..1 +

    +
    +
    +
    +
    +
    +

    mina.elastic(n) + + +

    +
    +
    +
    +
    +

    Elastic easing +

    +
    +

    Parameters

    +
      +
    1. + n + + number + + input 0..1 +
    2. +
    +
    +

    + Returns: + number + output 0..1 +

    +
    +
    +
    +
    +
    +

    mina.bounce(n) + + +

    +
    +
    +
    +
    +

    Bounce easing +

    +
    +

    Parameters

    +
      +
    1. + n + + number + + input 0..1 +
    2. +
    +
    +

    + Returns: + number + output 0..1 +

    +
    +
    +
    +
    +
    +

    Paper.filter(filstr) + + +

    +
    +
    +
    +
    +

    Creates a <filter> element +

    +
    +

    Parameters

    +
      +
    1. + filstr + + string + + SVG fragment of filter provided as a + string +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +

    Note: It is recommended to use filters embedded into + the page inside an empty SVG element. +

    +

    Usage

    +
    var f = paper.filter(''),
         c = paper.circle(10, 10, 10).attr({
             filter: f
         });
    - - - - - -
    -
    -
    - -
    -
    -

    Snap.filter.blur(x, [y])

    -
    -
    -
    -
    - - - - -

    Returns an SVG markup string for the blur filter -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. x - number - amount of horizontal blur, in pixels
    2. -
    3. y - number - amount of vertical blur, in pixels
    4. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - string - - filter representation -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var f = paper.filter(Snap.filter.blur(5, 10)),
    +                            
    +
    +
    +
    +
    +

    Snap.filter.blur(x, [y]) + + +

    +
    +
    +
    +
    +

    Returns an SVG markup string for the blur filter +

    +
    +

    Parameters

    +
      +
    1. + x + + number + + amount of horizontal blur, in pixels +
    2. +
    3. + y + + number + + amount of vertical blur, in pixels +
    4. +
    +
    +

    + Returns: + string + filter representation +

    +

    Usage

    +
    var f = paper.filter(Snap.filter.blur(5, 10)),
         c = paper.circle(10, 10, 10).attr({
             filter: f
         });
    - - - - - -
    -
    -
    - -
    -
    -

    Snap.filter.shadow(…)

    -
    -
    -
    -
    - - - - -

    Returns an SVG markup string for the shadow filter -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. dx - number - horizontal shift of the shadow, in pixels
    2. -
    3. dy - number - vertical shift of the shadow, in pixels
    4. -
    5. blur - number - amount of blur
    6. -
    7. color - string - color of the shadow
    8. -
    9. opacity - number - 0..1 opacity of the shadow
    10. - -
    -
    - - - - - - - - -

    or -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. dx - number - horizontal shift of the shadow, in pixels
    2. -
    3. dy - number - vertical shift of the shadow, in pixels
    4. -
    5. color - string - color of the shadow
    6. -
    7. opacity - number - 0..1 opacity of the shadow
    8. - -
    -
    - - - - - - - - -

    which makes blur default to 4. Or -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. dx - number - horizontal shift of the shadow, in pixels
    2. -
    3. dy - number - vertical shift of the shadow, in pixels
    4. -
    5. opacity - number - 0..1 opacity of the shadow
    6. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - string - - filter representation -

    - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    var f = paper.filter(Snap.filter.shadow(0, 2, 3)),
    +                            
    +
    +
    +
    +
    +

    Snap.filter.shadow(…) + + +

    +
    +
    +
    +
    +

    Returns an SVG markup string for the shadow filter +

    +
    +

    Parameters

    +
      +
    1. + dx + + number + + horizontal shift of the shadow, in pixels +
    2. +
    3. + dy + + number + + vertical shift of the shadow, in pixels +
    4. +
    5. + blur + + number + + amount of blur +
    6. +
    7. + color + + string + + color of the shadow +
    8. +
    9. + opacity + + number + + 0..1 opacity of the shadow +
    10. +
    +
    +

    or +

    +
    +

    Parameters

    +
      +
    1. + dx + + number + + horizontal shift of the shadow, in pixels +
    2. +
    3. + dy + + number + + vertical shift of the shadow, in pixels +
    4. +
    5. + color + + string + + color of the shadow +
    6. +
    7. + opacity + + number + + 0..1 opacity of the shadow +
    8. +
    +
    +

    which makes blur default to 4. Or +

    +
    +

    Parameters

    +
      +
    1. + dx + + number + + horizontal shift of the shadow, in pixels +
    2. +
    3. + dy + + number + + vertical shift of the shadow, in pixels +
    4. +
    5. + opacity + + number + + 0..1 opacity of the shadow +
    6. +
    +
    +

    + Returns: + string + filter representation +

    +

    Usage

    +
    var f = paper.filter(Snap.filter.shadow(0, 2, .3)),
         c = paper.circle(10, 10, 10).attr({
             filter: f
         });
    - - - - - -
    -
    -
    - -
    -
    -

    Snap.filter.grayscale(amount)

    -
    -
    -
    -
    - - - - -

    Returns an SVG markup string for the grayscale filter -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. amount - number - amount of filter (0..1)
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - string - - filter representation -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.filter.sepia(amount)

    -
    -
    -
    -
    - - - - -

    Returns an SVG markup string for the sepia filter -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. amount - number - amount of filter (0..1)
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - string - - filter representation -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.filter.saturate(amount)

    -
    -
    -
    -
    - - - - -

    Returns an SVG markup string for the saturate filter -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. amount - number - amount of filter (0..1)
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - string - - filter representation -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.filter.hueRotate(angle)

    -
    -
    -
    -
    - - - - -

    Returns an SVG markup string for the hue-rotate filter -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. angle - number - angle of rotation
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - string - - filter representation -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.filter.invert(amount)

    -
    -
    -
    -
    - - - - -

    Returns an SVG markup string for the invert filter -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. amount - number - amount of filter (0..1)
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - string - - filter representation -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.filter.brightness(amount)

    -
    -
    -
    -
    - - - - -

    Returns an SVG markup string for the brightness filter -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. amount - number - amount of filter (0..1)
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - string - - filter representation -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.filter.contrast(amount)

    -
    -
    -
    -
    - - - - -

    Returns an SVG markup string for the contrast filter -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. amount - number - amount of filter (0..1)
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - string - - filter representation -

    - - - - -
    -
    -
    - -
    -
    -

    Element.click(handler)

    -
    -
    -
    -
    - - - - -

    Adds a click event handler to the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.unclick(handler)

    -
    -
    -
    -
    - - - - -

    Removes a click event handler from the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.dblclick(handler)

    -
    -
    -
    -
    - - - - -

    Adds a double click event handler to the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.undblclick(handler)

    -
    -
    -
    -
    - - - - -

    Removes a double click event handler from the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.mousedown(handler)

    -
    -
    -
    -
    - - - - -

    Adds a mousedown event handler to the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.unmousedown(handler)

    -
    -
    -
    -
    - - - - -

    Removes a mousedown event handler from the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.mousemove(handler)

    -
    -
    -
    -
    - - - - -

    Adds a mousemove event handler to the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.unmousemove(handler)

    -
    -
    -
    -
    - - - - -

    Removes a mousemove event handler from the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.mouseout(handler)

    -
    -
    -
    -
    - - - - -

    Adds a mouseout event handler to the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.unmouseout(handler)

    -
    -
    -
    -
    - - - - -

    Removes a mouseout event handler from the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.mouseover(handler)

    -
    -
    -
    -
    - - - - -

    Adds a mouseover event handler to the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.unmouseover(handler)

    -
    -
    -
    -
    - - - - -

    Removes a mouseover event handler from the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.mouseup(handler)

    -
    -
    -
    -
    - - - - -

    Adds a mouseup event handler to the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.unmouseup(handler)

    -
    -
    -
    -
    - - - - -

    Removes a mouseup event handler from the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.touchstart(handler)

    -
    -
    -
    -
    - - - - -

    Adds a touchstart event handler to the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.untouchstart(handler)

    -
    -
    -
    -
    - - - - -

    Removes a touchstart event handler from the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.touchmove(handler)

    -
    -
    -
    -
    - - - - -

    Adds a touchmove event handler to the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.untouchmove(handler)

    -
    -
    -
    -
    - - - - -

    Removes a touchmove event handler from the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.touchend(handler)

    -
    -
    -
    -
    - - - - -

    Adds a touchend event handler to the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.untouchend(handler)

    -
    -
    -
    -
    - - - - -

    Removes a touchend event handler from the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.touchcancel(handler)

    -
    -
    -
    -
    - - - - -

    Adds a touchcancel event handler to the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.untouchcancel(handler)

    -
    -
    -
    -
    - - - - -

    Removes a touchcancel event handler from the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. handler - function - handler for the event
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.hover(f_in, f_out, [icontext], [ocontext])

    -
    -
    -
    -
    - - - - -

    Adds hover event handlers to the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. f_in - function - handler for hover in
    2. -
    3. f_out - function - handler for hover out
    4. -
    5. icontext - object - context for hover in handler
    6. -
    7. ocontext - object - context for hover out handler
    8. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.unhover(f_in, f_out)

    -
    -
    -
    -
    - - - - -

    Removes hover event handlers from the element -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. f_in - function - handler for hover in
    2. -
    3. f_out - function - handler for hover out
    4. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.drag(onmove, onstart, onend, [mcontext], [scontext], [econtext])

    -
    -
    -
    -
    - - - - -

    Adds event handlers for an element's drag gesture -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. onmove - function - handler for moving
    2. -
    3. onstart - function - handler for drag start
    4. -
    5. onend - function - handler for drag end
    6. -
    7. mcontext - object - context for moving handler
    8. -
    9. scontext - object - context for drag start handler
    10. -
    11. econtext - object - context for drag end handler
    12. - -
    -
    - - - - - - - - -

    Additionaly following drag events are triggered: drag.start.<id> on start, -drag.end.<id> on end and drag.move.<id> on every move. When element is dragged over another element -drag.over.<id> fires as well. -

    Start event and start handler are called in specified context or in context of the element with following parameters: -

    - - - - - - - - - - - - - - - -
      - - -
    1. - x - number - x position of the mouse -
    2. - - - -
    3. - y - number - y position of the mouse -
    4. - - - -
    5. - event - object - DOM event object -
    6. - - -
    - - - -

    Move event and move handler are called in specified context or in context of the element with following parameters: -

    - - - - - - - - - - - - - - - -
      - - -
    1. - dx - number - shift by x from the start point -
    2. - - - -
    3. - dy - number - shift by y from the start point -
    4. - - - -
    5. - x - number - x position of the mouse -
    6. - - - -
    7. - y - number - y position of the mouse -
    8. - - - -
    9. - event - object - DOM event object -
    10. - - -
    - - - -

    End event and end handler are called in specified context or in context of the element with following parameters: -

    - - - - - - - - - - - - - - - -
      - - -
    1. - event - object - DOM event object -
    2. - - -
    - - - - - - - - -

    - Returns: - - object - - Element -

    - - - - -
    -
    -
    - -
    -
    -

    Element.undrag()

    -
    -
    -
    -
    - - - - -

    Removes all drag event handlers from the given element -

    - - - - - - - - -
    -
    -
    - -
    -
    -

    Snap.path.getTotalLength(path)

    -
    -
    -
    -
    - - - - -

    Returns the length of the given path in pixels -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. path - string - SVG path string
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - number - - length -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.path.getPointAtLength(path, length)

    -
    -
    -
    -
    - - - - -

    Returns the coordinates of the point located at the given length along the given path -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. path - string - SVG path string
    2. -
    3. length - number - length, in pixels, from the start of the path, excluding non-rendering jumps
    4. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - representation of the point: -

    - - - - - - - - - - - -
      - - -
    1. {
        - - - -
      1. - x: - number - x coordinate, -
      2. - - - -
      3. - y: - number - y coordinate, -
      4. - - - -
      5. - alpha: - number - angle of derivative -
      6. - - - -
    2. }
    3. - - -
    - - -
    -
    -
    - -
    -
    -

    Snap.path.getSubpath(path, from, to)

    -
    -
    -
    -
    - - - - -

    Returns the subpath of a given path between given start and end lengths -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. path - string - SVG path string
    2. -
    3. from - number - length, in pixels, from the start of the path to the start of the segment
    4. -
    5. to - number - length, in pixels, from the start of the path to the end of the segment
    6. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - string - - path string definition for the segment -

    - - - - -
    -
    -
    - -
    -
    -

    Element.getTotalLength()

    -
    -
    -
    -
    - - - - -

    Returns the length of the path in pixels (only works for path elements) -

    - - - - - - - - - - - - - - -

    - Returns: - - number - - length -

    - - - - -
    -
    -
    - -
    -
    -

    Element.getPointAtLength(length)

    -
    -
    -
    -
    - - - - -

    Returns coordinates of the point located at the given length on the given path (only works for path elements) -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. length - number - length, in pixels, from the start of the path, excluding non-rendering jumps
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - representation of the point: -

    - - - - - - - - - - - -
      - - -
    1. {
        - - - -
      1. - x: - number - x coordinate, -
      2. - - - -
      3. - y: - number - y coordinate, -
      4. - - - -
      5. - alpha: - number - angle of derivative -
      6. - - - -
    2. }
    3. - - -
    - - -
    -
    -
    - -
    -
    -

    Element.getSubpath(from, to)

    -
    -
    -
    -
    - - - - -

    Returns subpath of a given element from given start and end lengths (only works for path elements) -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. from - number - length, in pixels, from the start of the path to the start of the segment
    2. -
    3. to - number - length, in pixels, from the start of the path to the end of the segment
    4. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - string - - path string definition for the segment -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.path.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t)

    -
    -
    -
    -
    - - - - -

    Utility method -Finds dot coordinates on the given cubic beziér curve at the given t -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. p1x - number - x of the first point of the curve
    2. -
    3. p1y - number - y of the first point of the curve
    4. -
    5. c1x - number - x of the first anchor of the curve
    6. -
    7. c1y - number - y of the first anchor of the curve
    8. -
    9. c2x - number - x of the second anchor of the curve
    10. -
    11. c2y - number - y of the second anchor of the curve
    12. -
    13. p2x - number - x of the second point of the curve
    14. -
    15. p2y - number - y of the second point of the curve
    16. -
    17. t - number - position on the curve (0..1)
    18. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - point information in format: -

    - - - - - - - - - - - -
      - - -
    1. {
        - - - -
      1. - x: - number - x coordinate of the point, -
      2. - - - -
      3. - y: - number - y coordinate of the point, -
      4. - - - -
      5. m: {
          - - - -
        1. - x: - number - x coordinate of the left anchor, -
        2. - - - -
        3. - y: - number - y coordinate of the left anchor -
        4. - - - -
      6. },
      7. - - - -
      8. n: {
          - - - -
        1. - x: - number - x coordinate of the right anchor, -
        2. - - - -
        3. - y: - number - y coordinate of the right anchor -
        4. - - - -
      9. },
      10. - - - -
      11. start: {
          - - - -
        1. - x: - number - x coordinate of the start of the curve, -
        2. - - - -
        3. - y: - number - y coordinate of the start of the curve -
        4. - - - -
      12. },
      13. - - - -
      14. end: {
          - - - -
        1. - x: - number - x coordinate of the end of the curve, -
        2. - - - -
        3. - y: - number - y coordinate of the end of the curve -
        4. - - - -
      15. },
      16. - - - -
      17. - alpha: - number - angle of the curve derivative at the point -
      18. - - - -
    2. }
    3. - - -
    - - -
    -
    -
    - -
    -
    -

    Snap.path.bezierBBox(…)

    -
    -
    -
    -
    - - - - -

    Utility method -Returns the bounding box of a given cubic beziér curve -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. p1x - number - x of the first point of the curve
    2. -
    3. p1y - number - y of the first point of the curve
    4. -
    5. c1x - number - x of the first anchor of the curve
    6. -
    7. c1y - number - y of the first anchor of the curve
    8. -
    9. c2x - number - x of the second anchor of the curve
    10. -
    11. c2y - number - y of the second anchor of the curve
    12. -
    13. p2x - number - x of the second point of the curve
    14. -
    15. p2y - number - y of the second point of the curve
    16. - -
    -
    - - - - - - - - -

    or -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. bez - array - array of six points for beziér curve
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - bounding box -

    - - - - - - - - - - - -
      - - -
    1. {
        - - - -
      1. - x: - number - x coordinate of the left top point of the box, -
      2. - - - -
      3. - y: - number - y coordinate of the left top point of the box, -
      4. - - - -
      5. - x2: - number - x coordinate of the right bottom point of the box, -
      6. - - - -
      7. - y2: - number - y coordinate of the right bottom point of the box, -
      8. - - - -
      9. - width: - number - width of the box, -
      10. - - - -
      11. - height: - number - height of the box -
      12. - - - -
    2. }
    3. - - -
    - - -
    -
    -
    - -
    -
    -

    Snap.path.isPointInsideBBox(bbox, x, y)

    -
    -
    -
    -
    - - - - -

    Utility method -Returns true if given point is inside bounding box -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. bbox - string - bounding box
    2. -
    3. x - string - x coordinate of the point
    4. -
    5. y - string - y coordinate of the point
    6. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - boolean - - true if point is inside -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.path.isBBoxIntersect(bbox1, bbox2)

    -
    -
    -
    -
    - - - - -

    Utility method -Returns true if two bounding boxes intersect -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. bbox1 - string - first bounding box
    2. -
    3. bbox2 - string - second bounding box
    4. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - boolean - - true if bounding boxes intersect -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.path.intersection(path1, path2)

    -
    -
    -
    -
    - - - - -

    Utility method -Finds intersections of two paths -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. path1 - string - path string
    2. -
    3. path2 - string - path string
    4. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - array - - dots of intersection -

    - - - - - - - - - - - -
      - - -
    1. [
    2. - - - -
    3. {
        - - - -
      1. - x: - number - x coordinate of the point, -
      2. - - - -
      3. - y: - number - y coordinate of the point, -
      4. - - - -
      5. - t1: - number - t value for segment of path1, -
      6. - - - -
      7. - t2: - number - t value for segment of path2, -
      8. - - - -
      9. - segment1: - number - order number for segment of path1, -
      10. - - - -
      11. - segment2: - number - order number for segment of path2, -
      12. - - - -
      13. - bez1: - array - eight coordinates representing beziér curve for the segment of path1, -
      14. - - - -
      15. - bez2: - array - eight coordinates representing beziér curve for the segment of path2 -
      16. - - - -
    4. }
    5. - - - -
    6. ]
    7. - - -
    - - -
    -
    -
    - -
    -
    -

    Snap.path.isPointInside(path, x, y)

    -
    -
    -
    -
    - - - - -

    Utility method -Returns true if given point is inside a given closed path. -

    Note: fill mode doesn’t affect the result of this method. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. path - string - path string
    2. -
    3. x - number - x of the point
    4. -
    5. y - number - y of the point
    6. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - boolean - - true if point is inside the path -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.path.getBBox(path)

    -
    -
    -
    -
    - - - - -

    Utility method -Returns the bounding box of a given path -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. path - string - path string
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - bounding box -

    - - - - - - - - - - - -
      - - -
    1. {
        - - - -
      1. - x: - number - x coordinate of the left top point of the box, -
      2. - - - -
      3. - y: - number - y coordinate of the left top point of the box, -
      4. - - - -
      5. - x2: - number - x coordinate of the right bottom point of the box, -
      6. - - - -
      7. - y2: - number - y coordinate of the right bottom point of the box, -
      8. - - - -
      9. - width: - number - width of the box, -
      10. - - - -
      11. - height: - number - height of the box -
      12. - - - -
    2. }
    3. - - -
    - - -
    -
    -
    - -
    -
    -

    Snap.path.toRelative(path)

    -
    -
    -
    -
    - - - - -

    Utility method -Converts path coordinates into relative values -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. path - string - path string
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - array - - path string -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.path.toAbsolute(path)

    -
    -
    -
    -
    - - - - -

    Utility method -Converts path coordinates into absolute values -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. path - string - path string
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - array - - path string -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.path.toCubic(pathString)

    -
    -
    -
    -
    - - - - -

    Utility method -Converts path to a new path where all segments are cubic beziér curves -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. pathString - string array - path string or array of segments
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - array - - array of segments -

    - - - - -
    -
    -
    - -
    -
    -

    Snap.path.map(path, matrix)

    -
    -
    -
    -
    - - - - -

    Transform the path string with the given matrix -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. path - string - path string
    2. -
    3. matrix - object - see Matrix
    4. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - string - - transformed path string -

    - - - - -
    -
    -
    - -
    -
    -

    Set.push()

    -
    -
    -
    -
    - - - - -

    Adds each argument to the current set -

    - - - - - - - - - - - - - - -

    - Returns: - - object - - original element -

    - - - - -
    -
    -
    - -
    -
    -

    Set.pop()

    -
    -
    -
    -
    - - - - -

    Removes last element and returns it -

    - - - - - - - - - - - - - - -

    - Returns: - - object - - element -

    - - - - -
    -
    -
    - -
    -
    -

    Set.forEach(callback, thisArg)

    -
    -
    -
    -
    - - - - -

    Executes given function for each element in the set -

    If the function returns false, the loop stops running. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. callback - function - function to run
    2. -
    3. thisArg - object - context object for the callback
    4. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Set object -

    - - - - -
    -
    -
    - -
    -
    -

    Set.animate(…)

    -
    -
    -
    -
    - - - - -

    Animates each element in set in sync. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. attrs - object - key-value pairs of destination attributes
    2. -
    3. duration - number - duration of the animation in milliseconds
    4. -
    5. easing - function - easing function from mina or custom
    6. -
    7. callback - function - callback function that executes when the animation ends
    8. - -
    -
    - - - - - - - - -

    or -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. animation - array - array of animation parameter for each element in set in format [attrs, duration, easing, callback]
    2. - -
    -
    - - - - - - - - - - - -

    Usage

    - - - - - - - - - - - -
    // animate all elements in set to radius 10
    +                            
    +
    +
    +
    +
    +

    Snap.filter.grayscale(amount) + + +

    +
    +
    +
    +
    +

    Returns an SVG markup string for the grayscale filter +

    +
    +

    Parameters

    +
      +
    1. + amount + + number + + amount of filter (0..1) +
    2. +
    +
    +

    + Returns: + string + filter representation +

    +
    +
    +
    +
    +
    +

    Snap.filter.sepia(amount) + + +

    +
    +
    +
    +
    +

    Returns an SVG markup string for the sepia filter +

    +
    +

    Parameters

    +
      +
    1. + amount + + number + + amount of filter (0..1) +
    2. +
    +
    +

    + Returns: + string + filter representation +

    +
    +
    +
    +
    +
    +

    Snap.filter.saturate(amount) + + +

    +
    +
    +
    +
    +

    Returns an SVG markup string for the saturate filter +

    +
    +

    Parameters

    +
      +
    1. + amount + + number + + amount of filter (0..1) +
    2. +
    +
    +

    + Returns: + string + filter representation +

    +
    +
    +
    +
    +
    +

    Snap.filter.hueRotate(angle) + + +

    +
    +
    +
    +
    +

    Returns an SVG markup string for the hue-rotate filter +

    +
    +

    Parameters

    +
      +
    1. + angle + + number + + angle of rotation +
    2. +
    +
    +

    + Returns: + string + filter representation +

    +
    +
    +
    +
    +
    +

    Snap.filter.invert(amount) + + +

    +
    +
    +
    +
    +

    Returns an SVG markup string for the invert filter +

    +
    +

    Parameters

    +
      +
    1. + amount + + number + + amount of filter (0..1) +
    2. +
    +
    +

    + Returns: + string + filter representation +

    +
    +
    +
    +
    +
    +

    Snap.filter.brightness(amount) + + +

    +
    +
    +
    +
    +

    Returns an SVG markup string for the brightness filter +

    +
    +

    Parameters

    +
      +
    1. + amount + + number + + amount of filter (0..1) +
    2. +
    +
    +

    + Returns: + string + filter representation +

    +
    +
    +
    +
    +
    +

    Snap.filter.contrast(amount) + + +

    +
    +
    +
    +
    +

    Returns an SVG markup string for the contrast filter +

    +
    +

    Parameters

    +
      +
    1. + amount + + number + + amount of filter (0..1) +
    2. +
    +
    +

    + Returns: + string + filter representation +

    +
    +
    +
    +
    +
    +

    Element.click(handler) + + +

    +
    +
    +
    +
    +

    Adds a click event handler to the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.unclick(handler) + + +

    +
    +
    +
    +
    +

    Removes a click event handler from the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.dblclick(handler) + + +

    +
    +
    +
    +
    +

    Adds a double click event handler to the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.undblclick(handler) + + +

    +
    +
    +
    +
    +

    Removes a double click event handler from the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.mousedown(handler) + + +

    +
    +
    +
    +
    +

    Adds a mousedown event handler to the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.unmousedown(handler) + + +

    +
    +
    +
    +
    +

    Removes a mousedown event handler from the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.mousemove(handler) + + +

    +
    +
    +
    +
    +

    Adds a mousemove event handler to the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.unmousemove(handler) + + +

    +
    +
    +
    +
    +

    Removes a mousemove event handler from the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.mouseout(handler) + + +

    +
    +
    +
    +
    +

    Adds a mouseout event handler to the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.unmouseout(handler) + + +

    +
    +
    +
    +
    +

    Removes a mouseout event handler from the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.mouseover(handler) + + +

    +
    +
    +
    +
    +

    Adds a mouseover event handler to the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.unmouseover(handler) + + +

    +
    +
    +
    +
    +

    Removes a mouseover event handler from the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.mouseup(handler) + + +

    +
    +
    +
    +
    +

    Adds a mouseup event handler to the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.unmouseup(handler) + + +

    +
    +
    +
    +
    +

    Removes a mouseup event handler from the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.touchstart(handler) + + +

    +
    +
    +
    +
    +

    Adds a touchstart event handler to the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.untouchstart(handler) + + +

    +
    +
    +
    +
    +

    Removes a touchstart event handler from the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.touchmove(handler) + + +

    +
    +
    +
    +
    +

    Adds a touchmove event handler to the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.untouchmove(handler) + + +

    +
    +
    +
    +
    +

    Removes a touchmove event handler from the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.touchend(handler) + + +

    +
    +
    +
    +
    +

    Adds a touchend event handler to the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.untouchend(handler) + + +

    +
    +
    +
    +
    +

    Removes a touchend event handler from the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.touchcancel(handler) + + +

    +
    +
    +
    +
    +

    Adds a touchcancel event handler to the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.untouchcancel(handler) + + +

    +
    +
    +
    +
    +

    Removes a touchcancel event handler from the element +

    +
    +

    Parameters

    +
      +
    1. + handler + + function + + handler for the event +
    2. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.hover(f_in, f_out, [icontext], [ocontext]) + + +

    +
    +
    +
    +
    +

    Adds hover event handlers to the element +

    +
    +

    Parameters

    +
      +
    1. + f_in + + function + + handler for hover in +
    2. +
    3. + f_out + + function + + handler for hover out +
    4. +
    5. + icontext + + object + + context for hover in handler +
    6. +
    7. + ocontext + + object + + context for hover out handler +
    8. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.unhover(f_in, f_out) + + +

    +
    +
    +
    +
    +

    Removes hover event handlers from the element +

    +
    +

    Parameters

    +
      +
    1. + f_in + + function + + handler for hover in +
    2. +
    3. + f_out + + function + + handler for hover out +
    4. +
    +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.drag(onmove, onstart, onend, [mcontext], [scontext], + [econtext]) + + +

    +
    +
    +
    +
    +

    Adds event handlers for an element's drag gesture +

    +
    +

    Parameters

    +
      +
    1. + onmove + + function + + handler for moving +
    2. +
    3. + onstart + + function + + handler for drag start +
    4. +
    5. + onend + + function + + handler for drag end +
    6. +
    7. + mcontext + + object + + context for moving handler +
    8. +
    9. + scontext + + object + + context for drag start handler +
    10. +
    11. + econtext + + object + + context for drag end handler +
    12. +
    +
    +

    Additionaly following drag events are + triggered: drag.start.<id> on start, + drag.end.<id> on end and drag.move.<id> on every move. When element is dragged over another + element + drag.over.<id> fires as well. +

    +

    Start event and start handler are called in specified + context or in context of the element with following + parameters: +

    +
      +
    1. + x + + number + + x position of the mouse +
    2. +
    3. + y + + number + + y position of the mouse +
    4. +
    5. + event + + object + + DOM event object +
    6. +
    +

    Move event and move handler are called in specified + context or in context of the element with following + parameters: +

    +
      +
    1. + dx + + number + + shift by x from the start point +
    2. +
    3. + dy + + number + + shift by y from the start point +
    4. +
    5. + x + + number + + x position of the mouse +
    6. +
    7. + y + + number + + y position of the mouse +
    8. +
    9. + event + + object + + DOM event object +
    10. +
    +

    End event and end handler are called in specified + context or in context of the element with following + parameters: +

    +
      +
    1. + event + + object + + DOM event object +
    2. +
    +

    + Returns: + object + + Element + +

    +
    +
    +
    +
    +
    +

    Element.undrag() + + +

    +
    +
    +
    +
    +

    Removes all drag event handlers from the given element +

    +
    +
    +
    +
    +
    +

    Snap.path.getTotalLength(path) + + +

    +
    +
    +
    +
    +

    Returns the length of the given path in pixels +

    +
    +

    Parameters

    +
      +
    1. + path + + string + + SVG path string +
    2. +
    +
    +

    + Returns: + number + length +

    +
    +
    +
    +
    +
    +

    Snap.path.getPointAtLength(path, length) + + +

    +
    +
    +
    +
    +

    Returns the coordinates of the point located at the + given length along the given path +

    +
    +

    Parameters

    +
      +
    1. + path + + string + + SVG path string +
    2. +
    3. + length + + number + + length, in pixels, from the start of + the path, excluding non-rendering + jumps +
    4. +
    +
    +

    + Returns: + object + representation of the point: +

    +
      +
    1. { +
        +
      1. + x: + + number + + x coordinate, +
      2. +
      3. + y: + + number + + y coordinate, +
      4. +
      5. + alpha: + + number + + angle of derivative +
      6. +
      +
    2. +
    3. }
    4. +
    +
    +
    +
    +
    +
    +

    Snap.path.getSubpath(path, from, to) + + +

    +
    +
    +
    +
    +

    Returns the subpath of a given path between given + start and end lengths +

    +
    +

    Parameters

    +
      +
    1. + path + + string + + SVG path string +
    2. +
    3. + from + + number + + length, in pixels, from the start of + the path to the start of the segment +
    4. +
    5. + to + + number + + length, in pixels, from the start of + the path to the end of the segment +
    6. +
    +
    +

    + Returns: + string + path string definition for the segment +

    +
    +
    +
    +
    +
    +

    Element.getTotalLength() + + +

    +
    +
    +
    +
    +

    Returns the length of the path in pixels (only works + for path elements) +

    +

    + Returns: + number + length +

    +
    +
    +
    +
    +
    +

    Element.getPointAtLength(length) + + +

    +
    +
    +
    +
    +

    Returns coordinates of the point located at the given + length on the given path (only works for path elements) +

    +
    +

    Parameters

    +
      +
    1. + length + + number + + length, in pixels, from the start of + the path, excluding non-rendering + jumps +
    2. +
    +
    +

    + Returns: + object + representation of the point: +

    +
      +
    1. { +
        +
      1. + x: + + number + + x coordinate, +
      2. +
      3. + y: + + number + + y coordinate, +
      4. +
      5. + alpha: + + number + + angle of derivative +
      6. +
      +
    2. +
    3. }
    4. +
    +
    +
    +
    +
    +
    +

    Element.getSubpath(from, to) + + +

    +
    +
    +
    +
    +

    Returns subpath of a given element from given start + and end lengths (only works for path elements) +

    +
    +

    Parameters

    +
      +
    1. + from + + number + + length, in pixels, from the start of + the path to the start of the segment +
    2. +
    3. + to + + number + + length, in pixels, from the start of + the path to the end of the segment +
    4. +
    +
    +

    + Returns: + string + path string definition for the segment +

    +
    +
    +
    +
    +
    +

    Snap.path.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, + c2y, p2x, p2y, t) + + +

    +
    +
    +
    +
    +

    Utility method Finds dot coordinates on the given + cubic beziér curve at the given t +

    +
    +

    Parameters

    +
      +
    1. + p1x + + number + + x of the first point of the curve +
    2. +
    3. + p1y + + number + + y of the first point of the curve +
    4. +
    5. + c1x + + number + + x of the first anchor of the curve +
    6. +
    7. + c1y + + number + + y of the first anchor of the curve +
    8. +
    9. + c2x + + number + + x of the second anchor of the curve +
    10. +
    11. + c2y + + number + + y of the second anchor of the curve +
    12. +
    13. + p2x + + number + + x of the second point of the curve +
    14. +
    15. + p2y + + number + + y of the second point of the curve +
    16. +
    17. + t + + number + + position on the curve (0..1) +
    18. +
    +
    +

    + Returns: + object + point information in format: +

    +
      +
    1. { +
        +
      1. + x: + + number + + x coordinate of the point, +
      2. +
      3. + y: + + number + + y coordinate of the point, +
      4. +
      5. m: { +
          +
        1. + x: + + number + + x coordinate of the left + anchor, +
        2. +
        3. + y: + + number + + y coordinate of the left + anchor +
        4. +
        +
      6. +
      7. },
      8. +
      9. n: { +
          +
        1. + x: + + number + + x coordinate of the right + anchor, +
        2. +
        3. + y: + + number + + y coordinate of the right + anchor +
        4. +
        +
      10. +
      11. },
      12. +
      13. start: { +
          +
        1. + x: + + number + + x coordinate of the start + of the curve, +
        2. +
        3. + y: + + number + + y coordinate of the start + of the curve +
        4. +
        +
      14. +
      15. },
      16. +
      17. end: { +
          +
        1. + x: + + number + + x coordinate of the end of + the curve, +
        2. +
        3. + y: + + number + + y coordinate of the end of + the curve +
        4. +
        +
      18. +
      19. },
      20. +
      21. + alpha: + + number + + angle of the curve derivative at + the point +
      22. +
      +
    2. +
    3. }
    4. +
    +
    +
    +
    +
    +
    +

    Snap.path.bezierBBox(…) + + +

    +
    +
    +
    +
    +

    Utility method Returns the bounding box of a given + cubic beziér curve +

    +
    +

    Parameters

    +
      +
    1. + p1x + + number + + x of the first point of the curve +
    2. +
    3. + p1y + + number + + y of the first point of the curve +
    4. +
    5. + c1x + + number + + x of the first anchor of the curve +
    6. +
    7. + c1y + + number + + y of the first anchor of the curve +
    8. +
    9. + c2x + + number + + x of the second anchor of the curve +
    10. +
    11. + c2y + + number + + y of the second anchor of the curve +
    12. +
    13. + p2x + + number + + x of the second point of the curve +
    14. +
    15. + p2y + + number + + y of the second point of the curve +
    16. +
    +
    +

    or +

    +
    +

    Parameters

    +
      +
    1. + bez + + array + + array of six points for beziér curve +
    2. +
    +
    +

    + Returns: + object + bounding box +

    +
      +
    1. { +
        +
      1. + x: + + number + + x coordinate of the left top point + of the box, +
      2. +
      3. + y: + + number + + y coordinate of the left top point + of the box, +
      4. +
      5. + x2: + + number + + x coordinate of the right bottom + point of the box, +
      6. +
      7. + y2: + + number + + y coordinate of the right bottom + point of the box, +
      8. +
      9. + width: + + number + + width of the box, +
      10. +
      11. + height: + + number + + height of the box +
      12. +
      +
    2. +
    3. }
    4. +
    +
    +
    +
    +
    +
    +

    Snap.path.isPointInsideBBox(bbox, x, y) + + +

    +
    +
    +
    +
    +

    Utility method Returns true if given + point is inside bounding box +

    +
    +

    Parameters

    +
      +
    1. + bbox + + string + + bounding box +
    2. +
    3. + x + + string + + x coordinate of the point +
    4. +
    5. + y + + string + + y coordinate of the point +
    6. +
    +
    +

    + Returns: + boolean + true if point is inside +

    +
    +
    +
    +
    +
    +

    Snap.path.isBBoxIntersect(bbox1, bbox2) + + +

    +
    +
    +
    +
    +

    Utility method Returns true if two bounding + boxes intersect +

    +
    +

    Parameters

    +
      +
    1. + bbox1 + + string + + first bounding box +
    2. +
    3. + bbox2 + + string + + second bounding box +
    4. +
    +
    +

    + Returns: + boolean + true if bounding boxes intersect +

    +
    +
    +
    +
    +
    +

    Snap.path.intersection(path1, path2) + + +

    +
    +
    +
    +
    +

    Utility method Finds intersections of two paths +

    +
    +

    Parameters

    +
      +
    1. + path1 + + string + + path string +
    2. +
    3. + path2 + + string + + path string +
    4. +
    +
    +

    + Returns: + array + dots of intersection +

    +
      +
    1. [
    2. +
    3. { +
        +
      1. + x: + + number + + x coordinate of the point, +
      2. +
      3. + y: + + number + + y coordinate of the point, +
      4. +
      5. + t1: + + number + + t value for segment of path1, +
      6. +
      7. + t2: + + number + + t value for segment of path2, +
      8. +
      9. + segment1: + + number + + order number for segment of path1, +
      10. +
      11. + segment2: + + number + + order number for segment of path2, +
      12. +
      13. + bez1: + + array + + eight coordinates representing beziér + curve for the segment of path1, +
      14. +
      15. + bez2: + + array + + eight coordinates representing beziér + curve for the segment of path2 +
      16. +
      +
    4. +
    5. }
    6. +
    7. ]
    8. +
    +
    +
    +
    +
    +
    +

    Snap.path.isPointInside(path, x, y) + + +

    +
    +
    +
    +
    +

    Utility method Returns true if given + point is inside a given closed path. +

    +

    Note: fill mode doesn’t affect the result of this + method. +

    +
    +

    Parameters

    +
      +
    1. + path + + string + + path string +
    2. +
    3. + x + + number + + x of the point +
    4. +
    5. + y + + number + + y of the point +
    6. +
    +
    +

    + Returns: + boolean + true if point is inside the path +

    +
    +
    +
    +
    +
    +

    Snap.path.getBBox(path) + + +

    +
    +
    +
    +
    +

    Utility method Returns the bounding box of a given + path +

    +
    +

    Parameters

    +
      +
    1. + path + + string + + path string +
    2. +
    +
    +

    + Returns: + object + bounding box +

    +
      +
    1. { +
        +
      1. + x: + + number + + x coordinate of the left top point + of the box, +
      2. +
      3. + y: + + number + + y coordinate of the left top point + of the box, +
      4. +
      5. + x2: + + number + + x coordinate of the right bottom + point of the box, +
      6. +
      7. + y2: + + number + + y coordinate of the right bottom + point of the box, +
      8. +
      9. + width: + + number + + width of the box, +
      10. +
      11. + height: + + number + + height of the box +
      12. +
      +
    2. +
    3. }
    4. +
    +
    +
    +
    +
    +
    +

    Snap.path.toRelative(path) + + +

    +
    +
    +
    +
    +

    Utility method Converts path coordinates into relative + values +

    +
    +

    Parameters

    +
      +
    1. + path + + string + + path string +
    2. +
    +
    +

    + Returns: + array + path string +

    +
    +
    +
    +
    +
    +

    Snap.path.toAbsolute(path) + + +

    +
    +
    +
    +
    +

    Utility method Converts path coordinates into absolute + values +

    +
    +

    Parameters

    +
      +
    1. + path + + string + + path string +
    2. +
    +
    +

    + Returns: + array + path string +

    +
    +
    +
    +
    +
    +

    Snap.path.toCubic(pathString) + + +

    +
    +
    +
    +
    +

    Utility method Converts path to a new path where + all segments are cubic beziér curves +

    +
    +

    Parameters

    +
      +
    1. + pathString + + string + array + + path string or array of segments +
    2. +
    +
    +

    + Returns: + array + array of segments +

    +
    +
    +
    +
    +
    +

    Snap.path.map(path, matrix) + + +

    +
    +
    +
    +
    +

    Transform the path string with the given matrix +

    +
    +

    Parameters

    +
      +
    1. + path + + string + + path string +
    2. +
    3. + matrix + + object + + see + Matrix + +
    4. +
    +
    +

    + Returns: + string + transformed path string +

    +
    +
    +
    +
    +
    +

    Set.push() + + +

    +
    +
    +
    +
    +

    Adds each argument to the current set +

    +

    + Returns: + object + original element +

    +
    +
    +
    +
    +
    +

    Set.pop() + + +

    +
    +
    +
    +
    +

    Removes last element and returns it +

    +

    + Returns: + object + element +

    +
    +
    +
    +
    +
    +

    Set.forEach(callback, thisArg) + + +

    +
    +
    +
    +
    +

    Executes given function for each element in the set +

    +

    If the function returns false, the loop + stops running. +

    +
    +

    Parameters

    +
      +
    1. + callback + + function + + function to run +
    2. +
    3. + thisArg + + object + + context object for the callback +
    4. +
    +
    +

    + Returns: + object + Set object +

    +
    +
    +
    +
    +
    +

    Set.animate(…) + + +

    +
    +
    +
    +
    +

    Animates each element in set in sync. +

    +

    +
    +

    Parameters

    +
      +
    1. + attrs + + object + + key-value pairs of destination attributes +
    2. +
    3. + duration + + number + + duration of the animation in milliseconds +
    4. +
    5. + easing + + function + + easing function from + mina or custom +
    6. +
    7. + callback + + function + + callback function that executes when + the animation ends +
    8. +
    +
    +

    or +

    +
    +

    Parameters

    +
      +
    1. + animation + + array + + array of animation parameter for each + element in set in format [attrs, duration, easing, callback] +
    2. +
    +
    +

    Usage

    +
    // animate all elements in set to radius 10
     set.animate({r: 10}, 500, mina.easein);
     // or
     // animate first element to radius 10, but second to radius 20 and in different time
     set.animate([{r: 10}, 500, mina.easein], [{r: 20}, 1500, mina.easein]);
    - - - - - - - - - - - -

    - Returns: - - Element - - the current element -

    - - - - -
    -
    -
    - -
    -
    -

    Set.bind(…)

    -
    -
    -
    -
    - - - - -

    Specifies how to handle a specific attribute when applied -to a set. -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. attr - string - attribute name
    2. -
    3. callback - function - function to run
    4. - -
    -
    - - - - - - - - -

    or -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. attr - string - attribute name
    2. -
    3. element - Element - specific element in the set to apply the attribute to
    4. - -
    -
    - - - - - - - - -

    or -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. attr - string - attribute name
    2. -
    3. element - Element - specific element in the set to apply the attribute to
    4. -
    5. eattr - string - attribute on the element to bind the attribute to
    6. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - Set object -

    - - - - -
    -
    -
    - -
    -
    -

    Set.clear()

    -
    -
    -
    -
    - - - - -

    Removes all elements from the set -

    - - - - - - - - -
    -
    -
    - -
    -
    -

    Set.splice(index, count, [insertion…])

    -
    -
    -
    -
    - - - - -

    Removes range of elements from the set -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. index - number - position of the deletion
    2. -
    3. count - number - number of element to remove
    4. -
    5. insertion… - object - elements to insert
    6. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - object - - set elements that were deleted -

    - - - - -
    -
    -
    - -
    -
    -

    Set.exclude(element)

    -
    -
    -
    -
    - - - - -

    Removes given element from the set -

    - - - - - - - - - - -
    -

    Parameters

    -
      -
    1. element - object - element to remove
    2. - -
    -
    - - - - - - - - - - - - - -

    - Returns: - - boolean - - true if object was found and removed from the set -

    - - - - -
    -
    -
    - -
    -
    -
    -
    - - - + - + + \ No newline at end of file diff --git a/dr.json b/dr.json index da75abb..9e690f9 100644 --- a/dr.json +++ b/dr.json @@ -8,6 +8,12 @@ }, { "url": "src/element.js", "link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/element.js" + }, { + "url": "src/attr.js", + "link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/attr.js" + }, { + "url": "src/animation.js", + "link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/animation.js" }, { "url": "src/matrix.js", "link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/matrix.js" @@ -35,5 +41,8 @@ }, { "url": "src/set.js", "link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/set.js" + }, { + "url": "src/colors.js", + "link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/colors.js" }] } diff --git a/history.md b/history.md index 51c18ea..5ff06b3 100644 --- a/history.md +++ b/history.md @@ -1,3 +1,11 @@ +#0.5.0 + +* Added color palettes for Material and FlatUI +* Added methods for gradients: `Element.stops()`, `Element.addStop()`, `Element.setStops()` +* Fixed matrix splitting for better animation of matrices` +* Various bug fixes +* Better integration of tests and ESlint + #0.4.1 * Bug fixes. @@ -46,4 +54,4 @@ #0.1.0 -* Initial release \ No newline at end of file +* Initial release diff --git a/package.json b/package.json index d3794c4..2adc3c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "snapsvg", - "version": "0.4.1", + "version": "0.5.0", "description": "JavaScript Vector Library", "main": "./dist/snap.svg.js", "repository": { @@ -8,17 +8,51 @@ "url": "git@github.com:adobe-webplatform/Snap.svg.git" }, "author": "Dmitry Baranovskiy", - "license": "Apache License v2", + "license": "Apache-2.0", "dependencies": { - "eve": "~0.4.2" + "eve": "~0.5.1" }, "devDependencies": { "grunt": "~0.4.1", "grunt-contrib-uglify": "~0.2.0", "grunt-contrib-concat": "~0.3.0", "grunt-exec": "~0.4.2", + "grunt-prettify": "0.4.0", "mocha": "*", "expect.js": "*", + "eslint": "*", "dr.js": "~0.1.0" + }, + "eslintConfig": { + "globals": { + "window": true, + "console": true + }, + "rules": { + "block-scoped-var": 0, + "comma-dangle": 0, + "no-extra-parens": 1, + "no-shadow": 0, + "consistent-return": 0, + "eqeqeq": 0, + "no-new-wrappers": 0, + "no-sequences": 1, + "radix": 2, + "new-parens": 0, + "no-underscore-dangle": 0, + "no-path-concat": 0, + "strict": 0, + "camelcase": 0, + "no-extend-native": 0, + "no-loop-func": 0, + "new-cap": 0, + "no-unused-expressions": 0, + "no-mixed-requires": 0, + "quotes": [ + 1, + "double", + "avoid-escape" + ] + } } } diff --git a/src/amd-banner.js b/src/amd-banner.js index 390c4aa..422561d 100644 --- a/src/amd-banner.js +++ b/src/amd-banner.js @@ -5,9 +5,9 @@ define(["eve"], function (eve) { return factory(glob, eve); }); - } else if (typeof exports != 'undefined') { + } else if (typeof exports != "undefined") { // Next for Node.js or CommonJS - var eve = require('eve'); + var eve = require("eve"); module.exports = factory(glob, eve); } else { // Browser globals (glob is window) diff --git a/src/animation.js b/src/animation.js new file mode 100644 index 0000000..5ea1717 --- /dev/null +++ b/src/animation.js @@ -0,0 +1,207 @@ +// Copyright (c) 2016 Adobe Systems Incorporated. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { + var elproto = Element.prototype, + is = Snap.is, + Str = String, + has = "hasOwnProperty"; + function slice(from, to, f) { + return function (arr) { + var res = arr.slice(from, to); + if (res.length == 1) { + res = res[0]; + } + return f ? f(res) : res; + }; + } + var Animation = function (attr, ms, easing, callback) { + if (typeof easing == "function" && !easing.length) { + callback = easing; + easing = mina.linear; + } + this.attr = attr; + this.dur = ms; + easing && (this.easing = easing); + callback && (this.callback = callback); + }; + Snap._.Animation = Animation; + /*\ + * Snap.animation + [ method ] + ** + * Creates an animation object + ** + - attr (object) attributes of final destination + - duration (number) duration of the animation, in milliseconds + - easing (function) #optional one of easing functions of @mina or custom one + - callback (function) #optional callback function that fires when animation ends + = (object) animation object + \*/ + Snap.animation = function (attr, ms, easing, callback) { + return new Animation(attr, ms, easing, callback); + }; + /*\ + * Element.inAnim + [ method ] + ** + * Returns a set of animations that may be able to manipulate the current element + ** + = (object) in format: + o { + o anim (object) animation object, + o mina (object) @mina object, + o curStatus (number) 0..1 — status of the animation: 0 — just started, 1 — just finished, + o status (function) gets or sets the status of the animation, + o stop (function) stops the animation + o } + \*/ + elproto.inAnim = function () { + var el = this, + res = []; + for (var id in el.anims) if (el.anims[has](id)) { + (function (a) { + res.push({ + anim: new Animation(a._attrs, a.dur, a.easing, a._callback), + mina: a, + curStatus: a.status(), + status: function (val) { + return a.status(val); + }, + stop: function () { + a.stop(); + } + }); + }(el.anims[id])); + } + return res; + }; + /*\ + * Snap.animate + [ method ] + ** + * Runs generic animation of one number into another with a caring function + ** + - from (number|array) number or array of numbers + - to (number|array) number or array of numbers + - setter (function) caring function that accepts one number argument + - duration (number) duration, in milliseconds + - easing (function) #optional easing function from @mina or custom + - callback (function) #optional callback function to execute when animation ends + = (object) animation object in @mina format + o { + o id (string) animation id, consider it read-only, + o duration (function) gets or sets the duration of the animation, + o easing (function) easing, + o speed (function) gets or sets the speed of the animation, + o status (function) gets or sets the status of the animation, + o stop (function) stops the animation + o } + | var rect = Snap().rect(0, 0, 10, 10); + | Snap.animate(0, 10, function (val) { + | rect.attr({ + | x: val + | }); + | }, 1000); + | // in given context is equivalent to + | rect.animate({x: 10}, 1000); + \*/ + Snap.animate = function (from, to, setter, ms, easing, callback) { + if (typeof easing == "function" && !easing.length) { + callback = easing; + easing = mina.linear; + } + var now = mina.time(), + anim = mina(from, to, now, now + ms, mina.time, setter, easing); + callback && eve.once("mina.finish." + anim.id, callback); + return anim; + }; + /*\ + * Element.stop + [ method ] + ** + * Stops all the animations for the current element + ** + = (Element) the current element + \*/ + elproto.stop = function () { + var anims = this.inAnim(); + for (var i = 0, ii = anims.length; i < ii; i++) { + anims[i].stop(); + } + return this; + }; + /*\ + * Element.animate + [ method ] + ** + * Animates the given attributes of the element + ** + - attrs (object) key-value pairs of destination attributes + - duration (number) duration of the animation in milliseconds + - easing (function) #optional easing function from @mina or custom + - callback (function) #optional callback function that executes when the animation ends + = (Element) the current element + \*/ + elproto.animate = function (attrs, ms, easing, callback) { + if (typeof easing == "function" && !easing.length) { + callback = easing; + easing = mina.linear; + } + if (attrs instanceof Animation) { + callback = attrs.callback; + easing = attrs.easing; + ms = attrs.dur; + attrs = attrs.attr; + } + var fkeys = [], tkeys = [], keys = {}, from, to, f, eq, + el = this; + for (var key in attrs) if (attrs[has](key)) { + if (el.equal) { + eq = el.equal(key, Str(attrs[key])); + from = eq.from; + to = eq.to; + f = eq.f; + } else { + from = +el.attr(key); + to = +attrs[key]; + } + var len = is(from, "array") ? from.length : 1; + keys[key] = slice(fkeys.length, fkeys.length + len, f); + fkeys = fkeys.concat(from); + tkeys = tkeys.concat(to); + } + var now = mina.time(), + anim = mina(fkeys, tkeys, now, now + ms, mina.time, function (val) { + var attr = {}; + for (var key in keys) if (keys[has](key)) { + attr[key] = keys[key](val); + } + el.attr(attr); + }, easing); + el.anims[anim.id] = anim; + anim._attrs = attrs; + anim._callback = callback; + eve("snap.animcreated." + el.id, anim); + eve.once("mina.finish." + anim.id, function () { + eve.off("mina.*." + anim.id); + delete el.anims[anim.id]; + callback && callback.call(el); + }); + eve.once("mina.stop." + anim.id, function () { + eve.off("mina.*." + anim.id); + delete el.anims[anim.id]; + }); + return el; + }; +}); diff --git a/src/attr.js b/src/attr.js index c76a180..c25f791 100644 --- a/src/attr.js +++ b/src/attr.js @@ -1,11 +1,11 @@ // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,12 +17,23 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { wrap = Snap._.wrap, is = Snap.is, getSomeDefs = Snap._.getSomeDefs, - reURLValue = /^url\(#?([^)]+)\)$/, + reURLValue = /^url\((['"]?)([^)]+)\1\)$/, $ = Snap._.$, URL = Snap.url, Str = String, separator = Snap._.separator, E = ""; + /*\ + * Snap.deurl + [ method ] + ** + * Unwraps path from `"url()"`. + - value (string) url path + = (string) unwrapped path + \*/ + Snap.deurl = function (value) { + return String(value).match(reURLValue)[2]; + } // Attributes event handlers eve.on("snap.util.attr.mask", function (value) { if (value instanceof Element || value instanceof Fragment) { @@ -53,9 +64,20 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { }(function (value) { if (value instanceof Element || value instanceof Fragment) { eve.stop(); - if (value.type == "clipPath") { - var clip = value; - } else { + var clip, + node = value.node; + while (node) { + if (node.nodeName === "clipPath") { + clip = new Element(node); + break; + } + if (node.nodeName === "svg") { + clip = undefined; + break; + } + node = node.parentNode; + } + if (!clip) { clip = make("clipPath", getSomeDefs(this)); clip.node.appendChild(value.node); !clip.node.id && $(clip.node, { @@ -143,6 +165,23 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { } return out; }); + var len = stops.length, + start = 0, + j = 0; + function seed(i, end) { + var step = (end - start) / (i - j); + for (var k = j; k < i; k++) { + stops[k].offset = +(+start + step * (k - j)).toFixed(2); + } + j = i; + start = end; + } + len--; + for (var i = 0; i < len; i++) if ("offset" in stops[i]) { + seed(i, stops[i].offset); + } + stops[len].offset = stops[len].offset || 100; + seed(len, stops[len].offset); return { type: type, params: params, @@ -375,6 +414,22 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { eve.on("snap.util.getattr.#text", function () { return this.node.textContent; })(-1); + eve.on("snap.util.getattr.fill", function (internal) { + if (internal) { + return; + } + eve.stop(); + var value = eve("snap.util.getattr.fill", this, true).firstDefined(); + return Snap(Snap.deurl(value)) || value; + })(-1); + eve.on("snap.util.getattr.stroke", function (internal) { + if (internal) { + return; + } + eve.stop(); + var value = eve("snap.util.getattr.stroke", this, true).firstDefined(); + return Snap(Snap.deurl(value)) || value; + })(-1); eve.on("snap.util.getattr.viewBox", function () { eve.stop(); var vb = $(this.node, "viewBox"); diff --git a/src/attradd.js b/src/attradd.js index 28b6ad1..57b0006 100644 --- a/src/attradd.js +++ b/src/attradd.js @@ -1,11 +1,11 @@ // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -86,4 +86,4 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { } } })(-10); -}); \ No newline at end of file +}); diff --git a/src/class.js b/src/class.js index 2ab4c05..f39d7dd 100644 --- a/src/class.js +++ b/src/class.js @@ -38,7 +38,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { if (classes.length) { j = 0; - while ((clazz = classes[j++])) { + while (clazz = classes[j++]) { pos = curClasses.indexOf(clazz); if (!~pos) { curClasses.push(clazz); @@ -72,7 +72,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { finalValue; if (curClasses.length) { j = 0; - while ((clazz = classes[j++])) { + while (clazz = classes[j++]) { pos = curClasses.indexOf(clazz); if (~pos) { curClasses.splice(pos, 1); @@ -129,7 +129,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { clazz, finalValue; j = 0; - while ((clazz = classes[j++])) { + while (clazz = classes[j++]) { pos = curClasses.indexOf(clazz); if (~pos) { curClasses.splice(pos, 1); diff --git a/src/colors.js b/src/colors.js new file mode 100644 index 0000000..d875778 --- /dev/null +++ b/src/colors.js @@ -0,0 +1,129 @@ +// Copyright (c) 2017 Adobe Systems Incorporated. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +Snap.plugin(function (Snap, Element, Paper, glob) { + // Colours are from https://www.materialui.co + var red = "#ffebee#ffcdd2#ef9a9a#e57373#ef5350#f44336#e53935#d32f2f#c62828#b71c1c#ff8a80#ff5252#ff1744#d50000", + pink = "#FCE4EC#F8BBD0#F48FB1#F06292#EC407A#E91E63#D81B60#C2185B#AD1457#880E4F#FF80AB#FF4081#F50057#C51162", + purple = "#F3E5F5#E1BEE7#CE93D8#BA68C8#AB47BC#9C27B0#8E24AA#7B1FA2#6A1B9A#4A148C#EA80FC#E040FB#D500F9#AA00FF", + deeppurple = "#EDE7F6#D1C4E9#B39DDB#9575CD#7E57C2#673AB7#5E35B1#512DA8#4527A0#311B92#B388FF#7C4DFF#651FFF#6200EA", + indigo = "#E8EAF6#C5CAE9#9FA8DA#7986CB#5C6BC0#3F51B5#3949AB#303F9F#283593#1A237E#8C9EFF#536DFE#3D5AFE#304FFE", + blue = "#E3F2FD#BBDEFB#90CAF9#64B5F6#64B5F6#2196F3#1E88E5#1976D2#1565C0#0D47A1#82B1FF#448AFF#2979FF#2962FF", + lightblue = "#E1F5FE#B3E5FC#81D4FA#4FC3F7#29B6F6#03A9F4#039BE5#0288D1#0277BD#01579B#80D8FF#40C4FF#00B0FF#0091EA", + cyan = "#E0F7FA#B2EBF2#80DEEA#4DD0E1#26C6DA#00BCD4#00ACC1#0097A7#00838F#006064#84FFFF#18FFFF#00E5FF#00B8D4", + teal = "#E0F2F1#B2DFDB#80CBC4#4DB6AC#26A69A#009688#00897B#00796B#00695C#004D40#A7FFEB#64FFDA#1DE9B6#00BFA5", + green = "#E8F5E9#C8E6C9#A5D6A7#81C784#66BB6A#4CAF50#43A047#388E3C#2E7D32#1B5E20#B9F6CA#69F0AE#00E676#00C853", + lightgreen = "#F1F8E9#DCEDC8#C5E1A5#AED581#9CCC65#8BC34A#7CB342#689F38#558B2F#33691E#CCFF90#B2FF59#76FF03#64DD17", + lime = "#F9FBE7#F0F4C3#E6EE9C#DCE775#D4E157#CDDC39#C0CA33#AFB42B#9E9D24#827717#F4FF81#EEFF41#C6FF00#AEEA00", + yellow = "#FFFDE7#FFF9C4#FFF59D#FFF176#FFEE58#FFEB3B#FDD835#FBC02D#F9A825#F57F17#FFFF8D#FFFF00#FFEA00#FFD600", + amber = "#FFF8E1#FFECB3#FFE082#FFD54F#FFCA28#FFC107#FFB300#FFA000#FF8F00#FF6F00#FFE57F#FFD740#FFC400#FFAB00", + orange = "#FFF3E0#FFE0B2#FFCC80#FFB74D#FFA726#FF9800#FB8C00#F57C00#EF6C00#E65100#FFD180#FFAB40#FF9100#FF6D00", + deeporange = "#FBE9E7#FFCCBC#FFAB91#FF8A65#FF7043#FF5722#F4511E#E64A19#D84315#BF360C#FF9E80#FF6E40#FF3D00#DD2C00", + brown = "#EFEBE9#D7CCC8#BCAAA4#A1887F#8D6E63#795548#6D4C41#5D4037#4E342E#3E2723", + grey = "#FAFAFA#F5F5F5#EEEEEE#E0E0E0#BDBDBD#9E9E9E#757575#616161#424242#212121", + bluegrey = "#ECEFF1#CFD8DC#B0BEC5#90A4AE#78909C#607D8B#546E7A#455A64#37474F#263238"; + /*\ + * Snap.mui + [ property ] + ** + * Contain Material UI colours. + | Snap().rect(0, 0, 10, 10).attr({fill: Snap.mui.deeppurple, stroke: Snap.mui.amber[600]}); + # For colour reference: https://www.materialui.co. + \*/ + Snap.mui = {}; + /*\ + * Snap.flat + [ property ] + ** + * Contain Flat UI colours. + | Snap().rect(0, 0, 10, 10).attr({fill: Snap.flat.carrot, stroke: Snap.flat.wetasphalt}); + # For colour reference: https://www.materialui.co. + \*/ + Snap.flat = {}; + function saveColor(colors) { + colors = colors.split(/(?=#)/); + var color = new String(colors[5]); + color[50] = colors[0]; + color[100] = colors[1]; + color[200] = colors[2]; + color[300] = colors[3]; + color[400] = colors[4]; + color[500] = colors[5]; + color[600] = colors[6]; + color[700] = colors[7]; + color[800] = colors[8]; + color[900] = colors[9]; + if (colors[10]) { + color.A100 = colors[10]; + color.A200 = colors[11]; + color.A400 = colors[12]; + color.A700 = colors[13]; + } + return color; + } + Snap.mui.red = saveColor(red); + Snap.mui.pink = saveColor(pink); + Snap.mui.purple = saveColor(purple); + Snap.mui.deeppurple = saveColor(deeppurple); + Snap.mui.indigo = saveColor(indigo); + Snap.mui.blue = saveColor(blue); + Snap.mui.lightblue = saveColor(lightblue); + Snap.mui.cyan = saveColor(cyan); + Snap.mui.teal = saveColor(teal); + Snap.mui.green = saveColor(green); + Snap.mui.lightgreen = saveColor(lightgreen); + Snap.mui.lime = saveColor(lime); + Snap.mui.yellow = saveColor(yellow); + Snap.mui.amber = saveColor(amber); + Snap.mui.orange = saveColor(orange); + Snap.mui.deeporange = saveColor(deeporange); + Snap.mui.brown = saveColor(brown); + Snap.mui.grey = saveColor(grey); + Snap.mui.bluegrey = saveColor(bluegrey); + Snap.flat.turquoise = "#1abc9c"; + Snap.flat.greensea = "#16a085"; + Snap.flat.sunflower = "#f1c40f"; + Snap.flat.orange = "#f39c12"; + Snap.flat.emerland = "#2ecc71"; + Snap.flat.nephritis = "#27ae60"; + Snap.flat.carrot = "#e67e22"; + Snap.flat.pumpkin = "#d35400"; + Snap.flat.peterriver = "#3498db"; + Snap.flat.belizehole = "#2980b9"; + Snap.flat.alizarin = "#e74c3c"; + Snap.flat.pomegranate = "#c0392b"; + Snap.flat.amethyst = "#9b59b6"; + Snap.flat.wisteria = "#8e44ad"; + Snap.flat.clouds = "#ecf0f1"; + Snap.flat.silver = "#bdc3c7"; + Snap.flat.wetasphalt = "#34495e"; + Snap.flat.midnightblue = "#2c3e50"; + Snap.flat.concrete = "#95a5a6"; + Snap.flat.asbestos = "#7f8c8d"; + /*\ + * Snap.importMUIColors + [ method ] + ** + * Imports Material UI colours into global object. + | Snap.importMUIColors(); + | Snap().rect(0, 0, 10, 10).attr({fill: deeppurple, stroke: amber[600]}); + # For colour reference: https://www.materialui.co. + \*/ + Snap.importMUIColors = function () { + for (var color in Snap.mui) { + if (Snap.mui.hasOwnProperty(color)) { + window[color] = Snap.mui[color]; + } + } + }; +}); diff --git a/src/copy.js b/src/copy.js index 0939cd6..952681c 100644 --- a/src/copy.js +++ b/src/copy.js @@ -1,6 +1,6 @@ // Snap.svg @VERSION // -// Copyright (c) 2013 – 2015 Adobe Systems Incorporated. All rights reserved. +// Copyright (c) 2013 – 2017 Adobe Systems Incorporated. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/element.js b/src/element.js index 4777ccb..3b43b37 100644 --- a/src/element.js +++ b/src/element.js @@ -47,6 +47,9 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { o } \*/ elproto.getBBox = function (isWithoutTransform) { + if (this.type == "tspan") { + return Snap._.box(this.node.getClientRects().item(0)); + } if (!Snap.Matrix || !Snap.path) { return this.node.getBBox(); } @@ -487,7 +490,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { if (val) { uses[val] = (uses[val] || []).concat(function (id) { var attr = {}; - attr[name] = URL(id); + attr[name] = Snap.url(id); $(it.node, attr); }); } @@ -651,193 +654,6 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { p.node.appendChild(this.node); return p; }; - // animation - function slice(from, to, f) { - return function (arr) { - var res = arr.slice(from, to); - if (res.length == 1) { - res = res[0]; - } - return f ? f(res) : res; - }; - } - var Animation = function (attr, ms, easing, callback) { - if (typeof easing == "function" && !easing.length) { - callback = easing; - easing = mina.linear; - } - this.attr = attr; - this.dur = ms; - easing && (this.easing = easing); - callback && (this.callback = callback); - }; - Snap._.Animation = Animation; - /*\ - * Snap.animation - [ method ] - ** - * Creates an animation object - ** - - attr (object) attributes of final destination - - duration (number) duration of the animation, in milliseconds - - easing (function) #optional one of easing functions of @mina or custom one - - callback (function) #optional callback function that fires when animation ends - = (object) animation object - \*/ - Snap.animation = function (attr, ms, easing, callback) { - return new Animation(attr, ms, easing, callback); - }; - /*\ - * Element.inAnim - [ method ] - ** - * Returns a set of animations that may be able to manipulate the current element - ** - = (object) in format: - o { - o anim (object) animation object, - o mina (object) @mina object, - o curStatus (number) 0..1 — status of the animation: 0 — just started, 1 — just finished, - o status (function) gets or sets the status of the animation, - o stop (function) stops the animation - o } - \*/ - elproto.inAnim = function () { - var el = this, - res = []; - for (var id in el.anims) if (el.anims[has](id)) { - (function (a) { - res.push({ - anim: new Animation(a._attrs, a.dur, a.easing, a._callback), - mina: a, - curStatus: a.status(), - status: function (val) { - return a.status(val); - }, - stop: function () { - a.stop(); - } - }); - }(el.anims[id])); - } - return res; - }; - /*\ - * Snap.animate - [ method ] - ** - * Runs generic animation of one number into another with a caring function - ** - - from (number|array) number or array of numbers - - to (number|array) number or array of numbers - - setter (function) caring function that accepts one number argument - - duration (number) duration, in milliseconds - - easing (function) #optional easing function from @mina or custom - - callback (function) #optional callback function to execute when animation ends - = (object) animation object in @mina format - o { - o id (string) animation id, consider it read-only, - o duration (function) gets or sets the duration of the animation, - o easing (function) easing, - o speed (function) gets or sets the speed of the animation, - o status (function) gets or sets the status of the animation, - o stop (function) stops the animation - o } - | var rect = Snap().rect(0, 0, 10, 10); - | Snap.animate(0, 10, function (val) { - | rect.attr({ - | x: val - | }); - | }, 1000); - | // in given context is equivalent to - | rect.animate({x: 10}, 1000); - \*/ - Snap.animate = function (from, to, setter, ms, easing, callback) { - if (typeof easing == "function" && !easing.length) { - callback = easing; - easing = mina.linear; - } - var now = mina.time(), - anim = mina(from, to, now, now + ms, mina.time, setter, easing); - callback && eve.once("mina.finish." + anim.id, callback); - return anim; - }; - /*\ - * Element.stop - [ method ] - ** - * Stops all the animations for the current element - ** - = (Element) the current element - \*/ - elproto.stop = function () { - var anims = this.inAnim(); - for (var i = 0, ii = anims.length; i < ii; i++) { - anims[i].stop(); - } - return this; - }; - /*\ - * Element.animate - [ method ] - ** - * Animates the given attributes of the element - ** - - attrs (object) key-value pairs of destination attributes - - duration (number) duration of the animation in milliseconds - - easing (function) #optional easing function from @mina or custom - - callback (function) #optional callback function that executes when the animation ends - = (Element) the current element - \*/ - elproto.animate = function (attrs, ms, easing, callback) { - if (typeof easing == "function" && !easing.length) { - callback = easing; - easing = mina.linear; - } - if (attrs instanceof Animation) { - callback = attrs.callback; - easing = attrs.easing; - ms = attrs.dur; - attrs = attrs.attr; - } - var fkeys = [], tkeys = [], keys = {}, from, to, f, eq, - el = this; - for (var key in attrs) if (attrs[has](key)) { - if (el.equal) { - eq = el.equal(key, Str(attrs[key])); - from = eq.from; - to = eq.to; - f = eq.f; - } else { - from = +el.attr(key); - to = +attrs[key]; - } - var len = is(from, "array") ? from.length : 1; - keys[key] = slice(fkeys.length, fkeys.length + len, f); - fkeys = fkeys.concat(from); - tkeys = tkeys.concat(to); - } - var now = mina.time(), - anim = mina(fkeys, tkeys, now, now + ms, mina.time, function (val) { - var attr = {}; - for (var key in keys) if (keys[has](key)) { - attr[key] = keys[key](val); - } - el.attr(attr); - }, easing); - el.anims[anim.id] = anim; - anim._attrs = attrs; - anim._callback = callback; - eve("snap.animcreated." + el.id, anim); - eve.once("mina.finish." + anim.id, function () { - delete el.anims[anim.id]; - callback && callback.call(el); - }); - eve.once("mina.stop." + anim.id, function () { - delete el.anims[anim.id]; - }); - return el; - }; var eldata = {}; /*\ * Element.data diff --git a/src/equal.js b/src/equal.js index 91810d3..742a36d 100644 --- a/src/equal.js +++ b/src/equal.js @@ -1,11 +1,11 @@ // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -13,7 +13,7 @@ // limitations under the License. Snap.plugin(function (Snap, Element, Paper, glob) { var names = {}, - reUnit = /[a-z]+$/i, + reUnit = /[%a-z]+$/i, Str = String; names.stroke = names.fill = "colour"; function getEmpty(item) { @@ -36,9 +36,10 @@ Snap.plugin(function (Snap, Element, Paper, glob) { } } function equaliseTransform(t1, t2, getBBox) { - t2 = Str(t2).replace(/\.{3}|\u2026/g, t1); - t1 = Snap.parseTransformString(t1) || []; - t2 = Snap.parseTransformString(t2) || []; + t1 = t1 || new Snap.Matrix; + t2 = t2 || new Snap.Matrix; + t1 = Snap.parseTransformString(t1.toTransformString()) || []; + t2 = Snap.parseTransformString(t2.toTransformString()) || []; var maxlength = Math.max(t1.length, t2.length), from = [], to = [], @@ -47,9 +48,9 @@ Snap.plugin(function (Snap, Element, Paper, glob) { for (; i < maxlength; i++) { tt1 = t1[i] || getEmpty(t2[i]); tt2 = t2[i] || getEmpty(tt1); - if ((tt1[0] != tt2[0]) || - (tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) || - (tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4])) + if (tt1[0] != tt2[0] || + tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3]) || + tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4]) ) { t1 = Snap._.transform2matrix(t1, getBBox()); t2 = Snap._.transform2matrix(t2, getBBox()); @@ -82,7 +83,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { return val.join(" "); } function getColour(clr) { - return Snap.rgb(clr[0], clr[1], clr[2]); + return Snap.rgb(clr[0], clr[1], clr[2], clr[3]); } function getPath(path) { var k = 0, i, ii, j, jj, out, a, b = []; @@ -90,7 +91,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { out = "["; a = ['"' + path[i][0] + '"']; for (j = 1, jj = path[i].length; j < jj; j++) { - a[j] = "val[" + (k++) + "]"; + a[j] = "val[" + k++ + "]"; } out += a + "]"; b[i] = out; @@ -107,7 +108,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { return out; } function isNumeric(obj) { - return isFinite(parseFloat(obj)); + return isFinite(obj); } function arrayEqual(arr1, arr2) { if (!Snap.is(arr1, "array") || !Snap.is(arr2, "array")) { @@ -121,13 +122,6 @@ Snap.plugin(function (Snap, Element, Paper, glob) { eve.on("snap.util.equal", function (name, b) { var A, B, a = Str(this.attr(name) || ""), el = this; - if (isNumeric(a) && isNumeric(b)) { - return { - from: parseFloat(a), - to: parseFloat(b), - f: getNumber - }; - } if (names[name] == "colour") { A = Snap.color(a); B = Snap.color(b); @@ -147,11 +141,14 @@ Snap.plugin(function (Snap, Element, Paper, glob) { }; } if (name == "transform" || name == "gradientTransform" || name == "patternTransform") { - if (b instanceof Snap.Matrix) { - b = b.toTransformString(); + if (typeof b == "string") { + b = Str(b).replace(/\.{3}|\u2026/g, a); } + a = this.matrix; if (!Snap._.rgTransform.test(b)) { - b = Snap._.svgTransform2string(b); + b = Snap._.transform2matrix(Snap._.svgTransform2string(b), this.getBBox()); + } else { + b = Snap._.transform2matrix(b, this.getBBox()); } return equaliseTransform(a, b, function () { return el.getBBox(1); @@ -174,6 +171,13 @@ Snap.plugin(function (Snap, Element, Paper, glob) { f: function (val) { return val; } }; } + if (isNumeric(a) && isNumeric(b)) { + return { + from: parseFloat(a), + to: parseFloat(b), + f: getNumber + }; + } var aUnit = a.match(reUnit), bUnit = Str(b).match(reUnit); if (aUnit && arrayEqual(aUnit, bUnit)) { diff --git a/src/filter.js b/src/filter.js index 6af88fc..705d3fa 100644 --- a/src/filter.js +++ b/src/filter.js @@ -1,11 +1,11 @@ // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -51,7 +51,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { paper.defs.appendChild(filter); return new Element(filter); }; - + eve.on("snap.util.getattr.filter", function () { eve.stop(); var p = $(this.node, "filter"); @@ -126,22 +126,23 @@ Snap.plugin(function (Snap, Element, Paper, glob) { - opacity (number) #optional `0..1` opacity of the shadow = (string) filter representation > Usage - | var f = paper.filter(Snap.filter.shadow(0, 2, 3)), + | var f = paper.filter(Snap.filter.shadow(0, 2, .3)), | c = paper.circle(10, 10, 10).attr({ | filter: f | }); \*/ Snap.filter.shadow = function (dx, dy, blur, color, opacity) { - if (typeof blur == "string") { - color = blur; - opacity = color; - blur = 4; + if (opacity == null) { + if (color == null) { + opacity = blur; + blur = 4; + color = "#000"; + } else { + opacity = color; + color = blur; + blur = 4; + } } - if (typeof color != "string") { - opacity = color; - color = "#000"; - } - color = color || "#000"; if (blur == null) { blur = 4; } diff --git a/src/matrix.js b/src/matrix.js index 957beda..b066e59 100644 --- a/src/matrix.js +++ b/src/matrix.js @@ -1,11 +1,11 @@ // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -58,30 +58,48 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { - matrix (object) @Matrix \*/ matrixproto.add = function (a, b, c, d, e, f) { - var out = [[], [], []], - m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]], - matrix = [[a, c, e], [b, d, f], [0, 0, 1]], - x, y, z, res; - if (a && a instanceof Matrix) { - matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]]; + return this.add(a.a, a.b, a.c, a.d, a.e, a.f); } + var aNew = a * this.a + b * this.c, + bNew = a * this.b + b * this.d; + this.e += e * this.a + f * this.c; + this.f += e * this.b + f * this.d; + this.c = c * this.a + d * this.c; + this.d = c * this.b + d * this.d; - for (x = 0; x < 3; x++) { - for (y = 0; y < 3; y++) { - res = 0; - for (z = 0; z < 3; z++) { - res += m[x][z] * matrix[z][y]; - } - out[x][y] = res; - } + this.a = aNew; + this.b = bNew; + return this; + }; + /*\ + * Matrix.multLeft + [ method ] + ** + * Multiplies a passed affine transform to the left: M * this. + - a (number) + - b (number) + - c (number) + - d (number) + - e (number) + - f (number) + * or + - matrix (object) @Matrix + \*/ + Matrix.prototype.multLeft = function (a, b, c, d, e, f) { + if (a && a instanceof Matrix) { + return this.multLeft(a.a, a.b, a.c, a.d, a.e, a.f); } - this.a = out[0][0]; - this.b = out[1][0]; - this.c = out[0][1]; - this.d = out[1][1]; - this.e = out[0][2]; - this.f = out[1][2]; + var aNew = a * this.a + c * this.b, + cNew = a * this.c + c * this.d, + eNew = a * this.e + c * this.f + e; + this.b = b * this.a + d * this.b; + this.d = b * this.c + d * this.d; + this.f = b * this.e + d * this.f + f; + + this.a = aNew; + this.c = cNew; + this.e = eNew; return this; }; /*\ @@ -115,7 +133,9 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { - y (number) vertical offset distance \*/ matrixproto.translate = function (x, y) { - return this.add(1, 0, 0, 1, x, y); + this.e += x * this.a + y * this.c; + this.f += x * this.b + y * this.d; + return this; }; /*\ * Matrix.scale @@ -130,9 +150,12 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { \*/ matrixproto.scale = function (x, y, cx, cy) { y == null && (y = x); - (cx || cy) && this.add(1, 0, 0, 1, cx, cy); - this.add(x, 0, 0, y, 0, 0); - (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy); + (cx || cy) && this.translate(cx, cy); + this.a *= x; + this.b *= x; + this.c *= y; + this.d *= y; + (cx || cy) && this.translate(-cx, -cy); return this; }; /*\ @@ -153,6 +176,43 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { this.add(cos, sin, -sin, cos, x, y); return this.add(1, 0, 0, 1, -x, -y); }; + /*\ + * Matrix.skewX + [ method ] + ** + * Skews the matrix along the x-axis + - x (number) Angle to skew along the x-axis (in degrees). + \*/ + matrixproto.skewX = function (x) { + return this.skew(x, 0); + }; + /*\ + * Matrix.skewY + [ method ] + ** + * Skews the matrix along the y-axis + - y (number) Angle to skew along the y-axis (in degrees). + \*/ + matrixproto.skewY = function (y) { + return this.skew(0, y); + }; + /*\ + * Matrix.skew + [ method ] + ** + * Skews the matrix + - y (number) Angle to skew along the y-axis (in degrees). + - x (number) Angle to skew along the x-axis (in degrees). + \*/ + matrixproto.skew = function (x, y) { + x = x || 0; + y = y || 0; + x = Snap.rad(x); + y = Snap.rad(y); + var c = math.tan(x).toFixed(9); + var b = math.tan(y).toFixed(9); + return this.add(1, b, c, 1, 0, 0); + }; /*\ * Matrix.x [ method ] @@ -225,7 +285,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { out.dy = this.f; // scale and shear - var row = [[this.a, this.c], [this.b, this.d]]; + var row = [[this.a, this.b], [this.c, this.d]]; out.scalex = math.sqrt(norm(row[0])); normalize(row[0]); @@ -241,7 +301,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { } // rotation - var sin = -row[0][1], + var sin = row[0][1], cos = row[1][1]; if (cos < 0) { out.rotate = Snap.deg(math.acos(cos)); @@ -270,9 +330,9 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { s.scalex = +s.scalex.toFixed(4); s.scaley = +s.scaley.toFixed(4); s.rotate = +s.rotate.toFixed(4); - return (s.dx || s.dy ? "t" + [+s.dx.toFixed(4), +s.dy.toFixed(4)] : E) + - (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) + - (s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E); + return (s.dx || s.dy ? "t" + [+s.dx.toFixed(4), +s.dy.toFixed(4)] : E) + + (s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E) + + (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E); } else { return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)]; } @@ -306,4 +366,4 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { Snap.matrix = function (a, b, c, d, e, f) { return new Matrix(a, b, c, d, e, f); }; -}); \ No newline at end of file +}); diff --git a/src/mina.js b/src/mina.js index 9d4d500..8b967a9 100644 --- a/src/mina.js +++ b/src/mina.js @@ -1,11 +1,11 @@ -// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// Copyright (c) 2017 Adobe Systems Incorporated. All rights reserved. +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,8 +19,10 @@ var mina = (function (eve) { window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { - setTimeout(callback, 16); + setTimeout(callback, 16, new Date().getTime()); + return true; }, + requestID, isArray = Array.isArray || function (a) { return a instanceof Array || Object.prototype.toString.call(a) == "[object Array]"; @@ -94,6 +96,7 @@ var mina = (function (eve) { a.b = a.get() - a.pdif; delete a.pdif; animations[a.id] = a; + frame(); }, update = function () { var a = this, @@ -109,7 +112,16 @@ var mina = (function (eve) { } a.set(res); }, - frame = function () { + frame = function (timeStamp) { + // Manual invokation? + if (!timeStamp) { + // Frame loop stopped? + if (!requestID) { + // Start frame loop... + requestID = requestAnimFrame(frame); + } + return; + } var len = 0; for (var i in animations) if (animations.hasOwnProperty(i)) { var a = animations[i], @@ -129,7 +141,7 @@ var mina = (function (eve) { } a.update(); } - len && requestAnimFrame(frame); + requestID = len ? requestAnimFrame(frame) : false; }, /*\ * mina @@ -140,7 +152,7 @@ var mina = (function (eve) { - a (number) start _slave_ number - A (number) end _slave_ number - b (number) start _master_ number (start time in general case) - - B (number) end _master_ number (end time in gereal case) + - B (number) end _master_ number (end time in general case) - get (function) getter of _master_ number (see @mina.time) - set (function) setter of _slave_ number - easing (function) #optional easing function, default is @mina.linear @@ -193,7 +205,7 @@ var mina = (function (eve) { break; } } - len == 1 && requestAnimFrame(frame); + len == 1 && frame(); return anim; }; /*\ @@ -333,18 +345,18 @@ var mina = (function (eve) { var s = 7.5625, p = 2.75, l; - if (n < (1 / p)) { + if (n < 1 / p) { l = s * n * n; } else { - if (n < (2 / p)) { - n -= (1.5 / p); + if (n < 2 / p) { + n -= 1.5 / p; l = s * n * n + .75; } else { - if (n < (2.5 / p)) { - n -= (2.25 / p); + if (n < 2.5 / p) { + n -= 2.25 / p; l = s * n * n + .9375; } else { - n -= (2.625 / p); + n -= 2.625 / p; l = s * n * n + .984375; } } @@ -353,4 +365,4 @@ var mina = (function (eve) { }; window.mina = mina; return mina; -})(typeof eve == "undefined" ? function () {} : eve); \ No newline at end of file +})(typeof eve == "undefined" ? function () {} : eve); diff --git a/src/paper.js b/src/paper.js index 30293f7..1cdbf03 100644 --- a/src/paper.js +++ b/src/paper.js @@ -1,11 +1,11 @@ // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -512,9 +512,27 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { (function () { var $ = Snap._.$; // gradients' helpers + /*\ + * Element.stops + [ method ] + ** + * Only for gradients! + * Returns array of gradient stops elements. + = (array) the stops array. + \*/ function Gstops() { return this.selectAll("stop"); } + /*\ + * Element.addStop + [ method ] + ** + * Only for gradients! + * Adds another stop to the gradient. + - color (string) stops color + - offset (number) stops offset 0..100 + = (object) gradient element + \*/ function GaddStop(color, offset) { var stop = $("stop"), attr = { @@ -526,7 +544,19 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { attr["stop-opacity"] = color.opacity; } $(stop, attr); - this.node.appendChild(stop); + var stops = this.stops(), + inserted; + for (var i = 0; i < stops.length; i++) { + var stopOffset = parseFloat(stops[i].attr("offset")); + if (stopOffset > offset) { + this.node.insertBefore(stop, stops[i].node); + inserted = true; + break; + } + } + if (!inserted) { + this.node.appendChild(stop); + } return this; } function GgetBBox() { @@ -543,6 +573,44 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { return Snap._.box(cx - r, cy - r, r * 2, r * 2); } } + /*\ + * Element.setStops + [ method ] + ** + * Only for gradients! + * Updates stops of the gradient based on passed gradient descriptor. See @Ppaer.gradient + - str (string) gradient descriptor part after `()`. + = (object) gradient element + | var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff"); + | g.setStops("#fff-#000-#f00-#fc0"); + \*/ + function GsetStops(str) { + var grad = str, + stops = this.stops(); + if (typeof str == "string") { + grad = eve("snap.util.grad.parse", null, "l(0,0,0,1)" + str).firstDefined().stops; + } + if (!Snap.is(grad, "array")) { + return; + } + for (var i = 0; i < stops.length; i++) { + if (grad[i]) { + var color = Snap.color(grad[i].color), + attr = {"offset": grad[i].offset + "%"}; + attr["stop-color"] = color.hex; + if (color.opacity < 1) { + attr["stop-opacity"] = color.opacity; + } + stops[i].attr(attr); + } else { + stops[i].remove(); + } + } + for (i = stops.length; i < grad.length; i++) { + this.addStop(grad[i].color, grad[i].offset); + } + return this; + } function gradient(defs, str) { var grad = eve("snap.util.grad.parse", null, str).firstDefined(), el; @@ -561,24 +629,8 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { }); } var stops = grad.stops, - len = stops.length, - start = 0, - j = 0; - function seed(i, end) { - var step = (end - start) / (i - j); - for (var k = j; k < i; k++) { - stops[k].offset = +(+start + step * (k - j)).toFixed(2); - } - j = i; - start = end; - } - len--; - for (var i = 0; i < len; i++) if ("offset" in stops[i]) { - seed(i, stops[i].offset); - } - stops[len].offset = stops[len].offset || 100; - seed(len, stops[len].offset); - for (i = 0; i <= len; i++) { + len = stops.length; + for (var i = 0; i < len; i++) { var stop = stops[i]; el.addStop(stop.color, stop.offset); } @@ -589,6 +641,7 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) { el.stops = Gstops; el.addStop = GaddStop; el.getBBox = GgetBBox; + el.setStops = GsetStops; if (x1 != null) { $(el.node, { x1: x1, diff --git a/src/path.js b/src/path.js index d3fd637..708752b 100644 --- a/src/path.js +++ b/src/path.js @@ -1,11 +1,11 @@ // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -165,7 +165,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { ay = t1 * p1y + t * c1y, cx = t1 * c2x + t * p2x, cy = t1 * c2y + t * p2y, - alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI); + alpha = 90 - math.atan2(mx - nx, my - ny) * 180 / PI; // (mx > nx || my < ny) && (alpha += 180); return { x: x, @@ -420,7 +420,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { return box(); } path = path2curve(path); - var x = 0, + var x = 0, y = 0, X = [], Y = [], @@ -451,7 +451,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { function rectPath(x, y, w, h, r) { if (r) { return [ - ["M", +x + (+r), y], + ["M", +x + +r, y], ["l", w - r * 2, 0], ["a", r, r, 0, 0, 1, r, r], ["l", 0, h - r * 2], @@ -575,7 +575,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { my = pa[2]; default: for (var j = 1, jj = pa.length; j < jj; j++) { - r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3); + r[j] = +(pa[j] - (j % 2 ? x : y)).toFixed(3); } } } else { @@ -686,7 +686,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { my = +pa[2] + y; default: for (j = 1, jj = pa.length; j < jj; j++) { - r[j] = +pa[j] + ((j % 2) ? x : y); + r[j] = +pa[j] + (j % 2 ? x : y); } } } else if (pa0 == "R") { @@ -761,6 +761,9 @@ Snap.plugin(function (Snap, Element, Paper, glob) { Y = x * math.sin(rad) + y * math.cos(rad); return {x: X, y: Y}; }); + if (!rx || !ry) { + return [x1, y1, x2, y2, x2, y2]; + } if (!recursive) { xy = rotate(x1, y1, -rad); x1 = xy.x; @@ -772,7 +775,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { sin = math.sin(PI / 180 * angle), x = (x1 - x2) / 2, y = (y1 - y2) / 2; - var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); + var h = x * x / (rx * rx) + y * y / (ry * ry); if (h > 1) { h = math.sqrt(h); rx = h * rx; @@ -845,7 +848,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) { y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y }; } - + // Returns bounding box of cubic bezier curve. // Source: http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html // Original version: NISHIO Hirokazu @@ -895,8 +898,8 @@ Snap.plugin(function (Snap, Element, Paper, glob) { while (j--) { t = tvalues[j]; mt = 1 - t; - bounds[0][j] = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3); - bounds[1][j] = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3); + bounds[0][j] = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3; + bounds[1][j] = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3; } bounds[0][jlen] = x0; diff --git a/src/set.js b/src/set.js index 6ad9bda..b2951d8 100644 --- a/src/set.js +++ b/src/set.js @@ -1,11 +1,11 @@ // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -142,6 +142,14 @@ Snap.plugin(function (Snap, Element, Paper, glob) { } }); }; + /*\ + * Set.remove + [ method ] + ** + * Removes all children of the set. + * + = (object) Set object + \*/ setproto.remove = function () { while (this.length) { this.pop().remove(); @@ -180,6 +188,13 @@ Snap.plugin(function (Snap, Element, Paper, glob) { } return this; }; + /*\ + * Set.attr + [ method ] + ** + * Equivalent of @Element.attr. + = (object) Set object + \*/ setproto.attr = function (value) { var unbound = {}; for (var k in value) { @@ -258,6 +273,15 @@ Snap.plugin(function (Snap, Element, Paper, glob) { } return false; }; + /*\ + * Set.insertAfter + [ method ] + ** + * Inserts set elements after given element. + ** + - element (object) set will be inserted after this element + = (object) Set object + \*/ setproto.insertAfter = function (el) { var i = this.items.length; while (i--) { @@ -265,6 +289,13 @@ Snap.plugin(function (Snap, Element, Paper, glob) { } return this; }; + /*\ + * Set.getBBox + [ method ] + ** + * Union of all bboxes of the set. See @Element.getBBox. + = (object) bounding box descriptor. See @Element.getBBox. + \*/ setproto.getBBox = function () { var x = [], y = [], @@ -292,6 +323,14 @@ Snap.plugin(function (Snap, Element, Paper, glob) { cy: y + (y2 - y) / 2 }; }; + /*\ + * Set.insertAfter + [ method ] + ** + * Creates a clone of the set. + ** + = (object) New Set object + \*/ setproto.clone = function (s) { s = new Set; for (var i = 0, ii = this.items.length; i < ii; i++) { @@ -304,7 +343,24 @@ Snap.plugin(function (Snap, Element, Paper, glob) { }; setproto.type = "set"; // export + /*\ + * Snap.Set + [ property ] + ** + * Set constructor. + \*/ Snap.Set = Set; + /*\ + * Snap.set + [ method ] + ** + * Creates a set and fills it with list of arguments. + ** + = (object) New Set object + | var r = paper.rect(0, 0, 10, 10), + | s1 = Snap.set(), // empty set + | s2 = Snap.set(r, paper.circle(100, 100, 20)); // prefilled set + \*/ Snap.set = function () { var set = new Set; if (arguments.length) { diff --git a/src/svg.js b/src/svg.js index a7f77a6..da4a9c3 100644 --- a/src/svg.js +++ b/src/svg.js @@ -1,4 +1,4 @@ -// Copyright (c) 2013 - 2015 Adobe Systems Incorporated. All rights reserved. +// Copyright (c) 2013 - 2017 Adobe Systems Incorporated. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ // limitations under the License. var Snap = (function(root) { -Snap.version = "0.4.1"; +Snap.version = "0.5.0"; /*\ * Snap [ method ] @@ -76,14 +76,13 @@ var has = "hasOwnProperty", ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i, colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i, bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/, - reURLValue = /^url\(#?([^)]+)\)$/, separator = Snap._.separator = /[,\s]+/, whitespace = /[\s]/g, commaSpaces = /[\s]*,[\s]*/, hsrg = {hs: 1, rg: 1}, pathCommand = /([a-z])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/ig, tCommand = /([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/ig, - pathValues = /(-?\d*\.?\d*(?:e[\-+]?\\d+)?)[\s]*,?[\s]*/ig, + pathValues = /(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\s]*,?[\s]*/ig, idgen = 0, idprefix = "S" + (+new Date).toString(36), ID = function (el) { @@ -92,6 +91,14 @@ var has = "hasOwnProperty", xlink = "http://www.w3.org/1999/xlink", xmlns = "http://www.w3.org/2000/svg", hub = {}, + /*\ + * Snap.url + [ method ] + ** + * Wraps path into `"url('')"`. + - value (string) path + = (string) wrapped path + \*/ URL = Snap.url = function (url) { return "url('#" + url + "')"; }; @@ -171,9 +178,9 @@ function is(o, type) { (o instanceof Array || Array.isArray && Array.isArray(o))) { return true; } - return (type == "null" && o === null) || - (type == typeof o && o !== null) || - (type == "object" && o === Object(o)) || + return type == "null" && o === null || + type == typeof o && o !== null || + type == "object" && o === Object(o) || objectToString.call(o).slice(8, -1).toLowerCase() == type; } /*\ @@ -379,7 +386,6 @@ Snap.atan2 = function (num) { [ method ] ** * Returns an angle between two or three points - > Parameters - x1 (number) x coord of first point - y1 (number) y coord of first point - x2 (number) x coord of second point @@ -394,7 +400,6 @@ Snap.angle = angle; [ method ] ** * Returns distance between two points - > Parameters - x1 (number) x coord of first point - y1 (number) y coord of first point - x2 (number) x coord of second point @@ -409,7 +414,6 @@ Snap.len = function (x1, y1, x2, y2) { [ method ] ** * Returns squared distance between two points - > Parameters - x1 (number) x coord of first point - y1 (number) y coord of first point - x2 (number) x coord of second point @@ -424,7 +428,6 @@ Snap.len2 = function (x1, y1, x2, y2) { [ method ] ** * Returns closest point to a given one on a given path. - > Parameters - path (Element) path element - x (number) x coord of a point - y (number) y coord of a point @@ -453,7 +456,9 @@ Snap.closestPoint = function (path, x, y) { // linear scan for coarse approximation for (var scan, scanLength = 0, scanDistance; scanLength <= pathLength; scanLength += precision) { if ((scanDistance = distance2(scan = pathNode.getPointAtLength(scanLength))) < bestDistance) { - best = scan, bestLength = scanLength, bestDistance = scanDistance; + best = scan; + bestLength = scanLength; + bestDistance = scanDistance; } } @@ -467,9 +472,13 @@ Snap.closestPoint = function (path, x, y) { beforeDistance, afterDistance; if ((beforeLength = bestLength - precision) >= 0 && (beforeDistance = distance2(before = pathNode.getPointAtLength(beforeLength))) < bestDistance) { - best = before, bestLength = beforeLength, bestDistance = beforeDistance; + best = before; + bestLength = beforeLength; + bestDistance = beforeDistance; } else if ((afterLength = bestLength + precision) <= pathLength && (afterDistance = distance2(after = pathNode.getPointAtLength(afterLength))) < bestDistance) { - best = after, bestLength = afterLength, bestDistance = afterDistance; + best = after; + bestLength = afterLength; + bestDistance = afterDistance; } else { precision *= .5; } @@ -628,7 +637,7 @@ Snap.getRGB = cacher(function (colour) { blue = mmin(math.round(blue), 255); opacity = mmin(mmax(opacity, 0), 1); rgb = {r: red, g: green, b: blue, toString: rgbtoString}; - rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1); + rgb.hex = "#" + (16777216 | blue | green << 8 | red << 16).toString(16).slice(1); rgb.opacity = is(opacity, "finite") ? opacity : 1; return rgb; } @@ -675,7 +684,7 @@ Snap.rgb = cacher(function (r, g, b, o) { var round = math.round; return "rgba(" + [round(r), round(g), round(b), +o.toFixed(2)] + ")"; } - return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1); + return "#" + (16777216 | b | g << 8 | r << 16).toString(16).slice(1); }); var toHex = function (color) { var i = glob.doc.getElementsByTagName("head")[0] || glob.doc.getElementsByTagName("svg")[0], @@ -817,7 +826,7 @@ Snap.hsb2rgb = function (h, s, v, o) { } h *= 360; var R, G, B, X, C; - h = (h % 360) / 60; + h = h % 360 / 60; C = v * s; X = C * (1 - abs(h % 2 - 1)); R = G = B = v - C; @@ -857,7 +866,7 @@ Snap.hsl2rgb = function (h, s, l, o) { } h *= 360; var R, G, B, X, C; - h = (h % 360) / 60; + h = h % 360 / 60; C = 2 * s * (l < .5 ? l : 1 - l); X = C * (1 - abs(h % 2 - 1)); R = G = B = l - C / 2; @@ -892,12 +901,11 @@ Snap.rgb2hsb = function (r, g, b) { var H, S, V, C; V = mmax(r, g, b); C = V - mmin(r, g, b); - H = (C == 0 ? null : - V == r ? (g - b) / C : - V == g ? (b - r) / C + 2 : - (r - g) / C + 4 - ); - H = ((H + 360) % 6) * 60 / 360; + H = C == 0 ? null : + V == r ? (g - b) / C : + V == g ? (b - r) / C + 2 : + (r - g) / C + 4; + H = (H + 360) % 6 * 60 / 360; S = C == 0 ? 0 : C / V; return {h: H, s: S, b: V, toString: hsbtoString}; }; @@ -926,15 +934,15 @@ Snap.rgb2hsl = function (r, g, b) { M = mmax(r, g, b); m = mmin(r, g, b); C = M - m; - H = (C == 0 ? null : - M == r ? (g - b) / C : - M == g ? (b - r) / C + 2 : - (r - g) / C + 4); - H = ((H + 360) % 6) * 60 / 360; + H = C == 0 ? null : + M == r ? (g - b) / C : + M == g ? (b - r) / C + 2 : + (r - g) / C + 4; + H = (H + 360) % 6 * 60 / 360; L = (M + m) / 2; - S = (C == 0 ? 0 : + S = C == 0 ? 0 : L < .5 ? C / (2 * L) : - C / (2 - 2 * L)); + C / (2 - 2 * L); return {h: H, s: S, l: L, toString: hsltoString}; }; @@ -1146,8 +1154,8 @@ var contains = glob.doc.contains || glob.doc.compareDocumentPosition ? return false; }; function getSomeDefs(el) { - var p = (el.node.ownerSVGElement && wrap(el.node.ownerSVGElement)) || - (el.node.parentNode && wrap(el.node.parentNode)) || + var p = el.node.ownerSVGElement && wrap(el.node.ownerSVGElement) || + el.node.parentNode && wrap(el.node.parentNode) || Snap.select("svg") || Snap(0, 0), pdefs = p.select("defs"), @@ -1492,7 +1500,7 @@ function Paper(w, h) { desc, defs, proto = Paper.prototype; - if (w && w.tagName == "svg") { + if (w && w.tagName && w.tagName.toLowerCase() == "svg") { if (w.snap in hub) { return hub[w.snap]; } @@ -1744,7 +1752,7 @@ Snap.ajax = function (url, postData, callback, scope){ } postData = pd.join("&"); } - req.open((postData ? "POST" : "GET"), url, true); + req.open(postData ? "POST" : "GET", url, true); if (postData) { req.setRequestHeader("X-Requested-With", "XMLHttpRequest"); req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); diff --git a/template.dot b/template.dot index f92c011..34923a6 100644 --- a/template.dot +++ b/template.dot @@ -8,7 +8,6 @@ - @@ -24,9 +23,9 @@ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); - function trackOutboundLink(link, category, action) { - try { - _gaq.push(['_trackEvent', category , action]); + function trackOutboundLink(link, category, action) { + try { + _gaq.push(['_trackEvent', category , action]); } catch(err){} setTimeout(function() { @@ -50,7 +49,7 @@ Docs Support Demos - Download + Download
    @@ -62,7 +61,7 @@
    - +