Mercurial > laserkard
view awesome_js/raphael.js @ 77:bf68c9ea9528 laserkard
saving
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 22 Jul 2010 09:30:45 -0400 |
parents | 7742910e0479 |
children |
line wrap: on
line source
1 /*!2 * Raphael 1.3.0 - JavaScript Vector Library3 *4 * Copyright (c) 2008 - 2009 Dmitry Baranovskiy (http://raphaeljs.com)5 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.6 */9 window.Raphael = (function () {10 var separator = /[, ]+/,11 elements = /^(circle|rect|path|ellipse|text|image)$/,12 doc = document,13 win = window,14 oldRaphael = {15 was: "Raphael" in win,16 is: win.Raphael17 },18 R = function () {19 if (R.is(arguments[0], "array")) {20 var a = arguments[0],21 cnv = create[apply](R, a.splice(0, 3 + R.is(a[0], nu))),22 res = cnv.set();23 for (var i = 0, ii = a[length]; i < ii; i++) {24 var j = a[i] || {};25 elements.test(j.type) && res[push](cnv[j.type]().attr(j));26 }27 return res;28 }29 return create[apply](R, arguments);30 },31 Paper = function () {},32 appendChild = "appendChild",33 apply = "apply",34 concat = "concat",35 E = "",36 S = " ",37 split = "split",38 events = "click dblclick mousedown mousemove mouseout mouseover mouseup"[split](S),39 has = "hasOwnProperty",40 join = "join",41 length = "length",42 proto = "prototype",43 lowerCase = String[proto].toLowerCase,44 math = Math,45 mmax = math.max,46 mmin = math.min,47 nu = "number",48 toString = "toString",49 objectToString = Object[proto][toString],50 paper = {},51 pow = math.pow,52 push = "push",53 rg = /^(?=[\da-f]$)/,54 ISURL = /^url\(['"]?([^\)]+)['"]?\)$/i,55 colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgb\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|rgb\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\)|hs[bl]\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|hs[bl]\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\))\s*$/i,56 round = math.round,57 setAttribute = "setAttribute",58 toFloat = parseFloat,59 toInt = parseInt,60 upperCase = String[proto].toUpperCase,61 availableAttrs = {"clip-rect": "0 0 1e9 1e9", cursor: "default", cx: 0, cy: 0, fill: "#fff", "fill-opacity": 1, font: '10px "Arial"', "font-family": '"Arial"', "font-size": "10", "font-style": "normal", "font-weight": 400, gradient: 0, height: 0, href: "http://raphaeljs.com/", opacity: 1, path: "M0,0", r: 0, rotation: 0, rx: 0, ry: 0, scale: "1 1", src: "", stroke: "#000", "stroke-dasharray": "", "stroke-linecap": "butt", "stroke-linejoin": "butt", "stroke-miterlimit": 0, "stroke-opacity": 1, "stroke-width": 1, target: "_blank", "text-anchor": "middle", title: "Raphael", translation: "0 0", width: 0, x: 0, y: 0},62 availableAnimAttrs = {along: "along", "clip-rect": "csv", cx: nu, cy: nu, fill: "colour", "fill-opacity": nu, "font-size": nu, height: nu, opacity: nu, path: "path", r: nu, rotation: "csv", rx: nu, ry: nu, scale: "csv", stroke: "colour", "stroke-opacity": nu, "stroke-width": nu, translation: "csv", width: nu, x: nu, y: nu},63 rp = "replace";64 R.version = "1.3.0";65 R.type = (win.SVGAngle || doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML");66 if (R.type == "VML") {67 var d = document.createElement("div");68 d.innerHTML = '<!--[if vml]><br><br><![endif]-->';69 if (d.childNodes[length] != 2) {70 return null;71 }72 }73 R.svg = !(R.vml = R.type == "VML");74 Paper[proto] = R[proto];75 R._id = 0;76 R._oid = 0;77 R.fn = {};78 R.is = function (o, type) {79 type = lowerCase.call(type);80 return ((type == "object" || type == "undefined") && typeof o == type) || (o == null && type == "null") || lowerCase.call(objectToString.call(o).slice(8, -1)) == type;81 };82 R.setWindow = function (newwin) {83 win = newwin;84 doc = win.document;85 };86 // colour utilities87 var toHex = function (color) {88 if (R.vml) {89 // http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/90 var trim = /^\s+|\s+$/g;91 toHex = cacher(function (color) {92 var bod;93 color = (color + E)[rp](trim, E);94 try {95 var docum = new ActiveXObject("htmlfile");96 docum.write("<body>");97 docum.close();98 bod = docum.body;99 } catch(e) {100 bod = createPopup().document.body;101 }102 var range = bod.createTextRange();103 try {104 bod.style.color = color;105 var value = range.queryCommandValue("ForeColor");106 value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16);107 return "#" + ("000000" + value[toString](16)).slice(-6);108 } catch(e) {109 return "none";110 }111 });112 } else {113 var i = doc.createElement("i");114 i.title = "Rapha\xebl Colour Picker";115 i.style.display = "none";116 doc.body[appendChild](i);117 toHex = cacher(function (color) {118 i.style.color = color;119 return doc.defaultView.getComputedStyle(i, E).getPropertyValue("color");120 });121 }122 return toHex(color);123 };124 R.hsb2rgb = cacher(function (hue, saturation, brightness) {125 if (R.is(hue, "object") && "h" in hue && "s" in hue && "b" in hue) {126 brightness = hue.b;127 saturation = hue.s;128 hue = hue.h;129 }130 var red,131 green,132 blue;133 if (brightness == 0) {134 return {r: 0, g: 0, b: 0, hex: "#000"};135 }136 if (hue > 1 || saturation > 1 || brightness > 1) {137 hue /= 255;138 saturation /= 255;139 brightness /= 255;140 }141 var i = ~~(hue * 6),142 f = (hue * 6) - i,143 p = brightness * (1 - saturation),144 q = brightness * (1 - (saturation * f)),145 t = brightness * (1 - (saturation * (1 - f)));146 red = [brightness, q, p, p, t, brightness, brightness][i];147 green = [t, brightness, brightness, q, p, p, t][i];148 blue = [p, p, t, brightness, brightness, q, p][i];149 red *= 255;150 green *= 255;151 blue *= 255;152 var rgb = {r: red, g: green, b: blue},153 r = (~~red)[toString](16),154 g = (~~green)[toString](16),155 b = (~~blue)[toString](16);156 r = r[rp](rg, "0");157 g = g[rp](rg, "0");158 b = b[rp](rg, "0");159 rgb.hex = "#" + r + g + b;160 return rgb;161 }, R);162 R.rgb2hsb = cacher(function (red, green, blue) {163 if (R.is(red, "object") && "r" in red && "g" in red && "b" in red) {164 blue = red.b;165 green = red.g;166 red = red.r;167 }168 if (R.is(red, "string")) {169 var clr = R.getRGB(red);170 red = clr.r;171 green = clr.g;172 blue = clr.b;173 }174 if (red > 1 || green > 1 || blue > 1) {175 red /= 255;176 green /= 255;177 blue /= 255;178 }179 var max = mmax(red, green, blue),180 min = mmin(red, green, blue),181 hue,182 saturation,183 brightness = max;184 if (min == max) {185 return {h: 0, s: 0, b: max};186 } else {187 var delta = (max - min);188 saturation = delta / max;189 if (red == max) {190 hue = (green - blue) / delta;191 } else if (green == max) {192 hue = 2 + ((blue - red) / delta);193 } else {194 hue = 4 + ((red - green) / delta);195 }196 hue /= 6;197 hue < 0 && hue++;198 hue > 1 && hue--;199 }200 return {h: hue, s: saturation, b: brightness};201 }, R);202 var p2s = /,?([achlmqrstvxz]),?/gi;203 R._path2string = function () {204 return this.join(",")[rp](p2s, "$1");205 };206 function cacher(f, scope, postprocessor) {207 function newf() {208 var arg = Array[proto].slice.call(arguments, 0),209 args = arg[join]("\u25ba"),210 cache = newf.cache = newf.cache || {},211 count = newf.count = newf.count || [];212 if (cache[has](args)) {213 return postprocessor ? postprocessor(cache[args]) : cache[args];214 }215 count[length] >= 1e3 && delete cache[count.shift()];216 count[push](args);217 cache[args] = f[apply](scope, arg);218 return postprocessor ? postprocessor(cache[args]) : cache[args];219 }220 return newf;221 }223 R.getRGB = cacher(function (colour) {224 if (!colour || !!((colour = colour + E).indexOf("-") + 1)) {225 return {r: -1, g: -1, b: -1, hex: "none", error: 1};226 }227 if (colour == "none") {228 return {r: -1, g: -1, b: -1, hex: "none"};229 }230 !(({hs: 1, rg: 1})[has](colour.substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour));231 var res,232 red,233 green,234 blue,235 t,236 rgb = colour.match(colourRegExp);237 if (rgb) {238 if (rgb[2]) {239 blue = toInt(rgb[2].substring(5), 16);240 green = toInt(rgb[2].substring(3, 5), 16);241 red = toInt(rgb[2].substring(1, 3), 16);242 }243 if (rgb[3]) {244 blue = toInt((t = rgb[3].charAt(3)) + t, 16);245 green = toInt((t = rgb[3].charAt(2)) + t, 16);246 red = toInt((t = rgb[3].charAt(1)) + t, 16);247 }248 if (rgb[4]) {249 rgb = rgb[4][split](/\s*,\s*/);250 red = toFloat(rgb[0]);251 green = toFloat(rgb[1]);252 blue = toFloat(rgb[2]);253 }254 if (rgb[5]) {255 rgb = rgb[5][split](/\s*,\s*/);256 red = toFloat(rgb[0]) * 2.55;257 green = toFloat(rgb[1]) * 2.55;258 blue = toFloat(rgb[2]) * 2.55;259 }260 if (rgb[6]) {261 rgb = rgb[6][split](/\s*,\s*/);262 red = toFloat(rgb[0]);263 green = toFloat(rgb[1]);264 blue = toFloat(rgb[2]);265 return R.hsb2rgb(red, green, blue);266 }267 if (rgb[7]) {268 rgb = rgb[7][split](/\s*,\s*/);269 red = toFloat(rgb[0]) * 2.55;270 green = toFloat(rgb[1]) * 2.55;271 blue = toFloat(rgb[2]) * 2.55;272 return R.hsb2rgb(red, green, blue);273 }274 rgb = {r: red, g: green, b: blue};275 var r = (~~red)[toString](16),276 g = (~~green)[toString](16),277 b = (~~blue)[toString](16);278 r = r[rp](rg, "0");279 g = g[rp](rg, "0");280 b = b[rp](rg, "0");281 rgb.hex = "#" + r + g + b;282 return rgb;283 }284 return {r: -1, g: -1, b: -1, hex: "none", error: 1};285 }, R);286 R.getColor = function (value) {287 var start = this.getColor.start = this.getColor.start || {h: 0, s: 1, b: value || .75},288 rgb = this.hsb2rgb(start.h, start.s, start.b);289 start.h += .075;290 if (start.h > 1) {291 start.h = 0;292 start.s -= .2;293 start.s <= 0 && (this.getColor.start = {h: 0, s: 1, b: start.b});294 }295 return rgb.hex;296 };297 R.getColor.reset = function () {298 delete this.start;299 };300 // path utilities301 R.parsePathString = cacher(function (pathString) {302 if (!pathString) {303 return null;304 }305 var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0},306 data = [];307 if (R.is(pathString, "array") && R.is(pathString[0], "array")) { // rough assumption308 data = pathClone(pathString);309 }310 if (!data[length]) {311 (pathString + E)[rp](/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig, function (a, b, c) {312 var params = [],313 name = lowerCase.call(b);314 c[rp](/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig, function (a, b) {315 b && params[push](+b);316 });317 while (params[length] >= paramCounts[name]) {318 data[push]([b][concat](params.splice(0, paramCounts[name])));319 if (!paramCounts[name]) {320 break;321 };322 }323 });324 }325 data[toString] = R._path2string;326 return data;327 });328 R.findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {329 var t1 = 1 - t,330 x = pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,331 y = pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y,332 mx = p1x + 2 * t * (c1x - p1x) + t * t * (c2x - 2 * c1x + p1x),333 my = p1y + 2 * t * (c1y - p1y) + t * t * (c2y - 2 * c1y + p1y),334 nx = c1x + 2 * t * (c2x - c1x) + t * t * (p2x - 2 * c2x + c1x),335 ny = c1y + 2 * t * (c2y - c1y) + t * t * (p2y - 2 * c2y + c1y),336 ax = (1 - t) * p1x + t * c1x,337 ay = (1 - t) * p1y + t * c1y,338 cx = (1 - t) * c2x + t * p2x,339 cy = (1 - t) * c2y + t * p2y,340 alpha = (90 - math.atan((mx - nx) / (my - ny)) * 180 / math.PI);341 (mx > nx || my < ny) && (alpha += 180);342 return {x: x, y: y, m: {x: mx, y: my}, n: {x: nx, y: ny}, start: {x: ax, y: ay}, end: {x: cx, y: cy}, alpha: alpha};343 };344 var pathDimensions = cacher(function (path) {345 if (!path) {346 return {x: 0, y: 0, width: 0, height: 0};347 }348 path = path2curve(path);349 var x = 0,350 y = 0,351 X = [],352 Y = [],353 p;354 for (var i = 0, ii = path[length]; i < ii; i++) {355 p = path[i];356 if (p[0] == "M") {357 x = p[1];358 y = p[2];359 X[push](x);360 Y[push](y);361 } else {362 var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);363 X = X[concat](dim.min.x, dim.max.x);364 Y = Y[concat](dim.min.y, dim.max.y);365 x = p[5];366 y = p[6];367 }368 }369 var xmin = mmin[apply](0, X),370 ymin = mmin[apply](0, Y);371 return {372 x: xmin,373 y: ymin,374 width: mmax[apply](0, X) - xmin,375 height: mmax[apply](0, Y) - ymin376 };377 }),378 pathClone = function (pathArray) {379 var res = [];380 if (!R.is(pathArray, "array") || !R.is(pathArray && pathArray[0], "array")) { // rough assumption381 pathArray = R.parsePathString(pathArray);382 }383 for (var i = 0, ii = pathArray[length]; i < ii; i++) {384 res[i] = [];385 for (var j = 0, jj = pathArray[i][length]; j < jj; j++) {386 res[i][j] = pathArray[i][j];387 }388 }389 res[toString] = R._path2string;390 return res;391 },392 pathToRelative = cacher(function (pathArray) {393 if (!R.is(pathArray, "array") || !R.is(pathArray && pathArray[0], "array")) { // rough assumption394 pathArray = R.parsePathString(pathArray);395 }396 var res = [],397 x = 0,398 y = 0,399 mx = 0,400 my = 0,401 start = 0;402 if (pathArray[0][0] == "M") {403 x = pathArray[0][1];404 y = pathArray[0][2];405 mx = x;406 my = y;407 start++;408 res[push](["M", x, y]);409 }410 for (var i = start, ii = pathArray[length]; i < ii; i++) {411 var r = res[i] = [],412 pa = pathArray[i];413 if (pa[0] != lowerCase.call(pa[0])) {414 r[0] = lowerCase.call(pa[0]);415 switch (r[0]) {416 case "a":417 r[1] = pa[1];418 r[2] = pa[2];419 r[3] = pa[3];420 r[4] = pa[4];421 r[5] = pa[5];422 r[6] = +(pa[6] - x).toFixed(3);423 r[7] = +(pa[7] - y).toFixed(3);424 break;425 case "v":426 r[1] = +(pa[1] - y).toFixed(3);427 break;428 case "m":429 mx = pa[1];430 my = pa[2];431 default:432 for (var j = 1, jj = pa[length]; j < jj; j++) {433 r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3);434 }435 }436 } else {437 r = res[i] = [];438 if (pa[0] == "m") {439 mx = pa[1] + x;440 my = pa[2] + y;441 }442 for (var k = 0, kk = pa[length]; k < kk; k++) {443 res[i][k] = pa[k];444 }445 }446 var len = res[i][length];447 switch (res[i][0]) {448 case "z":449 x = mx;450 y = my;451 break;452 case "h":453 x += +res[i][len - 1];454 break;455 case "v":456 y += +res[i][len - 1];457 break;458 default:459 x += +res[i][len - 2];460 y += +res[i][len - 1];461 }462 }463 res[toString] = R._path2string;464 return res;465 }, 0, pathClone),466 pathToAbsolute = cacher(function (pathArray) {467 if (!R.is(pathArray, "array") || !R.is(pathArray && pathArray[0], "array")) { // rough assumption468 pathArray = R.parsePathString(pathArray);469 }470 var res = [],471 x = 0,472 y = 0,473 mx = 0,474 my = 0,475 start = 0;476 if (pathArray[0][0] == "M") {477 x = +pathArray[0][1];478 y = +pathArray[0][2];479 mx = x;480 my = y;481 start++;482 res[0] = ["M", x, y];483 }484 for (var i = start, ii = pathArray[length]; i < ii; i++) {485 var r = res[i] = [],486 pa = pathArray[i];487 if (pa[0] != upperCase.call(pa[0])) {488 r[0] = upperCase.call(pa[0]);489 switch (r[0]) {490 case "A":491 r[1] = pa[1];492 r[2] = pa[2];493 r[3] = pa[3];494 r[4] = pa[4];495 r[5] = pa[5];496 r[6] = +(pa[6] + x);497 r[7] = +(pa[7] + y);498 break;499 case "V":500 r[1] = +pa[1] + y;501 break;502 case "H":503 r[1] = +pa[1] + x;504 break;505 case "M":506 mx = +pa[1] + x;507 my = +pa[2] + y;508 default:509 for (var j = 1, jj = pa[length]; j < jj; j++) {510 r[j] = +pa[j] + ((j % 2) ? x : y);511 }512 }513 } else {514 for (var k = 0, kk = pa[length]; k < kk; k++) {515 res[i][k] = pa[k];516 }517 }518 switch (r[0]) {519 case "Z":520 x = mx;521 y = my;522 break;523 case "H":524 x = r[1];525 break;526 case "V":527 y = r[1];528 break;529 default:530 x = res[i][res[i][length] - 2];531 y = res[i][res[i][length] - 1];532 }533 }534 res[toString] = R._path2string;535 return res;536 }, null, pathClone),537 l2c = function (x1, y1, x2, y2) {538 return [x1, y1, x2, y2, x2, y2];539 },540 q2c = function (x1, y1, ax, ay, x2, y2) {541 var _13 = 1 / 3,542 _23 = 2 / 3;543 return [544 _13 * x1 + _23 * ax,545 _13 * y1 + _23 * ay,546 _13 * x2 + _23 * ax,547 _13 * y2 + _23 * ay,548 x2,549 y2550 ];551 },552 a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {553 // for more information of where this math came from visit:554 // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes555 var PI = math.PI,556 _120 = PI * 120 / 180,557 rad = PI / 180 * (+angle || 0),558 res = [],559 xy,560 rotate = cacher(function (x, y, rad) {561 var X = x * math.cos(rad) - y * math.sin(rad),562 Y = x * math.sin(rad) + y * math.cos(rad);563 return {x: X, y: Y};564 });565 if (!recursive) {566 xy = rotate(x1, y1, -rad);567 x1 = xy.x;568 y1 = xy.y;569 xy = rotate(x2, y2, -rad);570 x2 = xy.x;571 y2 = xy.y;572 var cos = math.cos(PI / 180 * angle),573 sin = math.sin(PI / 180 * angle),574 x = (x1 - x2) / 2,575 y = (y1 - y2) / 2;576 rx = mmax(rx, math.abs(x));577 ry = mmax(ry, math.abs(y));578 var rx2 = rx * rx,579 ry2 = ry * ry,580 k = (large_arc_flag == sweep_flag ? -1 : 1) *581 math.sqrt(math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),582 cx = k * rx * y / ry + (x1 + x2) / 2,583 cy = k * -ry * x / rx + (y1 + y2) / 2,584 f1 = math.asin(((y1 - cy) / ry).toFixed(7)),585 f2 = math.asin(((y2 - cy) / ry).toFixed(7));587 f1 = x1 < cx ? PI - f1 : f1;588 f2 = x2 < cx ? PI - f2 : f2;589 f1 < 0 && (f1 = PI * 2 + f1);590 f2 < 0 && (f2 = PI * 2 + f2);591 if (sweep_flag && f1 > f2) {592 f1 = f1 - PI * 2;593 }594 if (!sweep_flag && f2 > f1) {595 f2 = f2 - PI * 2;596 }597 } else {598 f1 = recursive[0];599 f2 = recursive[1];600 cx = recursive[2];601 cy = recursive[3];602 }603 var df = f2 - f1;604 if (math.abs(df) > _120) {605 var f2old = f2,606 x2old = x2,607 y2old = y2;608 f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);609 x2 = cx + rx * math.cos(f2);610 y2 = cy + ry * math.sin(f2);611 res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);612 }613 df = f2 - f1;614 var c1 = math.cos(f1),615 s1 = math.sin(f1),616 c2 = math.cos(f2),617 s2 = math.sin(f2),618 t = math.tan(df / 4),619 hx = 4 / 3 * rx * t,620 hy = 4 / 3 * ry * t,621 m1 = [x1, y1],622 m2 = [x1 + hx * s1, y1 - hy * c1],623 m3 = [x2 + hx * s2, y2 - hy * c2],624 m4 = [x2, y2];625 m2[0] = 2 * m1[0] - m2[0];626 m2[1] = 2 * m1[1] - m2[1];627 if (recursive) {628 return [m2, m3, m4][concat](res);629 } else {630 res = [m2, m3, m4][concat](res)[join]()[split](",");631 var newres = [];632 for (var i = 0, ii = res[length]; i < ii; i++) {633 newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;634 }635 return newres;636 }637 },638 findDotAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {639 var t1 = 1 - t;640 return {641 x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,642 y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y643 };644 },645 curveDim = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {646 var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x),647 b = 2 * (c1x - p1x) - 2 * (c2x - c1x),648 c = p1x - c1x,649 t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a,650 t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a,651 y = [p1y, p2y],652 x = [p1x, p2x],653 dot;654 math.abs(t1) > 1e12 && (t1 = .5);655 math.abs(t2) > 1e12 && (t2 = .5);656 if (t1 > 0 && t1 < 1) {657 dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);658 x[push](dot.x);659 y[push](dot.y);660 }661 if (t2 > 0 && t2 < 1) {662 dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);663 x[push](dot.x);664 y[push](dot.y);665 }666 a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y);667 b = 2 * (c1y - p1y) - 2 * (c2y - c1y);668 c = p1y - c1y;669 t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a;670 t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a;671 math.abs(t1) > 1e12 && (t1 = .5);672 math.abs(t2) > 1e12 && (t2 = .5);673 if (t1 > 0 && t1 < 1) {674 dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);675 x[push](dot.x);676 y[push](dot.y);677 }678 if (t2 > 0 && t2 < 1) {679 dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);680 x[push](dot.x);681 y[push](dot.y);682 }683 return {684 min: {x: mmin[apply](0, x), y: mmin[apply](0, y)},685 max: {x: mmax[apply](0, x), y: mmax[apply](0, y)}686 };687 }),688 path2curve = cacher(function (path, path2) {689 var p = pathToAbsolute(path),690 p2 = path2 && pathToAbsolute(path2),691 attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},692 attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},693 processPath = function (path, d) {694 var nx, ny;695 if (!path) {696 return ["C", d.x, d.y, d.x, d.y, d.x, d.y];697 }698 !(path[0] in {T:1, Q:1}) && (d.qx = d.qy = null);699 switch (path[0]) {700 case "M":701 d.X = path[1];702 d.Y = path[2];703 break;704 case "A":705 path = ["C"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1))));706 break;707 case "S":708 nx = d.x + (d.x - (d.bx || d.x));709 ny = d.y + (d.y - (d.by || d.y));710 path = ["C", nx, ny][concat](path.slice(1));711 break;712 case "T":713 d.qx = d.x + (d.x - (d.qx || d.x));714 d.qy = d.y + (d.y - (d.qy || d.y));715 path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));716 break;717 case "Q":718 d.qx = path[1];719 d.qy = path[2];720 path = ["C"][concat](q2c(d.x, d.y, path[1], path[2], path[3], path[4]));721 break;722 case "L":723 path = ["C"][concat](l2c(d.x, d.y, path[1], path[2]));724 break;725 case "H":726 path = ["C"][concat](l2c(d.x, d.y, path[1], d.y));727 break;728 case "V":729 path = ["C"][concat](l2c(d.x, d.y, d.x, path[1]));730 break;731 case "Z":732 path = ["C"][concat](l2c(d.x, d.y, d.X, d.Y));733 break;734 }735 return path;736 },737 fixArc = function (pp, i) {738 if (pp[i][length] > 7) {739 pp[i].shift();740 var pi = pp[i];741 while (pi[length]) {742 pp.splice(i++, 0, ["C"][concat](pi.splice(0, 6)));743 }744 pp.splice(i, 1);745 ii = mmax(p[length], p2 && p2[length] || 0);746 }747 },748 fixM = function (path1, path2, a1, a2, i) {749 if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") {750 path2.splice(i, 0, ["M", a2.x, a2.y]);751 a1.bx = 0;752 a1.by = 0;753 a1.x = path1[i][1];754 a1.y = path1[i][2];755 ii = mmax(p[length], p2 && p2[length] || 0);756 }757 };758 for (var i = 0, ii = mmax(p[length], p2 && p2[length] || 0); i < ii; i++) {759 p[i] = processPath(p[i], attrs);760 fixArc(p, i);761 p2 && (p2[i] = processPath(p2[i], attrs2));762 p2 && fixArc(p2, i);763 fixM(p, p2, attrs, attrs2, i);764 fixM(p2, p, attrs2, attrs, i);765 var seg = p[i],766 seg2 = p2 && p2[i],767 seglen = seg[length],768 seg2len = p2 && seg2[length];769 attrs.x = seg[seglen - 2];770 attrs.y = seg[seglen - 1];771 attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;772 attrs.by = toFloat(seg[seglen - 3]) || attrs.y;773 attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x);774 attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y);775 attrs2.x = p2 && seg2[seg2len - 2];776 attrs2.y = p2 && seg2[seg2len - 1];777 }778 return p2 ? [p, p2] : p;779 }, null, pathClone),780 parseDots = cacher(function (gradient) {781 var dots = [];782 for (var i = 0, ii = gradient[length]; i < ii; i++) {783 var dot = {},784 par = gradient[i].match(/^([^:]*):?([\d\.]*)/);785 dot.color = R.getRGB(par[1]);786 if (dot.color.error) {787 return null;788 }789 dot.color = dot.color.hex;790 par[2] && (dot.offset = par[2] + "%");791 dots[push](dot);792 }793 for (var i = 1, ii = dots[length] - 1; i < ii; i++) {794 if (!dots[i].offset) {795 var start = toFloat(dots[i - 1].offset || 0),796 end = 0;797 for (var j = i + 1; j < ii; j++) {798 if (dots[j].offset) {799 end = dots[j].offset;800 break;801 }802 }803 if (!end) {804 end = 100;805 j = ii;806 }807 end = toFloat(end);808 var d = (end - start) / (j - i + 1);809 for (; i < j; i++) {810 start += d;811 dots[i].offset = start + "%";812 }813 }814 }815 return dots;816 }),817 getContainer = function () {818 var container,819 x,820 y,821 width,822 height;823 if (R.is(arguments[0], "string") || R.is(arguments[0], "object")) {824 if (R.is(arguments[0], "string")) {825 container = doc.getElementById(arguments[0]);826 } else {827 container = arguments[0];828 }829 if (container.tagName) {830 if (arguments[1] == null) {831 return {832 container: container,833 width: container.style.pixelWidth || container.offsetWidth,834 height: container.style.pixelHeight || container.offsetHeight835 };836 } else {837 return {container: container, width: arguments[1], height: arguments[2]};838 }839 }840 } else if (R.is(arguments[0], nu) && arguments[length] > 3) {841 return {container: 1, x: arguments[0], y: arguments[1], width: arguments[2], height: arguments[3]};842 }843 },844 plugins = function (con, add) {845 var that = this;846 for (var prop in add) if (add[has](prop) && !(prop in con)) {847 switch (typeof add[prop]) {848 case "function":849 (function (f) {850 con[prop] = con === that ? f : function () { return f[apply](that, arguments); };851 })(add[prop]);852 break;853 case "object":854 con[prop] = con[prop] || {};855 plugins.call(this, con[prop], add[prop]);856 break;857 default:858 con[prop] = add[prop];859 break;860 }861 }862 },863 tear = function (el, paper) {864 el == paper.top && (paper.top = el.prev);865 el == paper.bottom && (paper.bottom = el.next);866 el.next && (el.next.prev = el.prev);867 el.prev && (el.prev.next = el.next);868 },869 tofront = function (el, paper) {870 if (paper.top === el) {871 return;872 }873 tear(el, paper);874 el.next = null;875 el.prev = paper.top;876 paper.top.next = el;877 paper.top = el;878 },879 toback = function (el, paper) {880 if (paper.bottom === el) {881 return;882 }883 tear(el, paper);884 el.next = paper.bottom;885 el.prev = null;886 paper.bottom.prev = el;887 paper.bottom = el;888 },889 insertafter = function (el, el2, paper) {890 tear(el, paper);891 el2 == paper.top && (paper.top = el);892 el2.next && (el2.next.prev = el);893 el.next = el2.next;894 el.prev = el2;895 el2.next = el;896 },897 insertbefore = function (el, el2, paper) {898 tear(el, paper);899 el2 == paper.bottom && (paper.bottom = el);900 el2.prev && (el2.prev.next = el);901 el.prev = el2.prev;902 el2.prev = el;903 el.next = el2;904 },905 removed = function (methodname) {906 return function () {907 throw new Error("Rapha\xebl: you are calling to method \u201c" + methodname + "\u201d of removed object");908 };909 },910 radial_gradient = /^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/;912 // SVG913 if (R.svg) {914 Paper[proto].svgns = "http://www.w3.org/2000/svg";915 Paper[proto].xlink = "http://www.w3.org/1999/xlink";916 var round = function (num) {917 return +num + (~~num === num) * .5;918 },919 roundPath = function (path) {920 for (var i = 0, ii = path[length]; i < ii; i++) {921 if (lowerCase.call(path[i][0]) != "a") {922 for (var j = 1, jj = path[i][length]; j < jj; j++) {923 path[i][j] = round(path[i][j]);924 }925 } else {926 path[i][6] = round(path[i][6]);927 path[i][7] = round(path[i][7]);928 }929 }930 return path;931 },932 $ = function (el, attr) {933 if (attr) {934 for (var key in attr) if (attr[has](key)) {935 el[setAttribute](key, attr[key]);936 }937 } else {938 return doc.createElementNS(Paper[proto].svgns, el);939 }940 };941 R[toString] = function () {942 return "Your browser supports SVG.\nYou are running Rapha\xebl " + this.version;943 };944 var thePath = function (pathString, SVG) {945 var el = $("path");946 SVG.canvas && SVG.canvas[appendChild](el);947 var p = new Element(el, SVG);948 p.type = "path";949 setFillAndStroke(p, {fill: "none", stroke: "#000", path: pathString});950 return p;951 };952 var addGradientFill = function (o, gradient, SVG) {953 var type = "linear",954 fx = .5, fy = .5,955 s = o.style;956 gradient = (gradient + E)[rp](radial_gradient, function (all, _fx, _fy) {957 type = "radial";958 if (_fx && _fy) {959 fx = toFloat(_fx);960 fy = toFloat(_fy);961 var dir = ((fy > .5) * 2 - 1);962 pow(fx - .5, 2) + pow(fy - .5, 2) > .25 &&963 (fy = math.sqrt(.25 - pow(fx - .5, 2)) * dir + .5) &&964 fy != .5 &&965 (fy = fy.toFixed(5) - 1e-5 * dir);966 }967 return E;968 });969 gradient = gradient[split](/\s*\-\s*/);970 if (type == "linear") {971 var angle = gradient.shift();972 angle = -toFloat(angle);973 if (isNaN(angle)) {974 return null;975 }976 var vector = [0, 0, math.cos(angle * math.PI / 180), math.sin(angle * math.PI / 180)],977 max = 1 / (mmax(math.abs(vector[2]), math.abs(vector[3])) || 1);978 vector[2] *= max;979 vector[3] *= max;980 if (vector[2] < 0) {981 vector[0] = -vector[2];982 vector[2] = 0;983 }984 if (vector[3] < 0) {985 vector[1] = -vector[3];986 vector[3] = 0;987 }988 }989 var dots = parseDots(gradient);990 if (!dots) {991 return null;992 }993 var el = $(type + "Gradient");994 el.id = "r" + (R._id++)[toString](36);995 $(el, type == "radial" ? {fx: fx, fy: fy} : {x1: vector[0], y1: vector[1], x2: vector[2], y2: vector[3]});996 SVG.defs[appendChild](el);997 for (var i = 0, ii = dots[length]; i < ii; i++) {998 var stop = $("stop");999 $(stop, {1000 offset: dots[i].offset ? dots[i].offset : !i ? "0%" : "100%",1001 "stop-color": dots[i].color || "#fff"1002 });1003 el[appendChild](stop);1004 };1005 $(o, {1006 fill: "url(#" + el.id + ")",1007 opacity: 1,1008 "fill-opacity": 11009 });1010 s.fill = E;1011 s.opacity = 1;1012 s.fillOpacity = 1;1013 return 1;1014 };1015 var updatePosition = function (o) {1016 var bbox = o.getBBox();1017 $(o.pattern, {patternTransform: R.format("translate({0},{1})", bbox.x, bbox.y)});1018 };1019 var setFillAndStroke = function (o, params) {1020 var dasharray = {1021 "": [0],1022 "none": [0],1023 "-": [3, 1],1024 ".": [1, 1],1025 "-.": [3, 1, 1, 1],1026 "-..": [3, 1, 1, 1, 1, 1],1027 ". ": [1, 3],1028 "- ": [4, 3],1029 "--": [8, 3],1030 "- .": [4, 3, 1, 3],1031 "--.": [8, 3, 1, 3],1032 "--..": [8, 3, 1, 3, 1, 3]1033 },1034 node = o.node,1035 attrs = o.attrs,1036 rot = o.rotate(),1037 addDashes = function (o, value) {1038 value = dasharray[lowerCase.call(value)];1039 if (value) {1040 var width = o.attrs["stroke-width"] || "1",1041 butt = {round: width, square: width, butt: 0}[o.attrs["stroke-linecap"] || params["stroke-linecap"]] || 0,1042 dashes = [];1043 var i = value[length];1044 while (i--) {1045 dashes[i] = value[i] * width + ((i % 2) ? 1 : -1) * butt;1046 }1047 $(node, {"stroke-dasharray": dashes[join](",")});1048 }1049 };1050 params[has]("rotation") && (rot = params.rotation);1051 var rotxy = (rot + E)[split](separator);1052 if (!(rotxy.length - 1)) {1053 rotxy = null;1054 } else {1055 rotxy[1] = +rotxy[1];1056 rotxy[2] = +rotxy[2];1057 }1058 toFloat(rot) && o.rotate(0, true);1059 for (var att in params) if (params[has](att)) {1060 if (!availableAttrs[has](att)) {1061 continue;1062 }1063 var value = params[att];1064 attrs[att] = value;1065 switch (att) {1066 case "rotation":1067 o.rotate(value, true);1068 break;1069 // Hyperlink1070 case "href":1071 case "title":1072 case "target":1073 var pn = node.parentNode;1074 if (lowerCase.call(pn.tagName) != "a") {1075 var hl = $("a");1076 pn.insertBefore(hl, node);1077 hl[appendChild](node);1078 pn = hl;1079 }1080 pn.setAttributeNS(o.Paper[proto].xlink, att, value);1081 break;1082 case "cursor":1083 node.style.cursor = value;1084 break;1085 case "clip-rect":1086 var rect = (value + E)[split](separator);1087 if (rect[length] == 4) {1088 o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode);1089 var el = $("clipPath"),1090 rc = $("rect");1091 el.id = "r" + (R._id++)[toString](36);1092 $(rc, {1093 x: rect[0],1094 y: rect[1],1095 width: rect[2],1096 height: rect[3]1097 });1098 el[appendChild](rc);1099 o.paper.defs[appendChild](el);1100 $(node, {"clip-path": "url(#" + el.id + ")"});1101 o.clip = rc;1102 }1103 if (!value) {1104 var clip = doc.getElementById(node.getAttribute("clip-path")[rp](/(^url\(#|\)$)/g, E));1105 clip && clip.parentNode.removeChild(clip);1106 $(node, {"clip-path": E});1107 delete o.clip;1108 }1109 break;1110 case "path":1111 if (value && o.type == "path") {1112 attrs.path = roundPath(pathToAbsolute(value));1113 $(node, {d: attrs.path});1114 }1115 break;1116 case "width":1117 node[setAttribute](att, value);1118 if (attrs.fx) {1119 att = "x";1120 value = attrs.x;1121 } else {1122 break;1123 }1124 case "x":1125 if (attrs.fx) {1126 value = -attrs.x - (attrs.width || 0);1127 }1128 case "rx":1129 if (att == "rx" && o.type == "rect") {1130 break;1131 }1132 case "cx":1133 rotxy && (att == "x" || att == "cx") && (rotxy[1] += value - attrs[att]);1134 node[setAttribute](att, round(value));1135 o.pattern && updatePosition(o);1136 break;1137 case "height":1138 node[setAttribute](att, value);1139 if (attrs.fy) {1140 att = "y";1141 value = attrs.y;1142 } else {1143 break;1144 }1145 case "y":1146 if (attrs.fy) {1147 value = -attrs.y - (attrs.height || 0);1148 }1149 case "ry":1150 if (att == "ry" && o.type == "rect") {1151 break;1152 }1153 case "cy":1154 rotxy && (att == "y" || att == "cy") && (rotxy[2] += value - attrs[att]);1155 node[setAttribute](att, round(value));1156 o.pattern && updatePosition(o);1157 break;1158 case "r":1159 if (o.type == "rect") {1160 $(node, {rx: value, ry: value});1161 } else {1162 node[setAttribute](att, value);1163 }1164 break;1165 case "src":1166 if (o.type == "image") {1167 node.setAttributeNS(o.paper.xlink, "href", value);1168 }1169 break;1170 case "stroke-width":1171 node.style.strokeWidth = value;1172 // Need following line for Firefox1173 node[setAttribute](att, value);1174 if (attrs["stroke-dasharray"]) {1175 addDashes(o, attrs["stroke-dasharray"]);1176 }1177 break;1178 case "stroke-dasharray":1179 addDashes(o, value);1180 break;1181 case "translation":1182 var xy = (value + E)[split](separator);1183 xy[0] = +xy[0] || 0;1184 xy[1] = +xy[1] || 0;1185 if (rotxy) {1186 rotxy[1] += xy[0];1187 rotxy[2] += xy[1];1188 }1189 translate.call(o, xy[0], xy[1]);1190 break;1191 case "scale":1192 var xy = (value + E)[split](separator);1193 o.scale(+xy[0] || 1, +xy[1] || +xy[0] || 1, +xy[2] || null, +xy[3] || null);1194 break;1195 case "fill":1196 var isURL = (value + E).match(ISURL);1197 if (isURL) {1198 var el = $("pattern"),1199 ig = $("image");1200 el.id = "r" + (R._id++)[toString](36);1201 $(el, {x: 0, y: 0, patternUnits: "userSpaceOnUse", height: 1, width: 1});1202 $(ig, {x: 0, y: 0});1203 ig.setAttributeNS(o.paper.xlink, "href", isURL[1]);1204 el[appendChild](ig);1206 var img = doc.createElement("img");1207 img.style.cssText = "position:absolute;left:-9999em;top-9999em";1208 img.onload = function () {1209 $(el, {width: this.offsetWidth, height: this.offsetHeight});1210 $(ig, {width: this.offsetWidth, height: this.offsetHeight});1211 doc.body.removeChild(this);1212 o.paper.safari();1213 };1214 doc.body[appendChild](img);1215 img.src = isURL[1];1216 o.paper.defs[appendChild](el);1217 node.style.fill = "url(#" + el.id + ")";1218 $(node, {fill: "url(#" + el.id + ")"});1219 o.pattern = el;1220 o.pattern && updatePosition(o);1221 break;1222 }1223 if (!R.getRGB(value).error) {1224 delete params.gradient;1225 delete attrs.gradient;1226 !R.is(attrs.opacity, "undefined") &&1227 R.is(params.opacity, "undefined") &&1228 $(node, {opacity: attrs.opacity});1229 !R.is(attrs["fill-opacity"], "undefined") &&1230 R.is(params["fill-opacity"], "undefined") &&1231 $(node, {"fill-opacity": attrs["fill-opacity"]});1232 } else if ((({circle: 1, ellipse: 1})[has](o.type) || (value + E).charAt() != "r") && addGradientFill(node, value, o.paper)) {1233 attrs.gradient = value;1234 attrs.fill = "none";1235 break;1236 }1237 case "stroke":1238 node[setAttribute](att, R.getRGB(value).hex);1239 break;1240 case "gradient":1241 (({circle: 1, ellipse: 1})[has](o.type) || (value + E).charAt() != "r") && addGradientFill(node, value, o.paper);1242 break;1243 case "opacity":1244 case "fill-opacity":1245 if (attrs.gradient) {1246 var gradient = doc.getElementById(node.getAttribute("fill")[rp](/^url\(#|\)$/g, E));1247 if (gradient) {1248 var stops = gradient.getElementsByTagName("stop");1249 stops[stops[length] - 1][setAttribute]("stop-opacity", value);1250 }1251 break;1252 }1253 default:1254 att == "font-size" && (value = toInt(value, 10) + "px");1255 var cssrule = att[rp](/(\-.)/g, function (w) {1256 return upperCase.call(w.substring(1));1257 });1258 node.style[cssrule] = value;1259 // Need following line for Firefox1260 node[setAttribute](att, value);1261 break;1262 }1263 }1265 tuneText(o, params);1266 if (rotxy) {1267 o.rotate(rotxy.join(S));1268 } else {1269 toFloat(rot) && o.rotate(rot, true);1270 }1271 };1272 var leading = 1.2;1273 var tuneText = function (el, params) {1274 if (el.type != "text" || !(params[has]("text") || params[has]("font") || params[has]("font-size") || params[has]("x") || params[has]("y"))) {1275 return;1276 }1277 var a = el.attrs,1278 node = el.node,1279 fontSize = node.firstChild ? toInt(doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue("font-size"), 10) : 10;1281 if (params[has]("text")) {1282 a.text = params.text;1283 while (node.firstChild) {1284 node.removeChild(node.firstChild);1285 }1286 var texts = (params.text + E)[split]("\n");1287 for (var i = 0, ii = texts[length]; i < ii; i++) if (texts[i]) {1288 var tspan = $("tspan");1289 i && $(tspan, {dy: fontSize * leading, x: a.x});1290 tspan[appendChild](doc.createTextNode(texts[i]));1291 node[appendChild](tspan);1292 }1293 } else {1294 var texts = node.getElementsByTagName("tspan");1295 for (var i = 0, ii = texts[length]; i < ii; i++) {1296 i && $(texts[i], {dy: fontSize * leading, x: a.x});1297 }1298 }1299 $(node, {y: a.y});1300 var bb = el.getBBox(),1301 dif = a.y - (bb.y + bb.height / 2);1302 dif && isFinite(dif) && $(node, {y: a.y + dif});1303 };1304 var Element = function (node, svg) {1305 var X = 0,1306 Y = 0;1307 this[0] = node;1308 this.id = R._oid++;1309 this.node = node;1310 node.raphael = this;1311 this.paper = svg;1312 this.attrs = this.attrs || {};1313 this.transformations = []; // rotate, translate, scale1314 this._ = {1315 tx: 0,1316 ty: 0,1317 rt: {deg: 0, cx: 0, cy: 0},1318 sx: 1,1319 sy: 11320 };1321 !svg.bottom && (svg.bottom = this);1322 this.prev = svg.top;1323 svg.top && (svg.top.next = this);1324 svg.top = this;1325 this.next = null;1326 };1327 Element[proto].rotate = function (deg, cx, cy) {1328 if (this.removed) {1329 return this;1330 }1331 if (deg == null) {1332 if (this._.rt.cx) {1333 return [this._.rt.deg, this._.rt.cx, this._.rt.cy][join](S);1334 }1335 return this._.rt.deg;1336 }1337 var bbox = this.getBBox();1338 deg = (deg + E)[split](separator);1339 if (deg[length] - 1) {1340 cx = toFloat(deg[1]);1341 cy = toFloat(deg[2]);1342 }1343 deg = toFloat(deg[0]);1344 if (cx != null) {1345 this._.rt.deg = deg;1346 } else {1347 this._.rt.deg += deg;1348 }1349 (cy == null) && (cx = null);1350 this._.rt.cx = cx;1351 this._.rt.cy = cy;1352 cx = cx == null ? bbox.x + bbox.width / 2 : cx;1353 cy = cy == null ? bbox.y + bbox.height / 2 : cy;1354 if (this._.rt.deg) {1355 this.transformations[0] = R.format("rotate({0} {1} {2})", this._.rt.deg, cx, cy);1356 this.clip && $(this.clip, {transform: R.format("rotate({0} {1} {2})", -this._.rt.deg, cx, cy)});1357 } else {1358 this.transformations[0] = E;1359 this.clip && $(this.clip, {transform: E});1360 }1361 $(this.node, {transform: this.transformations[join](S)});1362 return this;1363 };1364 Element[proto].hide = function () {1365 !this.removed && (this.node.style.display = "none");1366 return this;1367 };1368 Element[proto].show = function () {1369 !this.removed && (this.node.style.display = "");1370 return this;1371 };1372 Element[proto].remove = function () {1373 if (this.removed) {1374 return;1375 }1376 tear(this, this.paper);1377 this.node.parentNode.removeChild(this.node);1378 for (var i in this) {1379 delete this[i];1380 }1381 this.removed = true;1382 };1383 Element[proto].getBBox = function () {1384 if (this.removed) {1385 return this;1386 }1387 if (this.type == "path") {1388 return pathDimensions(this.attrs.path);1389 }1390 if (this.node.style.display == "none") {1391 this.show();1392 var hide = true;1393 }1394 var bbox = {};1395 try {1396 bbox = this.node.getBBox();1397 } catch(e) {1398 // Firefox 3.0.x plays badly here1399 } finally {1400 bbox = bbox || {};1401 }1402 if (this.type == "text") {1403 bbox = {x: bbox.x, y: Infinity, width: 0, height: 0};1404 for (var i = 0, ii = this.node.getNumberOfChars(); i < ii; i++) {1405 var bb = this.node.getExtentOfChar(i);1406 (bb.y < bbox.y) && (bbox.y = bb.y);1407 (bb.y + bb.height - bbox.y > bbox.height) && (bbox.height = bb.y + bb.height - bbox.y);1408 (bb.x + bb.width - bbox.x > bbox.width) && (bbox.width = bb.x + bb.width - bbox.x);1409 }1410 }1411 hide && this.hide();1412 return bbox;1413 };1414 Element[proto].attr = function () {1415 if (this.removed) {1416 return this;1417 }1418 if (arguments[length] == 0) {1419 var res = {};1420 for (var i in this.attrs) if (this.attrs[has](i)) {1421 res[i] = this.attrs[i];1422 }1423 this._.rt.deg && (res.rotation = this.rotate());1424 (this._.sx != 1 || this._.sy != 1) && (res.scale = this.scale());1425 res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient;1426 return res;1427 }1428 if (arguments[length] == 1 && R.is(arguments[0], "string")) {1429 if (arguments[0] == "translation") {1430 return translate.call(this);1431 }1432 if (arguments[0] == "rotation") {1433 return this.rotate();1434 }1435 if (arguments[0] == "scale") {1436 return this.scale();1437 }1438 if (arguments[0] == "fill" && this.attrs.fill == "none" && this.attrs.gradient) {1439 return this.attrs.gradient;1440 }1441 return this.attrs[arguments[0]];1442 }1443 if (arguments[length] == 1 && R.is(arguments[0], "array")) {1444 var values = {};1445 for (var j in arguments[0]) if (arguments[0][has](j)) {1446 values[arguments[0][j]] = this.attrs[arguments[0][j]];1447 }1448 return values;1449 }1450 if (arguments[length] == 2) {1451 var params = {};1452 params[arguments[0]] = arguments[1];1453 setFillAndStroke(this, params);1454 } else if (arguments[length] == 1 && R.is(arguments[0], "object")) {1455 setFillAndStroke(this, arguments[0]);1456 }1457 return this;1458 };1459 Element[proto].toFront = function () {1460 if (this.removed) {1461 return this;1462 }1463 this.node.parentNode[appendChild](this.node);1464 var svg = this.paper;1465 svg.top != this && tofront(this, svg);1466 return this;1467 };1468 Element[proto].toBack = function () {1469 if (this.removed) {1470 return this;1471 }1472 if (this.node.parentNode.firstChild != this.node) {1473 this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild);1474 toback(this, this.paper);1475 var svg = this.paper;1476 }1477 return this;1478 };1479 Element[proto].insertAfter = function (element) {1480 if (this.removed) {1481 return this;1482 }1483 var node = element.node;1484 if (node.nextSibling) {1485 node.parentNode.insertBefore(this.node, node.nextSibling);1486 } else {1487 node.parentNode[appendChild](this.node);1488 }1489 insertafter(this, element, this.paper);1490 return this;1491 };1492 Element[proto].insertBefore = function (element) {1493 if (this.removed) {1494 return this;1495 }1496 var node = element.node;1497 node.parentNode.insertBefore(this.node, node);1498 insertbefore(this, element, this.paper);1499 return this;1500 };1501 var theCircle = function (svg, x, y, r) {1502 x = round(x);1503 y = round(y);1504 var el = $("circle");1505 svg.canvas && svg.canvas[appendChild](el);1506 var res = new Element(el, svg);1507 res.attrs = {cx: x, cy: y, r: r, fill: "none", stroke: "#000"};1508 res.type = "circle";1509 $(el, res.attrs);1510 return res;1511 };1512 var theRect = function (svg, x, y, w, h, r) {1513 x = round(x);1514 y = round(y);1515 var el = $("rect");1516 svg.canvas && svg.canvas[appendChild](el);1517 var res = new Element(el, svg);1518 res.attrs = {x: x, y: y, width: w, height: h, r: r || 0, rx: r || 0, ry: r || 0, fill: "none", stroke: "#000"};1519 res.type = "rect";1520 $(el, res.attrs);1521 return res;1522 };1523 var theEllipse = function (svg, x, y, rx, ry) {1524 x = round(x);1525 y = round(y);1526 var el = $("ellipse");1527 svg.canvas && svg.canvas[appendChild](el);1528 var res = new Element(el, svg);1529 res.attrs = {cx: x, cy: y, rx: rx, ry: ry, fill: "none", stroke: "#000"};1530 res.type = "ellipse";1531 $(el, res.attrs);1532 return res;1533 };1534 var theImage = function (svg, src, x, y, w, h) {1535 var el = $("image");1536 $(el, {x: x, y: y, width: w, height: h, preserveAspectRatio: "none"});1537 el.setAttributeNS(svg.xlink, "href", src);1538 svg.canvas && svg.canvas[appendChild](el);1539 var res = new Element(el, svg);1540 res.attrs = {x: x, y: y, width: w, height: h, src: src};1541 res.type = "image";1542 return res;1543 };1544 var theText = function (svg, x, y, text) {1545 var el = $("text");1546 $(el, {x: x, y: y, "text-anchor": "middle"});1547 svg.canvas && svg.canvas[appendChild](el);1548 var res = new Element(el, svg);1549 res.attrs = {x: x, y: y, "text-anchor": "middle", text: text, font: availableAttrs.font, stroke: "none", fill: "#000"};1550 res.type = "text";1551 setFillAndStroke(res, res.attrs);1552 return res;1553 };1554 var setSize = function (width, height) {1555 this.width = width || this.width;1556 this.height = height || this.height;1557 this.canvas[setAttribute]("width", this.width);1558 this.canvas[setAttribute]("height", this.height);1559 return this;1560 };1561 var create = function () {1562 var con = getContainer[apply](null, arguments),1563 container = con && con.container,1564 x = con.x,1565 y = con.y,1566 width = con.width,1567 height = con.height;1568 if (!container) {1569 throw new Error("SVG container not found.");1570 }1571 var cnvs = $("svg");1572 width = width || 512;1573 height = height || 342;1574 $(cnvs, {1575 xmlns: "http://www.w3.org/2000/svg",1576 version: 1.1,1577 width: width,1578 height: height1579 });1580 if (container == 1) {1581 cnvs.style.cssText = "position:absolute;left:" + x + "px;top:" + y + "px";1582 doc.body[appendChild](cnvs);1583 } else {1584 if (container.firstChild) {1585 container.insertBefore(cnvs, container.firstChild);1586 } else {1587 container[appendChild](cnvs);1588 }1589 }1590 container = new Paper;1591 container.width = width;1592 container.height = height;1593 container.canvas = cnvs;1594 plugins.call(container, container, R.fn);1595 container.clear();1596 return container;1597 };1598 Paper[proto].clear = function () {1599 var c = this.canvas;1600 while (c.firstChild) {1601 c.removeChild(c.firstChild);1602 }1603 this.bottom = this.top = null;1604 (this.desc = $("desc"))[appendChild](doc.createTextNode("Created with Rapha\xebl"));1605 c[appendChild](this.desc);1606 c[appendChild](this.defs = $("defs"));1607 };1608 Paper[proto].remove = function () {1609 this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas);1610 for (var i in this) {1611 this[i] = removed(i);1612 }1613 };1614 }1616 // VML1617 if (R.vml) {1618 var path2vml = function (path) {1619 var total = /[ahqstv]/ig,1620 command = pathToAbsolute;1621 (path + E).match(total) && (command = path2curve);1622 total = /[clmz]/g;1623 if (command == pathToAbsolute && !(path + E).match(total)) {1624 var map = {M: "m", L: "l", C: "c", Z: "x", m: "t", l: "r", c: "v", z: "x"},1625 bites = /([clmz]),?([^clmz]*)/gi,1626 val = /-?[^,\s-]+/g;1627 var res = (path + E)[rp](bites, function (all, command, args) {1628 var vals = [];1629 args[rp](val, function (value) {1630 vals[push](round(value));1631 });1632 return map[command] + vals;1633 });1634 return res;1635 }1636 var pa = command(path), p, res = [], r;1637 for (var i = 0, ii = pa[length]; i < ii; i++) {1638 p = pa[i];1639 r = lowerCase.call(pa[i][0]);1640 r == "z" && (r = "x");1641 for (var j = 1, jj = p[length]; j < jj; j++) {1642 r += round(p[j]) + (j != jj - 1 ? "," : E);1643 }1644 res[push](r);1645 }1646 return res[join](S);1647 };1649 R[toString] = function () {1650 return "Your browser doesn\u2019t support SVG. Falling down to VML.\nYou are running Rapha\xebl " + this.version;1651 };1652 var thePath = function (pathString, VML) {1653 var g = createNode("group");1654 g.style.cssText = "position:absolute;left:0;top:0;width:" + VML.width + "px;height:" + VML.height + "px";1655 g.coordsize = VML.coordsize;1656 g.coordorigin = VML.coordorigin;1657 var el = createNode("shape"), ol = el.style;1658 ol.width = VML.width + "px";1659 ol.height = VML.height + "px";1660 el.coordsize = this.coordsize;1661 el.coordorigin = this.coordorigin;1662 g[appendChild](el);1663 var p = new Element(el, g, VML);1664 p.isAbsolute = true;1665 p.type = "path";1666 p.path = [];1667 p.Path = E;1668 pathString && setFillAndStroke(p, {fill: "none", stroke: "#000", path: pathString});1669 VML.canvas[appendChild](g);1670 return p;1671 };1672 var setFillAndStroke = function (o, params) {1673 o.attrs = o.attrs || {};1674 var node = o.node,1675 a = o.attrs,1676 s = node.style,1677 xy,1678 res = o;1679 for (var par in params) if (params[has](par)) {1680 a[par] = params[par];1681 }1682 params.href && (node.href = params.href);1683 params.title && (node.title = params.title);1684 params.target && (node.target = params.target);1685 params.cursor && (s.cursor = params.cursor);1686 if (params.path && o.type == "path") {1687 a.path = params.path;1688 node.path = path2vml(a.path);1689 }1690 if (params.rotation != null) {1691 o.rotate(params.rotation, true);1692 }1693 if (params.translation) {1694 xy = (params.translation + E)[split](separator);1695 translate.call(o, xy[0], xy[1]);1696 if (o._.rt.cx != null) {1697 o._.rt.cx +=+ xy[0];1698 o._.rt.cy +=+ xy[1];1699 o.setBox(o.attrs, xy[0], xy[1]);1700 }1701 }1702 if (params.scale) {1703 xy = (params.scale + E)[split](separator);1704 o.scale(+xy[0] || 1, +xy[1] || +xy[0] || 1, +xy[2] || null, +xy[3] || null);1705 }1706 if ("clip-rect" in params) {1707 var rect = (params["clip-rect"] + E)[split](separator);1708 if (rect[length] == 4) {1709 rect[2] = +rect[2] + (+rect[0]);1710 rect[3] = +rect[3] + (+rect[1]);1711 var div = node.clipRect || doc.createElement("div"),1712 dstyle = div.style,1713 group = node.parentNode;1714 dstyle.clip = R.format("rect({1}px {2}px {3}px {0}px)", rect);1715 if (!node.clipRect) {1716 dstyle.position = "absolute";1717 dstyle.top = 0;1718 dstyle.left = 0;1719 dstyle.width = o.paper.width + "px";1720 dstyle.height = o.paper.height + "px";1721 group.parentNode.insertBefore(div, group);1722 div[appendChild](group);1723 node.clipRect = div;1724 }1725 }1726 if (!params["clip-rect"]) {1727 node.clipRect && (node.clipRect.style.clip = E);1728 }1729 }1730 if (o.type == "image" && params.src) {1731 node.src = params.src;1732 }1733 if (o.type == "image" && params.opacity) {1734 node.filterOpacity = " progid:DXImageTransform.Microsoft.Alpha(opacity=" + (params.opacity * 100) + ")";1735 s.filter = (node.filterMatrix || E) + (node.filterOpacity || E);1736 }1737 params.font && (s.font = params.font);1738 params["font-family"] && (s.fontFamily = '"' + params["font-family"][split](",")[0][rp](/^['"]+|['"]+$/g, E) + '"');1739 params["font-size"] && (s.fontSize = params["font-size"]);1740 params["font-weight"] && (s.fontWeight = params["font-weight"]);1741 params["font-style"] && (s.fontStyle = params["font-style"]);1742 if (params.opacity != null ||1743 params["stroke-width"] != null ||1744 params.fill != null ||1745 params.stroke != null ||1746 params["stroke-width"] != null ||1747 params["stroke-opacity"] != null ||1748 params["fill-opacity"] != null ||1749 params["stroke-dasharray"] != null ||1750 params["stroke-miterlimit"] != null ||1751 params["stroke-linejoin"] != null ||1752 params["stroke-linecap"] != null) {1753 node = o.shape || node;1754 var fill = (node.getElementsByTagName("fill") && node.getElementsByTagName("fill")[0]),1755 newfill = false;1756 !fill && (newfill = fill = createNode("fill"));1757 if ("fill-opacity" in params || "opacity" in params) {1758 var opacity = ((+a["fill-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1);1759 opacity < 0 && (opacity = 0);1760 opacity > 1 && (opacity = 1);1761 fill.opacity = opacity;1762 }1763 params.fill && (fill.on = true);1764 if (fill.on == null || params.fill == "none") {1765 fill.on = false;1766 }1767 if (fill.on && params.fill) {1768 var isURL = params.fill.match(ISURL);1769 if (isURL) {1770 fill.src = isURL[1];1771 fill.type = "tile";1772 } else {1773 fill.color = R.getRGB(params.fill).hex;1774 fill.src = E;1775 fill.type = "solid";1776 if (R.getRGB(params.fill).error && (res.type in {circle: 1, ellipse: 1} || (params.fill + E).charAt() != "r") && addGradientFill(res, params.fill)) {1777 a.fill = "none";1778 a.gradient = params.fill;1779 }1780 }1781 }1782 newfill && node[appendChild](fill);1783 var stroke = (node.getElementsByTagName("stroke") && node.getElementsByTagName("stroke")[0]),1784 newstroke = false;1785 !stroke && (newstroke = stroke = createNode("stroke"));1786 if ((params.stroke && params.stroke != "none") ||1787 params["stroke-width"] ||1788 params["stroke-opacity"] != null ||1789 params["stroke-dasharray"] ||1790 params["stroke-miterlimit"] ||1791 params["stroke-linejoin"] ||1792 params["stroke-linecap"]) {1793 stroke.on = true;1794 }1795 (params.stroke == "none" || stroke.on == null || params.stroke == 0 || params["stroke-width"] == 0) && (stroke.on = false);1796 stroke.on && params.stroke && (stroke.color = R.getRGB(params.stroke).hex);1797 var opacity = ((+a["stroke-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1),1798 width = (toFloat(params["stroke-width"]) || 1) * .75;1799 opacity < 0 && (opacity = 0);1800 opacity > 1 && (opacity = 1);1801 params["stroke-width"] == null && (width = a["stroke-width"]);1802 params["stroke-width"] && (stroke.weight = width);1803 width && width < 1 && (opacity *= width) && (stroke.weight = 1);1804 stroke.opacity = opacity;1806 params["stroke-linejoin"] && (stroke.joinstyle = params["stroke-linejoin"] || "miter");1807 stroke.miterlimit = params["stroke-miterlimit"] || 8;1808 params["stroke-linecap"] && (stroke.endcap = params["stroke-linecap"] == "butt" ? "flat" : params["stroke-linecap"] == "square" ? "square" : "round");1809 if (params["stroke-dasharray"]) {1810 var dasharray = {1811 "-": "shortdash",1812 ".": "shortdot",1813 "-.": "shortdashdot",1814 "-..": "shortdashdotdot",1815 ". ": "dot",1816 "- ": "dash",1817 "--": "longdash",1818 "- .": "dashdot",1819 "--.": "longdashdot",1820 "--..": "longdashdotdot"1821 };1822 stroke.dashstyle = dasharray[has](params["stroke-dasharray"]) ? dasharray[params["stroke-dasharray"]] : E;1823 }1824 newstroke && node[appendChild](stroke);1825 }1826 if (res.type == "text") {1827 var s = res.paper.span.style;1828 a.font && (s.font = a.font);1829 a["font-family"] && (s.fontFamily = a["font-family"]);1830 a["font-size"] && (s.fontSize = a["font-size"]);1831 a["font-weight"] && (s.fontWeight = a["font-weight"]);1832 a["font-style"] && (s.fontStyle = a["font-style"]);1833 res.node.string && (res.paper.span.innerHTML = (res.node.string + E)[rp](/</g, "<")[rp](/&/g, "&")[rp](/\n/g, "<br>"));1834 res.W = a.w = res.paper.span.offsetWidth;1835 res.H = a.h = res.paper.span.offsetHeight;1836 res.X = a.x;1837 res.Y = a.y + round(res.H / 2);1839 // text-anchor emulationm1840 switch (a["text-anchor"]) {1841 case "start":1842 res.node.style["v-text-align"] = "left";1843 res.bbx = round(res.W / 2);1844 break;1845 case "end":1846 res.node.style["v-text-align"] = "right";1847 res.bbx = -round(res.W / 2);1848 break;1849 default:1850 res.node.style["v-text-align"] = "center";1851 break;1852 }1853 }1854 };1855 var addGradientFill = function (o, gradient) {1856 o.attrs = o.attrs || {};1857 var attrs = o.attrs,1858 fill = o.node.getElementsByTagName("fill"),1859 type = "linear",1860 fxfy = ".5 .5";1861 o.attrs.gradient = gradient;1862 gradient = (gradient + E)[rp](radial_gradient, function (all, fx, fy) {1863 type = "radial";1864 if (fx && fy) {1865 fx = toFloat(fx);1866 fy = toFloat(fy);1867 pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && (fy = math.sqrt(.25 - pow(fx - .5, 2)) * ((fy > .5) * 2 - 1) + .5);1868 fxfy = fx + S + fy;1869 }1870 return E;1871 });1872 gradient = gradient[split](/\s*\-\s*/);1873 if (type == "linear") {1874 var angle = gradient.shift();1875 angle = -toFloat(angle);1876 if (isNaN(angle)) {1877 return null;1878 }1879 }1880 var dots = parseDots(gradient);1881 if (!dots) {1882 return null;1883 }1884 o = o.shape || o.node;1885 fill = fill[0] || createNode("fill");1886 if (dots[length]) {1887 fill.on = true;1888 fill.method = "none";1889 fill.type = (type == "radial") ? "gradientradial" : "gradient";1890 fill.color = dots[0].color;1891 fill.color2 = dots[dots[length] - 1].color;1892 var clrs = [];1893 for (var i = 0, ii = dots[length]; i < ii; i++) {1894 dots[i].offset && clrs[push](dots[i].offset + S + dots[i].color);1895 }1896 fill.colors && (fill.colors.value = clrs[length] ? clrs[join](",") : "0% " + fill.color);1897 if (type == "radial") {1898 fill.focus = "100%";1899 fill.focussize = fxfy;1900 fill.focusposition = fxfy;1901 } else {1902 fill.angle = (270 - angle) % 360;1903 }1904 }1905 return 1;1906 };1907 var Element = function (node, group, vml) {1908 var Rotation = 0,1909 RotX = 0,1910 RotY = 0,1911 Scale = 1;1912 this[0] = node;1913 this.id = R._oid++;1914 this.node = node;1915 node.raphael = this;1916 this.X = 0;1917 this.Y = 0;1918 this.attrs = {};1919 this.Group = group;1920 this.paper = vml;1921 this._ = {1922 tx: 0,1923 ty: 0,1924 rt: {deg:0},1925 sx: 1,1926 sy: 11927 };1928 !vml.bottom && (vml.bottom = this);1929 this.prev = vml.top;1930 vml.top && (vml.top.next = this);1931 vml.top = this;1932 this.next = null;1933 };1934 Element[proto].rotate = function (deg, cx, cy) {1935 if (this.removed) {1936 return this;1937 }1938 if (deg == null) {1939 if (this._.rt.cx) {1940 return [this._.rt.deg, this._.rt.cx, this._.rt.cy][join](S);1941 }1942 return this._.rt.deg;1943 }1944 deg = (deg + E)[split](separator);1945 if (deg[length] - 1) {1946 cx = toFloat(deg[1]);1947 cy = toFloat(deg[2]);1948 }1949 deg = toFloat(deg[0]);1950 if (cx != null) {1951 this._.rt.deg = deg;1952 } else {1953 this._.rt.deg += deg;1954 }1955 cy == null && (cx = null);1956 this._.rt.cx = cx;1957 this._.rt.cy = cy;1958 this.setBox(this.attrs, cx, cy);1959 this.Group.style.rotation = this._.rt.deg;1960 // gradient fix for rotation. TODO1961 // var fill = (this.shape || this.node).getElementsByTagName("fill");1962 // fill = fill[0] || {};1963 // var b = ((360 - this._.rt.deg) - 270) % 360;1964 // !R.is(fill.angle, "undefined") && (fill.angle = b);1965 return this;1966 };1967 Element[proto].setBox = function (params, cx, cy) {1968 if (this.removed) {1969 return this;1970 }1971 var gs = this.Group.style,1972 os = (this.shape && this.shape.style) || this.node.style;1973 params = params || {};1974 for (var i in params) if (params[has](i)) {1975 this.attrs[i] = params[i];1976 }1977 cx = cx || this._.rt.cx;1978 cy = cy || this._.rt.cy;1979 var attr = this.attrs,1980 x,1981 y,1982 w,1983 h;1984 switch (this.type) {1985 case "circle":1986 x = attr.cx - attr.r;1987 y = attr.cy - attr.r;1988 w = h = attr.r * 2;1989 break;1990 case "ellipse":1991 x = attr.cx - attr.rx;1992 y = attr.cy - attr.ry;1993 w = attr.rx * 2;1994 h = attr.ry * 2;1995 break;1996 case "rect":1997 case "image":1998 x = +attr.x;1999 y = +attr.y;2000 w = attr.width || 0;2001 h = attr.height || 0;2002 break;2003 case "text":2004 this.textpath.v = ["m", round(attr.x), ", ", round(attr.y - 2), "l", round(attr.x) + 1, ", ", round(attr.y - 2)][join](E);2005 x = attr.x - round(this.W / 2);2006 y = attr.y - this.H / 2;2007 w = this.W;2008 h = this.H;2009 break;2010 case "path":2011 if (!this.attrs.path) {2012 x = 0;2013 y = 0;2014 w = this.paper.width;2015 h = this.paper.height;2016 } else {2017 var dim = pathDimensions(this.attrs.path);2018 x = dim.x;2019 y = dim.y;2020 w = dim.width;2021 h = dim.height;2022 }2023 break;2024 default:2025 x = 0;2026 y = 0;2027 w = this.paper.width;2028 h = this.paper.height;2029 break;2030 }2031 cx = (cx == null) ? x + w / 2 : cx;2032 cy = (cy == null) ? y + h / 2 : cy;2033 var left = cx - this.paper.width / 2,2034 top = cy - this.paper.height / 2;2035 if (this.type == "path" || this.type == "text") {2036 (gs.left != left + "px") && (gs.left = left + "px");2037 (gs.top != top + "px") && (gs.top = top + "px");2038 this.X = this.type == "text" ? x : -left;2039 this.Y = this.type == "text" ? y : -top;2040 this.W = w;2041 this.H = h;2042 (os.left != -left + "px") && (os.left = -left + "px");2043 (os.top != -top + "px") && (os.top = -top + "px");2044 } else {2045 (gs.left != left + "px") && (gs.left = left + "px");2046 (gs.top != top + "px") && (gs.top = top + "px");2047 this.X = x;2048 this.Y = y;2049 this.W = w;2050 this.H = h;2051 (gs.width != this.paper.width + "px") && (gs.width = this.paper.width + "px");2052 (gs.height != this.paper.height + "px") && (gs.height = this.paper.height + "px");2053 (os.left != x - left + "px") && (os.left = x - left + "px");2054 (os.top != y - top + "px") && (os.top = y - top + "px");2055 (os.width != w + "px") && (os.width = w + "px");2056 (os.height != h + "px") && (os.height = h + "px");2057 var arcsize = (+params.r || 0) / mmin(w, h);2058 if (this.type == "rect" && this.arcsize.toFixed(4) != arcsize.toFixed(4) && (arcsize || this.arcsize)) {2059 // We should replace element with the new one2060 var o = createNode("roundrect"),2061 a = {},2062 i = 0,2063 ii = this.events && this.events[length];2064 o.arcsize = arcsize;2065 o.raphael = this;2066 this.Group[appendChild](o);2067 this.Group.removeChild(this.node);2068 this[0] = this.node = o;2069 this.arcsize = arcsize;2070 for (var i in attr) {2071 a[i] = attr[i];2072 }2073 delete a.scale;2074 this.attr(a);2075 if (this.events) for (; i < ii; i++) {2076 this.events[i].unbind = addEvent(this.node, this.events[i].name, this.events[i].f, this);2077 }2078 }2079 }2080 };2081 Element[proto].hide = function () {2082 !this.removed && (this.Group.style.display = "none");2083 return this;2084 };2085 Element[proto].show = function () {2086 !this.removed && (this.Group.style.display = "block");2087 return this;2088 };2089 Element[proto].getBBox = function () {2090 if (this.removed) {2091 return this;2092 }2093 if (this.type == "path") {2094 return pathDimensions(this.attrs.path);2095 }2096 return {2097 x: this.X + (this.bbx || 0),2098 y: this.Y,2099 width: this.W,2100 height: this.H2101 };2102 };2103 Element[proto].remove = function () {2104 if (this.removed) {2105 return;2106 }2107 tear(this, this.paper);2108 this.node.parentNode.removeChild(this.node);2109 this.Group.parentNode.removeChild(this.Group);2110 this.shape && this.shape.parentNode.removeChild(this.shape);2111 for (var i in this) {2112 delete this[i];2113 }2114 this.removed = true;2115 };2116 Element[proto].attr = function () {2117 if (this.removed) {2118 return this;2119 }2120 if (arguments[length] == 0) {2121 var res = {};2122 for (var i in this.attrs) if (this.attrs[has](i)) {2123 res[i] = this.attrs[i];2124 }2125 this._.rt.deg && (res.rotation = this.rotate());2126 (this._.sx != 1 || this._.sy != 1) && (res.scale = this.scale());2127 res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient;2128 return res;2129 }2130 if (arguments[length] == 1 && R.is(arguments[0], "string")) {2131 if (arguments[0] == "translation") {2132 return translate.call(this);2133 }2134 if (arguments[0] == "rotation") {2135 return this.rotate();2136 }2137 if (arguments[0] == "scale") {2138 return this.scale();2139 }2140 if (arguments[0] == "fill" && this.attrs.fill == "none" && this.attrs.gradient) {2141 return this.attrs.gradient;2142 }2143 return this.attrs[arguments[0]];2144 }2145 if (this.attrs && arguments[length] == 1 && R.is(arguments[0], "array")) {2146 var values = {};2147 for (var i = 0, ii = arguments[0][length]; i < ii; i++) {2148 values[arguments[0][i]] = this.attrs[arguments[0][i]];2149 };2150 return values;2151 }2152 var params;2153 if (arguments[length] == 2) {2154 params = {};2155 params[arguments[0]] = arguments[1];2156 }2157 arguments[length] == 1 && R.is(arguments[0], "object") && (params = arguments[0]);2158 if (params) {2159 if (params.text && this.type == "text") {2160 this.node.string = params.text;2161 }2162 setFillAndStroke(this, params);2163 if (params.gradient && (({circle: 1, ellipse: 1})[has](this.type) || (params.gradient + E).charAt() != "r")) {2164 addGradientFill(this, params.gradient);2165 }2166 (this.type != "path" || this._.rt.deg) && this.setBox(this.attrs);2167 }2168 return this;2169 };2170 Element[proto].toFront = function () {2171 !this.removed && this.Group.parentNode[appendChild](this.Group);2172 this.paper.top != this && tofront(this, this.paper);2173 return this;2174 };2175 Element[proto].toBack = function () {2176 if (this.removed) {2177 return this;2178 }2179 if (this.Group.parentNode.firstChild != this.Group) {2180 this.Group.parentNode.insertBefore(this.Group, this.Group.parentNode.firstChild);2181 toback(this, this.paper);2182 }2183 return this;2184 };2185 Element[proto].insertAfter = function (element) {2186 if (this.removed) {2187 return this;2188 }2189 if (element.Group.nextSibling) {2190 element.Group.parentNode.insertBefore(this.Group, element.Group.nextSibling);2191 } else {2192 element.Group.parentNode[appendChild](this.Group);2193 }2194 insertafter(this, element, this.paper);2195 return this;2196 };2197 Element[proto].insertBefore = function (element) {2198 if (this.removed) {2199 return this;2200 }2201 element.Group.parentNode.insertBefore(this.Group, element.Group);2202 insertbefore(this, element, this.paper);2203 return this;2204 };2206 var theCircle = function (vml, x, y, r) {2207 var g = createNode("group"),2208 o = createNode("oval"),2209 ol = o.style;2210 g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";2211 g.coordsize = vml.coordsize;2212 g.coordorigin = vml.coordorigin;2213 g[appendChild](o);2214 var res = new Element(o, g, vml);2215 res.type = "circle";2216 setFillAndStroke(res, {stroke: "#000", fill: "none"});2217 res.attrs.cx = x;2218 res.attrs.cy = y;2219 res.attrs.r = r;2220 res.setBox({x: x - r, y: y - r, width: r * 2, height: r * 2});2221 vml.canvas[appendChild](g);2222 return res;2223 },2224 theRect = function (vml, x, y, w, h, r) {2225 var g = createNode("group"),2226 o = createNode("roundrect"),2227 arcsize = (+r || 0) / (mmin(w, h));2228 g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";2229 g.coordsize = vml.coordsize;2230 g.coordorigin = vml.coordorigin;2231 g[appendChild](o);2232 o.arcsize = arcsize;2233 var res = new Element(o, g, vml);2234 res.type = "rect";2235 setFillAndStroke(res, {stroke: "#000"});2236 res.arcsize = arcsize;2237 res.setBox({x: x, y: y, width: w, height: h, r: r});2238 vml.canvas[appendChild](g);2239 return res;2240 },2241 theEllipse = function (vml, x, y, rx, ry) {2242 var g = createNode("group"),2243 o = createNode("oval"),2244 ol = o.style;2245 g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";2246 g.coordsize = vml.coordsize;2247 g.coordorigin = vml.coordorigin;2248 g[appendChild](o);2249 var res = new Element(o, g, vml);2250 res.type = "ellipse";2251 setFillAndStroke(res, {stroke: "#000"});2252 res.attrs.cx = x;2253 res.attrs.cy = y;2254 res.attrs.rx = rx;2255 res.attrs.ry = ry;2256 res.setBox({x: x - rx, y: y - ry, width: rx * 2, height: ry * 2});2257 vml.canvas[appendChild](g);2258 return res;2259 },2260 theImage = function (vml, src, x, y, w, h) {2261 var g = createNode("group"),2262 o = createNode("image"),2263 ol = o.style;2264 g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";2265 g.coordsize = vml.coordsize;2266 g.coordorigin = vml.coordorigin;2267 o.src = src;2268 g[appendChild](o);2269 var res = new Element(o, g, vml);2270 res.type = "image";2271 res.attrs.src = src;2272 res.attrs.x = x;2273 res.attrs.y = y;2274 res.attrs.w = w;2275 res.attrs.h = h;2276 res.setBox({x: x, y: y, width: w, height: h});2277 vml.canvas[appendChild](g);2278 return res;2279 },2280 theText = function (vml, x, y, text) {2281 var g = createNode("group"),2282 el = createNode("shape"),2283 ol = el.style,2284 path = createNode("path"),2285 ps = path.style,2286 o = createNode("textpath");2287 g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";2288 g.coordsize = vml.coordsize;2289 g.coordorigin = vml.coordorigin;2290 path.v = R.format("m{0},{1}l{2},{1}", round(x), round(y), round(x) + 1);2291 path.textpathok = true;2292 ol.width = vml.width;2293 ol.height = vml.height;2294 o.string = text + E;2295 o.on = true;2296 el[appendChild](o);2297 el[appendChild](path);2298 g[appendChild](el);2299 var res = new Element(o, g, vml);2300 res.shape = el;2301 res.textpath = path;2302 res.type = "text";2303 res.attrs.text = text;2304 res.attrs.x = x;2305 res.attrs.y = y;2306 res.attrs.w = 1;2307 res.attrs.h = 1;2308 setFillAndStroke(res, {font: availableAttrs.font, stroke: "none", fill: "#000"});2309 res.setBox();2310 vml.canvas[appendChild](g);2311 return res;2312 },2313 setSize = function (width, height) {2314 var cs = this.canvas.style;2315 width == +width && (width += "px");2316 height == +height && (height += "px");2317 cs.width = width;2318 cs.height = height;2319 cs.clip = "rect(0 " + width + " " + height + " 0)";2320 return this;2321 },2322 createNode;2323 doc.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)");2324 try {2325 !doc.namespaces.rvml && doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");2326 createNode = function (tagName) {2327 return doc.createElement('<rvml:' + tagName + ' class="rvml">');2328 };2329 } catch (e) {2330 createNode = function (tagName) {2331 return doc.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');2332 };2333 }2334 var create = function () {2335 var con = getContainer[apply](null, arguments),2336 container = con.container,2337 height = con.height,2338 s,2339 width = con.width,2340 x = con.x,2341 y = con.y;2342 if (!container) {2343 throw new Error("VML container not found.");2344 }2345 var res = new Paper,2346 c = res.canvas = doc.createElement("div"),2347 cs = c.style;2348 width = width || 512;2349 height = height || 342;2350 width == +width && (width += "px");2351 height == +height && (height += "px");2352 res.width = 1e3;2353 res.height = 1e3;2354 res.coordsize = "1000 1000";2355 res.coordorigin = "0 0";2356 res.span = doc.createElement("span");2357 res.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";2358 c[appendChild](res.span);2359 cs.cssText = R.format("width:{0};height:{1};position:absolute;clip:rect(0 {0} {1} 0);overflow:hidden", width, height);2360 if (container == 1) {2361 doc.body[appendChild](c);2362 cs.left = x + "px";2363 cs.top = y + "px";2364 } else {2365 container.style.width = width;2366 container.style.height = height;2367 if (container.firstChild) {2368 container.insertBefore(c, container.firstChild);2369 } else {2370 container[appendChild](c);2371 }2372 }2373 plugins.call(res, res, R.fn);2374 return res;2375 };2376 Paper[proto].clear = function () {2377 this.canvas.innerHTML = E;2378 this.span = doc.createElement("span");2379 this.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";2380 this.canvas[appendChild](this.span);2381 this.bottom = this.top = null;2382 };2383 Paper[proto].remove = function () {2384 this.canvas.parentNode.removeChild(this.canvas);2385 for (var i in this) {2386 this[i] = removed(i);2387 }2388 };2389 }2391 // rest2392 // Safari or Chrome (WebKit) rendering bug workaround method2393 if ((/^Apple|^Google/).test(navigator.vendor) && !(navigator.userAgent.indexOf("Version/4.0") + 1)) {2394 Paper[proto].safari = function () {2395 var rect = this.rect(-99, -99, this.width + 99, this.height + 99);2396 setTimeout(function () {rect.remove();});2397 };2398 } else {2399 Paper[proto].safari = function () {};2400 }2402 // Events2403 var addEvent = (function () {2404 if (doc.addEventListener) {2405 return function (obj, type, fn, element) {2406 var f = function (e) {2407 return fn.call(element, e);2408 };2409 obj.addEventListener(type, f, false);2410 return function () {2411 obj.removeEventListener(type, f, false);2412 return true;2413 };2414 };2415 } else if (doc.attachEvent) {2416 return function (obj, type, fn, element) {2417 var f = function (e) {2418 return fn.call(element, e || win.event);2419 };2420 obj.attachEvent("on" + type, f);2421 var detacher = function () {2422 obj.detachEvent("on" + type, f);2423 return true;2424 };2425 return detacher;2426 };2427 }2428 })();2429 for (var i = events[length]; i--;) {2430 (function (eventName) {2431 Element[proto][eventName] = function (fn) {2432 if (R.is(fn, "function")) {2433 this.events = this.events || [];2434 this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node, eventName, fn, this)});2435 }2436 return this;2437 };2438 Element[proto]["un" + eventName] = function (fn) {2439 var events = this.events,2440 l = events[length];2441 while (l--) if (events[l].name == eventName && events[l].f == fn) {2442 events[l].unbind();2443 events.splice(l, 1);2444 !events.length && delete this.events;2445 return this;2446 }2447 return this;2448 };2449 })(events[i]);2450 }2451 Element[proto].hover = function (f_in, f_out) {2452 return this.mouseover(f_in).mouseout(f_out);2453 };2454 Element[proto].unhover = function (f_in, f_out) {2455 return this.unmouseover(f_in).unmouseout(f_out);2456 };2457 Paper[proto].circle = function (x, y, r) {2458 return theCircle(this, x || 0, y || 0, r || 0);2459 };2460 Paper[proto].rect = function (x, y, w, h, r) {2461 return theRect(this, x || 0, y || 0, w || 0, h || 0, r || 0);2462 };2463 Paper[proto].ellipse = function (x, y, rx, ry) {2464 return theEllipse(this, x || 0, y || 0, rx || 0, ry || 0);2465 };2466 Paper[proto].path = function (pathString) {2467 pathString && !R.is(pathString, "string") && !R.is(pathString[0], "array") && (pathString += E);2468 return thePath(R.format[apply](R, arguments), this);2469 };2470 Paper[proto].image = function (src, x, y, w, h) {2471 return theImage(this, src || "about:blank", x || 0, y || 0, w || 0, h || 0);2472 };2473 Paper[proto].text = function (x, y, text) {2474 return theText(this, x || 0, y || 0, text || E);2475 };2476 Paper[proto].set = function (itemsArray) {2477 arguments[length] > 1 && (itemsArray = Array[proto].splice.call(arguments, 0, arguments[length]));2478 return new Set(itemsArray);2479 };2480 Paper[proto].setSize = setSize;2481 Paper[proto].top = Paper[proto].bottom = null;2482 Paper[proto].raphael = R;2483 function x_y() {2484 return this.x + S + this.y;2485 };2486 Element[proto].scale = function (x, y, cx, cy) {2487 if (x == null && y == null) {2488 return {2489 x: this._.sx,2490 y: this._.sy,2491 toString: x_y2492 };2493 }2494 y = y || x;2495 !+y && (y = x);2496 var dx,2497 dy,2498 dcx,2499 dcy,2500 a = this.attrs;2501 if (x != 0) {2502 var bb = this.getBBox(),2503 rcx = bb.x + bb.width / 2,2504 rcy = bb.y + bb.height / 2,2505 kx = x / this._.sx,2506 ky = y / this._.sy;2507 cx = (+cx || cx == 0) ? cx : rcx;2508 cy = (+cy || cy == 0) ? cy : rcy;2509 var dirx = ~~(x / math.abs(x)),2510 diry = ~~(y / math.abs(y)),2511 s = this.node.style,2512 ncx = cx + (rcx - cx) * kx,2513 ncy = cy + (rcy - cy) * ky;2514 switch (this.type) {2515 case "rect":2516 case "image":2517 var neww = a.width * dirx * kx,2518 newh = a.height * diry * ky;2519 this.attr({2520 height: newh,2521 r: a.r * mmin(dirx * kx, diry * ky),2522 width: neww,2523 x: ncx - neww / 2,2524 y: ncy - newh / 22525 });2526 break;2527 case "circle":2528 case "ellipse":2529 this.attr({2530 rx: a.rx * dirx * kx,2531 ry: a.ry * diry * ky,2532 r: a.r * mmin(dirx * kx, diry * ky),2533 cx: ncx,2534 cy: ncy2535 });2536 break;2537 case "path":2538 var path = pathToRelative(a.path),2539 skip = true;2540 for (var i = 0, ii = path[length]; i < ii; i++) {2541 var p = path[i],2542 j,2543 P0 = upperCase.call(p[0]);2544 if (P0 == "M" && skip) {2545 continue;2546 } else {2547 skip = false;2548 }2549 if (P0 == "A") {2550 p[path[i][length] - 2] *= kx;2551 p[path[i][length] - 1] *= ky;2552 p[1] *= dirx * kx;2553 p[2] *= diry * ky;2554 p[5] = +(dirx + diry ? !!+p[5] : !+p[5]);2555 } else if (P0 == "H") {2556 for (j = 1, jj = p[length]; j < jj; j++) {2557 p[j] *= kx;2558 }2559 } else if (P0 == "V") {2560 for (j = 1, jj = p[length]; j < jj; j++) {2561 p[j] *= ky;2562 }2563 } else {2564 for (j = 1, jj = p[length]; j < jj; j++) {2565 p[j] *= (j % 2) ? kx : ky;2566 }2567 }2568 }2569 var dim2 = pathDimensions(path),2570 dx = ncx - dim2.x - dim2.width / 2,2571 dy = ncy - dim2.y - dim2.height / 2;2572 path[0][1] += dx;2573 path[0][2] += dy;2574 this.attr({path: path});2575 break;2576 }2577 if (this.type in {text: 1, image:1} && (dirx != 1 || diry != 1)) {2578 if (this.transformations) {2579 this.transformations[2] = "scale("[concat](dirx, ",", diry, ")");2580 this.node[setAttribute]("transform", this.transformations[join](S));2581 dx = (dirx == -1) ? -a.x - (neww || 0) : a.x;2582 dy = (diry == -1) ? -a.y - (newh || 0) : a.y;2583 this.attr({x: dx, y: dy});2584 a.fx = dirx - 1;2585 a.fy = diry - 1;2586 } else {2587 this.node.filterMatrix = " progid:DXImageTransform.Microsoft.Matrix(M11="[concat](dirx,2588 ", M12=0, M21=0, M22=", diry,2589 ", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");2590 s.filter = (this.node.filterMatrix || E) + (this.node.filterOpacity || E);2591 }2592 } else {2593 if (this.transformations) {2594 this.transformations[2] = E;2595 this.node[setAttribute]("transform", this.transformations[join](S));2596 a.fx = 0;2597 a.fy = 0;2598 } else {2599 this.node.filterMatrix = E;2600 s.filter = (this.node.filterMatrix || E) + (this.node.filterOpacity || E);2601 }2602 }2603 a.scale = [x, y, cx, cy][join](S);2604 this._.sx = x;2605 this._.sy = y;2606 }2607 return this;2608 };2609 Element[proto].clone = function () {2610 var attr = this.attr();2611 delete attr.scale;2612 delete attr.translation;2613 return this.paper[this.type]().attr(attr);2614 };2615 var getLengthFactory = function (istotal, subpath) {2616 return function (path, length, onlystart) {2617 path = path2curve(path);2618 var x, y, p, l, sp = "", subpaths = {}, point,2619 len = 0;2620 for (var i = 0, ii = path.length; i < ii; i++) {2621 p = path[i];2622 if (p[0] == "M") {2623 x = +p[1];2624 y = +p[2];2625 } else {2626 l = segmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);2627 if (len + l > length) {2628 if (subpath && !subpaths.start) {2629 point = R.findDotsAtSegment(x, y, p[1], p[2], p[3], p[4], p[5], p[6], (length - len) / l);2630 sp += ["C", point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y];2631 if (onlystart) {2632 return sp;2633 }2634 subpaths.start = sp;2635 sp = ["M", point.x, point.y, "C", point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]][join]();2636 len += l;2637 x = +p[5];2638 y = +p[6];2639 continue;2640 }2641 if (!istotal && !subpath) {2642 point = R.findDotsAtSegment(x, y, p[1], p[2], p[3], p[4], p[5], p[6], (length - len) / l);2643 return {x: point.x, y: point.y, alpha: point.alpha};2644 }2645 }2646 len += l;2647 x = +p[5];2648 y = +p[6];2649 }2650 sp += p;2651 }2652 subpaths.end = sp;2653 point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[1], p[2], p[3], p[4], p[5], p[6], 1);2654 point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha});2655 return point;2656 };2657 },2658 segmentLength = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {2659 var old = {x: 0, y: 0},2660 len = 0;2661 for (var i = 0; i < 1.01; i+=.01) {2662 var dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, i);2663 i && (len += math.sqrt(pow(old.x - dot.x, 2) + pow(old.y - dot.y, 2)));2664 old = dot;2665 }2666 return len;2667 });2668 var getTotalLength = getLengthFactory(1),2669 getPointAtLength = getLengthFactory(),2670 getSubpathsAtLength = getLengthFactory(0, 1);2671 Element[proto].getTotalLength = function () {2672 if (this.type != "path") return;2673 return getTotalLength(this.attrs.path);2674 };2675 Element[proto].getPointAtLength = function (length) {2676 if (this.type != "path") return;2677 return getPointAtLength(this.attrs.path, length);2678 };2679 Element[proto].getSubpath = function (from, to) {2680 if (this.type != "path") return;2681 var a = getSubpathsAtLength(this.attrs.path, to, 1);2682 return from ? getSubpathsAtLength(a, from).end : a;2683 };2685 // animation easing formulas2686 R.easing_formulas = {2687 linear: function (n) {2688 return n;2689 },2690 "<": function (n) {2691 return pow(n, 3);2692 },2693 ">": function (n) {2694 return pow(n - 1, 3) + 1;2695 },2696 "<>": function (n) {2697 n = n * 2;2698 if (n < 1) {2699 return pow(n, 3) / 2;2700 }2701 n -= 2;2702 return (pow(n, 3) + 2) / 2;2703 },2704 backIn: function (n) {2705 var s = 1.70158;2706 return n * n * ((s + 1) * n - s);2707 },2708 backOut: function (n) {2709 n = n - 1;2710 var s = 1.70158;2711 return n * n * ((s + 1) * n + s) + 1;2712 },2713 elastic: function (n) {2714 if (n == 0 || n == 1) {2715 return n;2716 }2717 var p = .3,2718 s = p / 4;2719 return pow(2, -10 * n) * math.sin((n - s) * (2 * math.PI) / p) + 1;2720 },2721 bounce: function (n) {2722 var s = 7.5625,2723 p = 2.75,2724 l;2725 if (n < (1 / p)) {2726 l = s * n * n;2727 } else {2728 if (n < (2 / p)) {2729 n -= (1.5 / p);2730 l = s * n * n + .75;2731 } else {2732 if (n < (2.5 / p)) {2733 n -= (2.25 / p);2734 l = s * n * n + .9375;2735 } else {2736 n -= (2.625 / p);2737 l = s * n * n + .984375;2738 }2739 }2740 }2741 return l;2742 }2743 };2745 var animationElements = {length : 0},2746 animation = function () {2747 var Now = +new Date;2748 for (var l in animationElements) if (l != "length" && animationElements[has](l)) {2749 var e = animationElements[l];2750 if (e.stop) {2751 delete animationElements[l];2752 animationElements[length]--;2753 continue;2754 }2755 var time = Now - e.start,2756 ms = e.ms,2757 easing = e.easing,2758 from = e.from,2759 diff = e.diff,2760 to = e.to,2761 t = e.t,2762 prev = e.prev || 0,2763 that = e.el,2764 callback = e.callback,2765 set = {},2766 now;2767 if (time < ms) {2768 var pos = R.easing_formulas[easing] ? R.easing_formulas[easing](time / ms) : time / ms;2769 for (var attr in from) if (from[has](attr)) {2770 switch (availableAnimAttrs[attr]) {2771 case "along":2772 now = pos * ms * diff[attr];2773 to.back && (now = to.len - now);2774 var point = getPointAtLength(to[attr], now);2775 that.translate(diff.sx - diff.x || 0, diff.sy - diff.y || 0);2776 diff.x = point.x;2777 diff.y = point.y;2778 that.translate(point.x - diff.sx, point.y - diff.sy);2779 to.rot && that.rotate(diff.r + point.alpha, point.x, point.y);2780 break;2781 case "number":2782 now = +from[attr] + pos * ms * diff[attr];2783 break;2784 case "colour":2785 now = "rgb(" + [2786 upto255(round(from[attr].r + pos * ms * diff[attr].r)),2787 upto255(round(from[attr].g + pos * ms * diff[attr].g)),2788 upto255(round(from[attr].b + pos * ms * diff[attr].b))2789 ][join](",") + ")";2790 break;2791 case "path":2792 now = [];2793 for (var i = 0, ii = from[attr][length]; i < ii; i++) {2794 now[i] = [from[attr][i][0]];2795 for (var j = 1, jj = from[attr][i][length]; j < jj; j++) {2796 now[i][j] = +from[attr][i][j] + pos * ms * diff[attr][i][j];2797 }2798 now[i] = now[i][join](S);2799 }2800 now = now[join](S);2801 break;2802 case "csv":2803 switch (attr) {2804 case "translation":2805 var x = diff[attr][0] * (time - prev),2806 y = diff[attr][1] * (time - prev);2807 t.x += x;2808 t.y += y;2809 now = x + S + y;2810 break;2811 case "rotation":2812 now = +from[attr][0] + pos * ms * diff[attr][0];2813 from[attr][1] && (now += "," + from[attr][1] + "," + from[attr][2]);2814 break;2815 case "scale":2816 now = [+from[attr][0] + pos * ms * diff[attr][0], +from[attr][1] + pos * ms * diff[attr][1], (2 in to[attr] ? to[attr][2] : E), (3 in to[attr] ? to[attr][3] : E)][join](S);2817 break;2818 case "clip-rect":2819 now = [];2820 var i = 4;2821 while (i--) {2822 now[i] = +from[attr][i] + pos * ms * diff[attr][i];2823 }2824 break;2825 }2826 break;2827 }2828 set[attr] = now;2829 }2830 that.attr(set);2831 that._run && that._run.call(that);2832 } else {2833 if (to.along) {2834 var point = getPointAtLength(to.along, to.len * !to.back);2835 that.translate(diff.sx - (diff.x || 0) + point.x - diff.sx, diff.sy - (diff.y || 0) + point.y - diff.sy);2836 to.rot && that.rotate(diff.r + point.alpha, point.x, point.y);2837 }2838 (t.x || t.y) && that.translate(-t.x, -t.y);2839 to.scale && (to.scale = to.scale + E);2840 that.attr(to);2841 delete animationElements[l];2842 animationElements[length]--;2843 that.in_animation = null;2844 R.is(callback, "function") && callback.call(that);2845 }2846 e.prev = time;2847 }2848 R.svg && that && that.paper.safari();2849 animationElements[length] && setTimeout(animation);2850 },2851 upto255 = function (color) {2852 return color > 255 ? 255 : (color < 0 ? 0 : color);2853 },2854 translate = function (x, y) {2855 if (x == null) {2856 return {x: this._.tx, y: this._.ty, toString: x_y};2857 }2858 this._.tx += +x;2859 this._.ty += +y;2860 switch (this.type) {2861 case "circle":2862 case "ellipse":2863 this.attr({cx: +x + this.attrs.cx, cy: +y + this.attrs.cy});2864 break;2865 case "rect":2866 case "image":2867 case "text":2868 this.attr({x: +x + this.attrs.x, y: +y + this.attrs.y});2869 break;2870 case "path":2871 var path = pathToRelative(this.attrs.path);2872 path[0][1] += +x;2873 path[0][2] += +y;2874 this.attr({path: path});2875 break;2876 }2877 return this;2878 };2879 Element[proto].animateWith = function (element, params, ms, easing, callback) {2880 animationElements[element.id] && (params.start = animationElements[element.id].start);2881 return this.animate(params, ms, easing, callback);2882 };2883 Element[proto].animateAlong = along();2884 Element[proto].animateAlongBack = along(1);2885 function along(isBack) {2886 return function (path, ms, rotate, callback) {2887 var params = {back: isBack};2888 R.is(rotate, "function") ? (callback = rotate) : (params.rot = rotate);2889 path && path.constructor == Element && (path = path.attrs.path);2890 path && (params.along = path);2891 return this.animate(params, ms, callback);2892 };2893 }2894 Element[proto].onAnimation = function (f) {2895 this._run = f || 0;2896 return this;2897 };2898 Element[proto].animate = function (params, ms, easing, callback) {2899 if (R.is(easing, "function") || !easing) {2900 callback = easing || null;2901 }2902 var from = {},2903 to = {},2904 diff = {};2905 for (var attr in params) if (params[has](attr)) {2906 if (availableAnimAttrs[has](attr)) {2907 from[attr] = this.attr(attr);2908 (from[attr] == null) && (from[attr] = availableAttrs[attr]);2909 to[attr] = params[attr];2910 switch (availableAnimAttrs[attr]) {2911 case "along":2912 var len = getTotalLength(params[attr]),2913 point = getPointAtLength(params[attr], len * !!params.back),2914 bb = this.getBBox();2915 diff[attr] = len / ms;2916 diff.tx = bb.x;2917 diff.ty = bb.y;2918 diff.sx = point.x;2919 diff.sy = point.y;2920 to.rot = params.rot;2921 to.back = params.back;2922 to.len = len;2923 params.rot && (diff.r = toFloat(this.rotate()) || 0);2924 break;2925 case "number":2926 diff[attr] = (to[attr] - from[attr]) / ms;2927 break;2928 case "colour":2929 from[attr] = R.getRGB(from[attr]);2930 var toColour = R.getRGB(to[attr]);2931 diff[attr] = {2932 r: (toColour.r - from[attr].r) / ms,2933 g: (toColour.g - from[attr].g) / ms,2934 b: (toColour.b - from[attr].b) / ms2935 };2936 break;2937 case "path":2938 var pathes = path2curve(from[attr], to[attr]);2939 from[attr] = pathes[0];2940 var toPath = pathes[1];2941 diff[attr] = [];2942 for (var i = 0, ii = from[attr][length]; i < ii; i++) {2943 diff[attr][i] = [0];2944 for (var j = 1, jj = from[attr][i][length]; j < jj; j++) {2945 diff[attr][i][j] = (toPath[i][j] - from[attr][i][j]) / ms;2946 }2947 }2948 break;2949 case "csv":2950 var values = (params[attr] + E)[split](separator),2951 from2 = (from[attr] + E)[split](separator);2952 switch (attr) {2953 case "translation":2954 from[attr] = [0, 0];2955 diff[attr] = [values[0] / ms, values[1] / ms];2956 break;2957 case "rotation":2958 from[attr] = (from2[1] == values[1] && from2[2] == values[2]) ? from2 : [0, values[1], values[2]];2959 diff[attr] = [(values[0] - from[attr][0]) / ms, 0, 0];2960 break;2961 case "scale":2962 params[attr] = values;2963 from[attr] = (from[attr] + E)[split](separator);2964 diff[attr] = [(values[0] - from[attr][0]) / ms, (values[1] - from[attr][1]) / ms, 0, 0];2965 break;2966 case "clip-rect":2967 from[attr] = (from[attr] + E)[split](separator);2968 diff[attr] = [];2969 var i = 4;2970 while (i--) {2971 diff[attr][i] = (values[i] - from[attr][i]) / ms;2972 }2973 break;2974 }2975 to[attr] = values;2976 }2977 }2978 }2979 this.stop();2980 this.in_animation = 1;2981 animationElements[this.id] = {2982 start: params.start || +new Date,2983 ms: ms,2984 easing: easing,2985 from: from,2986 diff: diff,2987 to: to,2988 el: this,2989 callback: callback,2990 t: {x: 0, y: 0}2991 };2992 ++animationElements[length] == 1 && animation();2993 return this;2994 };2995 Element[proto].stop = function () {2996 animationElements[this.id] && animationElements[length]--;2997 delete animationElements[this.id];2998 return this;2999 };3000 Element[proto].translate = function (x, y) {3001 return this.attr({translation: x + " " + y});3002 };3003 Element[proto][toString] = function () {3004 return "Rapha\xebl\u2019s object";3005 };3006 R.ae = animationElements;3008 // Set3009 var Set = function (items) {3010 this.items = [];3011 this[length] = 0;3012 if (items) {3013 for (var i = 0, ii = items[length]; i < ii; i++) {3014 if (items[i] && (items[i].constructor == Element || items[i].constructor == Set)) {3015 this[this.items[length]] = this.items[this.items[length]] = items[i];3016 this[length]++;3017 }3018 }3019 }3020 };3021 Set[proto][push] = function () {3022 var item,3023 len;3024 for (var i = 0, ii = arguments[length]; i < ii; i++) {3025 item = arguments[i];3026 if (item && (item.constructor == Element || item.constructor == Set)) {3027 len = this.items[length];3028 this[len] = this.items[len] = item;3029 this[length]++;3030 }3031 }3032 return this;3033 };3034 Set[proto].pop = function () {3035 delete this[this[length]--];3036 return this.items.pop();3037 };3038 for (var method in Element[proto]) if (Element[proto][has](method)) {3039 Set[proto][method] = (function (methodname) {3040 return function () {3041 for (var i = 0, ii = this.items[length]; i < ii; i++) {3042 this.items[i][methodname][apply](this.items[i], arguments);3043 }3044 return this;3045 };3046 })(method);3047 }3048 Set[proto].attr = function (name, value) {3049 if (name && R.is(name, "array") && R.is(name[0], "object")) {3050 for (var j = 0, jj = name[length]; j < jj; j++) {3051 this.items[j].attr(name[j]);3052 }3053 } else {3054 for (var i = 0, ii = this.items[length]; i < ii; i++) {3055 this.items[i].attr[apply](this.items[i], arguments);3056 }3057 }3058 return this;3059 };3060 Set[proto].animate = function (params, ms, easing, callback) {3061 (R.is(easing, "function") || !easing) && (callback = easing || null);3062 var len = this.items[length],3063 i = len,3064 set = this,3065 collector;3066 callback && (collector = function () {3067 !--len && callback.call(set);3068 });3069 this.items[--i].animate(params, ms, easing || collector, collector);3070 while (i--) {3071 this.items[i].animateWith(this.items[len - 1], params, ms, easing || collector, collector);3072 }3073 return this;3074 };3075 Set[proto].insertAfter = function (el) {3076 var i = this.items[length];3077 while (i--) {3078 this.items[i].insertAfter(el);3079 }3080 return this;3081 };3082 Set[proto].getBBox = function () {3083 var x = [],3084 y = [],3085 w = [],3086 h = [];3087 for (var i = this.items[length]; i--;) {3088 var box = this.items[i].getBBox();3089 x[push](box.x);3090 y[push](box.y);3091 w[push](box.x + box.width);3092 h[push](box.y + box.height);3093 }3094 x = mmin[apply](0, x);3095 y = mmin[apply](0, y);3096 return {3097 x: x,3098 y: y,3099 width: mmax[apply](0, w) - x,3100 height: mmax[apply](0, h) - y3101 };3102 };3104 R.registerFont = function (font) {3105 if (!font.face) {3106 return font;3107 }3108 this.fonts = this.fonts || {};3109 var fontcopy = {3110 w: font.w,3111 face: {},3112 glyphs: {}3113 },3114 family = font.face["font-family"];3115 for (var prop in font.face) if (font.face[has](prop)) {3116 fontcopy.face[prop] = font.face[prop];3117 }3118 if (this.fonts[family]) {3119 this.fonts[family][push](fontcopy);3120 } else {3121 this.fonts[family] = [fontcopy];3122 }3123 if (!font.svg) {3124 fontcopy.face["units-per-em"] = toInt(font.face["units-per-em"], 10);3125 for (var glyph in font.glyphs) if (font.glyphs[has](glyph)) {3126 var path = font.glyphs[glyph];3127 fontcopy.glyphs[glyph] = {3128 w: path.w,3129 k: {},3130 d: path.d && "M" + path.d[rp](/[mlcxtrv]/g, function (command) {3131 return {l: "L", c: "C", x: "z", t: "m", r: "l", v: "c"}[command] || "M";3132 }) + "z"3133 };3134 if (path.k) {3135 for (var k in path.k) if (path[has](k)) {3136 fontcopy.glyphs[glyph].k[k] = path.k[k];3137 }3138 }3139 }3140 }3141 return font;3142 };3143 Paper[proto].getFont = function (family, weight, style, stretch) {3144 stretch = stretch || "normal";3145 style = style || "normal";3146 weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400;3147 var font = R.fonts[family];3148 if (!font) {3149 var name = new RegExp("(^|\\s)" + family[rp](/[^\w\d\s+!~.:_-]/g, E) + "(\\s|$)", "i");3150 for (var fontName in R.fonts) if (R.fonts[has](fontName)) {3151 if (name.test(fontName)) {3152 font = R.fonts[fontName];3153 break;3154 }3155 }3156 }3157 var thefont;3158 if (font) {3159 for (var i = 0, ii = font[length]; i < ii; i++) {3160 thefont = font[i];3161 if (thefont.face["font-weight"] == weight && (thefont.face["font-style"] == style || !thefont.face["font-style"]) && thefont.face["font-stretch"] == stretch) {3162 break;3163 }3164 }3165 }3166 return thefont;3167 };3168 Paper[proto].print = function (x, y, string, font, size, origin) {3169 origin = origin || "middle"; // baseline|middle3170 var out = this.set(),3171 letters = (string + E)[split](E),3172 shift = 0,3173 path = E,3174 scale;3175 R.is(font, "string") && (font = this.getFont(font));3176 if (font) {3177 scale = (size || 16) / font.face["units-per-em"];3178 var bb = font.face.bbox.split(separator),3179 top = +bb[0],3180 height = +bb[1] + (origin == "baseline" ? bb[3] - bb[1] + (+font.face.descent) : (bb[3] - bb[1]) / 2);3181 for (var i = 0, ii = letters[length]; i < ii; i++) {3182 var prev = i && font.glyphs[letters[i - 1]] || {},3183 curr = font.glyphs[letters[i]];3184 shift += i ? (prev.w || font.w) + (prev.k && prev.k[letters[i]] || 0) : 0;3185 curr && curr.d && out[push](this.path(curr.d).attr({fill: "#000", stroke: "none", translation: [shift, 0]}));3186 }3187 out.scale(scale, scale, top, height).translate(x - top, y - height);3188 }3189 return out;3190 };3192 R.format = function (token) {3193 var args = R.is(arguments[1], "array") ? [0][concat](arguments[1]) : arguments,3194 rg = /\{(\d+)\}/g;3195 token && R.is(token, "string") && args[length] - 1 && (token = token[rp](rg, function (str, i) {3196 return args[++i] == null ? E : args[i];3197 }));3198 return token || E;3199 };3200 R.ninja = function () {3201 var r = win.Raphael, u;3202 if (oldRaphael.was) {3203 win.Raphael = oldRaphael.is;3204 } else {3205 try {3206 delete win.Raphael;3207 } catch (e) {3208 win.Raphael = u;3209 }3210 }3211 return r;3212 };3213 R.el = Element[proto];3214 return R;3215 })();