visage-app 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,74 +1,84 @@
1
1
  /*!
2
- * Raphael 1.3.0 - JavaScript Vector Library
2
+ * Raphael 1.4.3 - JavaScript Vector Library
3
3
  *
4
- * Copyright (c) 2008 - 2009 Dmitry Baranovskiy (http://raphaeljs.com)
4
+ * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
5
5
  * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
6
6
  */
7
7
 
8
-
9
- window.Raphael = (function () {
8
+ Raphael = (function () {
9
+ function R() {
10
+ if (R.is(arguments[0], array)) {
11
+ var a = arguments[0],
12
+ cnv = create[apply](R, a.splice(0, 3 + R.is(a[0], nu))),
13
+ res = cnv.set();
14
+ for (var i = 0, ii = a[length]; i < ii; i++) {
15
+ var j = a[i] || {};
16
+ elements.test(j.type) && res[push](cnv[j.type]().attr(j));
17
+ }
18
+ return res;
19
+ }
20
+ return create[apply](R, arguments);
21
+ }
22
+ R.version = "1.4.3";
10
23
  var separator = /[, ]+/,
11
24
  elements = /^(circle|rect|path|ellipse|text|image)$/,
25
+ proto = "prototype",
26
+ has = "hasOwnProperty",
12
27
  doc = document,
13
28
  win = window,
14
29
  oldRaphael = {
15
- was: "Raphael" in win,
30
+ was: Object[proto][has].call(win, "Raphael"),
16
31
  is: win.Raphael
17
32
  },
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
33
  Paper = function () {},
32
34
  appendChild = "appendChild",
33
35
  apply = "apply",
34
36
  concat = "concat",
37
+ supportsTouch = "createTouch" in doc,
35
38
  E = "",
36
39
  S = " ",
37
40
  split = "split",
38
- events = "click dblclick mousedown mousemove mouseout mouseover mouseup"[split](S),
39
- has = "hasOwnProperty",
41
+ events = "click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[split](S),
42
+ touchMap = {
43
+ mousedown: "touchstart",
44
+ mousemove: "touchmove",
45
+ mouseup: "touchend"
46
+ },
40
47
  join = "join",
41
48
  length = "length",
42
- proto = "prototype",
43
49
  lowerCase = String[proto].toLowerCase,
44
50
  math = Math,
45
51
  mmax = math.max,
46
52
  mmin = math.min,
47
53
  nu = "number",
54
+ string = "string",
55
+ array = "array",
48
56
  toString = "toString",
57
+ fillString = "fill",
49
58
  objectToString = Object[proto][toString],
50
59
  paper = {},
51
60
  pow = math.pow,
52
61
  push = "push",
53
62
  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,
63
+ ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i,
64
+ colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+(?:\s*,\s*[\d\.]+)?)\s*\)|rgba?\(\s*([\d\.]+%\s*,\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
65
  round = math.round,
57
66
  setAttribute = "setAttribute",
58
67
  toFloat = parseFloat,
59
68
  toInt = parseInt,
69
+ ms = " progid:DXImageTransform.Microsoft",
60
70
  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},
71
+ availableAttrs = {blur: 0, "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},
72
+ availableAnimAttrs = {along: "along", blur: nu, "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
73
  rp = "replace";
64
- R.version = "1.3.0";
65
74
  R.type = (win.SVGAngle || doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML");
66
75
  if (R.type == "VML") {
67
- var d = document.createElement("div");
76
+ var d = doc.createElement("div");
68
77
  d.innerHTML = '<!--[if vml]><br><br><![endif]-->';
69
78
  if (d.childNodes[length] != 2) {
70
- return null;
79
+ return R.type = null;
71
80
  }
81
+ d = null;
72
82
  }
73
83
  R.svg = !(R.vml = R.type == "VML");
74
84
  Paper[proto] = R[proto];
@@ -77,8 +87,12 @@ window.Raphael = (function () {
77
87
  R.fn = {};
78
88
  R.is = function (o, type) {
79
89
  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;
90
+ return (type == "object" && o === Object(o)) ||
91
+ (type == "undefined" && typeof o == type) ||
92
+ (type == "null" && o == null) ||
93
+ lowerCase.call(objectToString.call(o).slice(8, -1)) == type;
81
94
  };
95
+
82
96
  R.setWindow = function (newwin) {
83
97
  win = newwin;
84
98
  doc = win.document;
@@ -92,12 +106,12 @@ window.Raphael = (function () {
92
106
  var bod;
93
107
  color = (color + E)[rp](trim, E);
94
108
  try {
95
- var docum = new ActiveXObject("htmlfile");
109
+ var docum = new win.ActiveXObject("htmlfile");
96
110
  docum.write("<body>");
97
111
  docum.close();
98
112
  bod = docum.body;
99
113
  } catch(e) {
100
- bod = createPopup().document.body;
114
+ bod = win.createPopup().document.body;
101
115
  }
102
116
  var range = bod.createTextRange();
103
117
  try {
@@ -121,6 +135,12 @@ window.Raphael = (function () {
121
135
  }
122
136
  return toHex(color);
123
137
  };
138
+ var hsbtoString = function () {
139
+ return "hsb(" + [this.h, this.s, this.b] + ")";
140
+ },
141
+ rgbtoString = function () {
142
+ return this.hex;
143
+ };
124
144
  R.hsb2rgb = cacher(function (hue, saturation, brightness) {
125
145
  if (R.is(hue, "object") && "h" in hue && "s" in hue && "b" in hue) {
126
146
  brightness = hue.b;
@@ -149,7 +169,7 @@ window.Raphael = (function () {
149
169
  red *= 255;
150
170
  green *= 255;
151
171
  blue *= 255;
152
- var rgb = {r: red, g: green, b: blue},
172
+ var rgb = {r: red, g: green, b: blue, toString: rgbtoString},
153
173
  r = (~~red)[toString](16),
154
174
  g = (~~green)[toString](16),
155
175
  b = (~~blue)[toString](16);
@@ -165,7 +185,7 @@ window.Raphael = (function () {
165
185
  green = red.g;
166
186
  red = red.r;
167
187
  }
168
- if (R.is(red, "string")) {
188
+ if (R.is(red, string)) {
169
189
  var clr = R.getRGB(red);
170
190
  red = clr.r;
171
191
  green = clr.g;
@@ -197,9 +217,11 @@ window.Raphael = (function () {
197
217
  hue < 0 && hue++;
198
218
  hue > 1 && hue--;
199
219
  }
200
- return {h: hue, s: saturation, b: brightness};
220
+ return {h: hue, s: saturation, b: brightness, toString: hsbtoString};
201
221
  }, R);
202
- var p2s = /,?([achlmqrstvxz]),?/gi;
222
+ var p2s = /,?([achlmqrstvxz]),?/gi,
223
+ commaSpaces = /\s*,\s*/,
224
+ hsrg = {hs: 1, rg: 1};
203
225
  R._path2string = function () {
204
226
  return this.join(",")[rp](p2s, "$1");
205
227
  };
@@ -227,11 +249,12 @@ window.Raphael = (function () {
227
249
  if (colour == "none") {
228
250
  return {r: -1, g: -1, b: -1, hex: "none"};
229
251
  }
230
- !(({hs: 1, rg: 1})[has](colour.substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour));
252
+ !(hsrg[has](colour.substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour));
231
253
  var res,
232
254
  red,
233
255
  green,
234
256
  blue,
257
+ opacity,
235
258
  t,
236
259
  rgb = colour.match(colourRegExp);
237
260
  if (rgb) {
@@ -246,26 +269,28 @@ window.Raphael = (function () {
246
269
  red = toInt((t = rgb[3].charAt(1)) + t, 16);
247
270
  }
248
271
  if (rgb[4]) {
249
- rgb = rgb[4][split](/\s*,\s*/);
272
+ rgb = rgb[4][split](commaSpaces);
250
273
  red = toFloat(rgb[0]);
251
274
  green = toFloat(rgb[1]);
252
275
  blue = toFloat(rgb[2]);
276
+ opacity = toFloat(rgb[3]);
253
277
  }
254
278
  if (rgb[5]) {
255
- rgb = rgb[5][split](/\s*,\s*/);
279
+ rgb = rgb[5][split](commaSpaces);
256
280
  red = toFloat(rgb[0]) * 2.55;
257
281
  green = toFloat(rgb[1]) * 2.55;
258
282
  blue = toFloat(rgb[2]) * 2.55;
283
+ opacity = toFloat(rgb[3]);
259
284
  }
260
285
  if (rgb[6]) {
261
- rgb = rgb[6][split](/\s*,\s*/);
286
+ rgb = rgb[6][split](commaSpaces);
262
287
  red = toFloat(rgb[0]);
263
288
  green = toFloat(rgb[1]);
264
289
  blue = toFloat(rgb[2]);
265
290
  return R.hsb2rgb(red, green, blue);
266
291
  }
267
292
  if (rgb[7]) {
268
- rgb = rgb[7][split](/\s*,\s*/);
293
+ rgb = rgb[7][split](commaSpaces);
269
294
  red = toFloat(rgb[0]) * 2.55;
270
295
  green = toFloat(rgb[1]) * 2.55;
271
296
  blue = toFloat(rgb[2]) * 2.55;
@@ -279,6 +304,7 @@ window.Raphael = (function () {
279
304
  g = g[rp](rg, "0");
280
305
  b = b[rp](rg, "0");
281
306
  rgb.hex = "#" + r + g + b;
307
+ isFinite(toFloat(opacity)) && (rgb.o = opacity);
282
308
  return rgb;
283
309
  }
284
310
  return {r: -1, g: -1, b: -1, hex: "none", error: 1};
@@ -298,27 +324,34 @@ window.Raphael = (function () {
298
324
  delete this.start;
299
325
  };
300
326
  // path utilities
327
+ var pathCommand = /([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,
328
+ pathValues = /(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig;
301
329
  R.parsePathString = cacher(function (pathString) {
302
330
  if (!pathString) {
303
331
  return null;
304
332
  }
305
333
  var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0},
306
334
  data = [];
307
- if (R.is(pathString, "array") && R.is(pathString[0], "array")) { // rough assumption
335
+ if (R.is(pathString, array) && R.is(pathString[0], array)) { // rough assumption
308
336
  data = pathClone(pathString);
309
337
  }
310
338
  if (!data[length]) {
311
- (pathString + E)[rp](/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig, function (a, b, c) {
339
+ (pathString + E)[rp](pathCommand, function (a, b, c) {
312
340
  var params = [],
313
341
  name = lowerCase.call(b);
314
- c[rp](/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig, function (a, b) {
342
+ c[rp](pathValues, function (a, b) {
315
343
  b && params[push](+b);
316
344
  });
345
+ if (name == "m" && params[length] > 2) {
346
+ data[push]([b][concat](params.splice(0, 2)));
347
+ name = "l";
348
+ b = b == "m" ? "l" : "L";
349
+ }
317
350
  while (params[length] >= paramCounts[name]) {
318
351
  data[push]([b][concat](params.splice(0, paramCounts[name])));
319
352
  if (!paramCounts[name]) {
320
353
  break;
321
- };
354
+ }
322
355
  }
323
356
  });
324
357
  }
@@ -377,7 +410,7 @@ window.Raphael = (function () {
377
410
  }),
378
411
  pathClone = function (pathArray) {
379
412
  var res = [];
380
- if (!R.is(pathArray, "array") || !R.is(pathArray && pathArray[0], "array")) { // rough assumption
413
+ if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption
381
414
  pathArray = R.parsePathString(pathArray);
382
415
  }
383
416
  for (var i = 0, ii = pathArray[length]; i < ii; i++) {
@@ -390,7 +423,7 @@ window.Raphael = (function () {
390
423
  return res;
391
424
  },
392
425
  pathToRelative = cacher(function (pathArray) {
393
- if (!R.is(pathArray, "array") || !R.is(pathArray && pathArray[0], "array")) { // rough assumption
426
+ if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption
394
427
  pathArray = R.parsePathString(pathArray);
395
428
  }
396
429
  var res = [],
@@ -464,7 +497,7 @@ window.Raphael = (function () {
464
497
  return res;
465
498
  }, 0, pathClone),
466
499
  pathToAbsolute = cacher(function (pathArray) {
467
- if (!R.is(pathArray, "array") || !R.is(pathArray && pathArray[0], "array")) { // rough assumption
500
+ if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption
468
501
  pathArray = R.parsePathString(pathArray);
469
502
  }
470
503
  var res = [],
@@ -573,8 +606,12 @@ window.Raphael = (function () {
573
606
  sin = math.sin(PI / 180 * angle),
574
607
  x = (x1 - x2) / 2,
575
608
  y = (y1 - y2) / 2;
576
- rx = mmax(rx, math.abs(x));
577
- ry = mmax(ry, math.abs(y));
609
+ var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
610
+ if (h > 1) {
611
+ h = math.sqrt(h);
612
+ rx = h * rx;
613
+ ry = h * ry;
614
+ }
578
615
  var rx2 = rx * rx,
579
616
  ry2 = ry * ry,
580
617
  k = (large_arc_flag == sweep_flag ? -1 : 1) *
@@ -583,7 +620,7 @@ window.Raphael = (function () {
583
620
  cy = k * -ry * x / rx + (y1 + y2) / 2,
584
621
  f1 = math.asin(((y1 - cy) / ry).toFixed(7)),
585
622
  f2 = math.asin(((y2 - cy) / ry).toFixed(7));
586
-
623
+
587
624
  f1 = x1 < cx ? PI - f1 : f1;
588
625
  f2 = x2 < cx ? PI - f2 : f2;
589
626
  f1 < 0 && (f1 = PI * 2 + f1);
@@ -790,7 +827,7 @@ window.Raphael = (function () {
790
827
  par[2] && (dot.offset = par[2] + "%");
791
828
  dots[push](dot);
792
829
  }
793
- for (var i = 1, ii = dots[length] - 1; i < ii; i++) {
830
+ for (i = 1, ii = dots[length] - 1; i < ii; i++) {
794
831
  if (!dots[i].offset) {
795
832
  var start = toFloat(dots[i - 1].offset || 0),
796
833
  end = 0;
@@ -814,49 +851,43 @@ window.Raphael = (function () {
814
851
  }
815
852
  return dots;
816
853
  }),
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
- }
854
+ getContainer = function (x, y, w, h) {
855
+ var container;
856
+ if (R.is(x, string) || R.is(x, "object")) {
857
+ container = R.is(x, string) ? doc.getElementById(x) : x;
829
858
  if (container.tagName) {
830
- if (arguments[1] == null) {
859
+ if (y == null) {
831
860
  return {
832
861
  container: container,
833
862
  width: container.style.pixelWidth || container.offsetWidth,
834
863
  height: container.style.pixelHeight || container.offsetHeight
835
864
  };
836
865
  } else {
837
- return {container: container, width: arguments[1], height: arguments[2]};
866
+ return {container: container, width: y, height: w};
838
867
  }
839
868
  }
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]};
869
+ } else {
870
+ return {container: 1, x: x, y: y, width: w, height: h};
842
871
  }
843
872
  },
844
873
  plugins = function (con, add) {
845
874
  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;
875
+ for (var prop in add) {
876
+ if (add[has](prop) && !(prop in con)) {
877
+ switch (typeof add[prop]) {
878
+ case "function":
879
+ (function (f) {
880
+ con[prop] = con === that ? f : function () { return f[apply](that, arguments); };
881
+ })(add[prop]);
882
+ break;
883
+ case "object":
884
+ con[prop] = con[prop] || {};
885
+ plugins.call(this, con[prop], add[prop]);
886
+ break;
887
+ default:
888
+ con[prop] = add[prop];
889
+ break;
890
+ }
860
891
  }
861
892
  }
862
893
  },
@@ -913,31 +944,22 @@ window.Raphael = (function () {
913
944
  if (R.svg) {
914
945
  Paper[proto].svgns = "http://www.w3.org/2000/svg";
915
946
  Paper[proto].xlink = "http://www.w3.org/1999/xlink";
916
- var round = function (num) {
947
+ round = function (num) {
917
948
  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]);
949
+ };
950
+ var $ = function (el, attr) {
951
+ if (attr) {
952
+ for (var key in attr) {
953
+ if (attr[has](key)) {
954
+ el[setAttribute](key, attr[key] + E);
936
955
  }
937
- } else {
938
- return doc.createElementNS(Paper[proto].svgns, el);
939
956
  }
940
- };
957
+ } else {
958
+ el = doc.createElementNS(Paper[proto].svgns, el);
959
+ el.style.webkitTapHighlightColor = "rgba(0,0,0,0)";
960
+ return el;
961
+ }
962
+ };
941
963
  R[toString] = function () {
942
964
  return "Your browser supports SVG.\nYou are running Rapha\xebl " + this.version;
943
965
  };
@@ -990,6 +1012,10 @@ window.Raphael = (function () {
990
1012
  if (!dots) {
991
1013
  return null;
992
1014
  }
1015
+ var id = o.getAttribute(fillString);
1016
+ id = id.match(/^url\(#(.*)\)$/);
1017
+ id && SVG.defs.removeChild(doc.getElementById(id[1]));
1018
+
993
1019
  var el = $(type + "Gradient");
994
1020
  el.id = "r" + (R._id++)[toString](36);
995
1021
  $(el, type == "radial" ? {fx: fx, fy: fy} : {x1: vector[0], y1: vector[1], x2: vector[2], y2: vector[3]});
@@ -1001,7 +1027,7 @@ window.Raphael = (function () {
1001
1027
  "stop-color": dots[i].color || "#fff"
1002
1028
  });
1003
1029
  el[appendChild](stop);
1004
- };
1030
+ }
1005
1031
  $(o, {
1006
1032
  fill: "url(#" + el.id + ")",
1007
1033
  opacity: 1,
@@ -1056,209 +1082,216 @@ window.Raphael = (function () {
1056
1082
  rotxy[2] = +rotxy[2];
1057
1083
  }
1058
1084
  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
- // Hyperlink
1070
- 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 {
1085
+ for (var att in params) {
1086
+ if (params[has](att)) {
1087
+ if (!availableAttrs[has](att)) {
1088
+ continue;
1089
+ }
1090
+ var value = params[att];
1091
+ attrs[att] = value;
1092
+ switch (att) {
1093
+ case "blur":
1094
+ o.blur(value);
1122
1095
  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") {
1096
+ case "rotation":
1097
+ o.rotate(value, true);
1130
1098
  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 {
1099
+ case "href":
1100
+ case "title":
1101
+ case "target":
1102
+ var pn = node.parentNode;
1103
+ if (lowerCase.call(pn.tagName) != "a") {
1104
+ var hl = $("a");
1105
+ pn.insertBefore(hl, node);
1106
+ hl[appendChild](node);
1107
+ pn = hl;
1108
+ }
1109
+ pn.setAttributeNS(o.paper.xlink, att, value);
1143
1110
  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") {
1111
+ case "cursor":
1112
+ node.style.cursor = value;
1151
1113
  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);
1114
+ case "clip-rect":
1115
+ var rect = (value + E)[split](separator);
1116
+ if (rect[length] == 4) {
1117
+ o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode);
1118
+ var el = $("clipPath"),
1119
+ rc = $("rect");
1120
+ el.id = "r" + (R._id++)[toString](36);
1121
+ $(rc, {
1122
+ x: rect[0],
1123
+ y: rect[1],
1124
+ width: rect[2],
1125
+ height: rect[3]
1126
+ });
1127
+ el[appendChild](rc);
1128
+ o.paper.defs[appendChild](el);
1129
+ $(node, {"clip-path": "url(#" + el.id + ")"});
1130
+ o.clip = rc;
1131
+ }
1132
+ if (!value) {
1133
+ var clip = doc.getElementById(node.getAttribute("clip-path")[rp](/(^url\(#|\)$)/g, E));
1134
+ clip && clip.parentNode.removeChild(clip);
1135
+ $(node, {"clip-path": E});
1136
+ delete o.clip;
1137
+ }
1157
1138
  break;
1158
- case "r":
1159
- if (o.type == "rect") {
1160
- $(node, {rx: value, ry: value});
1161
- } else {
1139
+ case "path":
1140
+ if (o.type == "path") {
1141
+ $(node, {d: value ? attrs.path = pathToAbsolute(value) : "M0,0"});
1142
+ }
1143
+ break;
1144
+ case "width":
1162
1145
  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 Firefox
1173
- 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);
1205
-
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;
1146
+ if (attrs.fx) {
1147
+ att = "x";
1148
+ value = attrs.x;
1149
+ } else {
1150
+ break;
1151
+ }
1152
+ case "x":
1153
+ if (attrs.fx) {
1154
+ value = -attrs.x - (attrs.width || 0);
1155
+ }
1156
+ case "rx":
1157
+ if (att == "rx" && o.type == "rect") {
1158
+ break;
1159
+ }
1160
+ case "cx":
1161
+ rotxy && (att == "x" || att == "cx") && (rotxy[1] += value - attrs[att]);
1162
+ node[setAttribute](att, round(value));
1220
1163
  o.pattern && updatePosition(o);
1221
1164
  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";
1165
+ case "height":
1166
+ node[setAttribute](att, value);
1167
+ if (attrs.fy) {
1168
+ att = "y";
1169
+ value = attrs.y;
1170
+ } else {
1171
+ break;
1172
+ }
1173
+ case "y":
1174
+ if (attrs.fy) {
1175
+ value = -attrs.y - (attrs.height || 0);
1176
+ }
1177
+ case "ry":
1178
+ if (att == "ry" && o.type == "rect") {
1179
+ break;
1180
+ }
1181
+ case "cy":
1182
+ rotxy && (att == "y" || att == "cy") && (rotxy[2] += value - attrs[att]);
1183
+ node[setAttribute](att, round(value));
1184
+ o.pattern && updatePosition(o);
1235
1185
  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);
1186
+ case "r":
1187
+ if (o.type == "rect") {
1188
+ $(node, {rx: value, ry: value});
1189
+ } else {
1190
+ node[setAttribute](att, value);
1250
1191
  }
1251
1192
  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 Firefox
1260
- node[setAttribute](att, value);
1261
- break;
1193
+ case "src":
1194
+ if (o.type == "image") {
1195
+ node.setAttributeNS(o.paper.xlink, "href", value);
1196
+ }
1197
+ break;
1198
+ case "stroke-width":
1199
+ node.style.strokeWidth = value;
1200
+ // Need following line for Firefox
1201
+ node[setAttribute](att, value);
1202
+ if (attrs["stroke-dasharray"]) {
1203
+ addDashes(o, attrs["stroke-dasharray"]);
1204
+ }
1205
+ break;
1206
+ case "stroke-dasharray":
1207
+ addDashes(o, value);
1208
+ break;
1209
+ case "translation":
1210
+ var xy = (value + E)[split](separator);
1211
+ xy[0] = +xy[0] || 0;
1212
+ xy[1] = +xy[1] || 0;
1213
+ if (rotxy) {
1214
+ rotxy[1] += xy[0];
1215
+ rotxy[2] += xy[1];
1216
+ }
1217
+ translate.call(o, xy[0], xy[1]);
1218
+ break;
1219
+ case "scale":
1220
+ xy = (value + E)[split](separator);
1221
+ o.scale(+xy[0] || 1, +xy[1] || +xy[0] || 1, isNaN(toFloat(xy[2])) ? null : +xy[2], isNaN(toFloat(xy[3])) ? null : +xy[3]);
1222
+ break;
1223
+ case fillString:
1224
+ var isURL = (value + E).match(ISURL);
1225
+ if (isURL) {
1226
+ el = $("pattern");
1227
+ var ig = $("image");
1228
+ el.id = "r" + (R._id++)[toString](36);
1229
+ $(el, {x: 0, y: 0, patternUnits: "userSpaceOnUse", height: 1, width: 1});
1230
+ $(ig, {x: 0, y: 0});
1231
+ ig.setAttributeNS(o.paper.xlink, "href", isURL[1]);
1232
+ el[appendChild](ig);
1233
+
1234
+ var img = doc.createElement("img");
1235
+ img.style.cssText = "position:absolute;left:-9999em;top-9999em";
1236
+ img.onload = function () {
1237
+ $(el, {width: this.offsetWidth, height: this.offsetHeight});
1238
+ $(ig, {width: this.offsetWidth, height: this.offsetHeight});
1239
+ doc.body.removeChild(this);
1240
+ o.paper.safari();
1241
+ };
1242
+ doc.body[appendChild](img);
1243
+ img.src = isURL[1];
1244
+ o.paper.defs[appendChild](el);
1245
+ node.style.fill = "url(#" + el.id + ")";
1246
+ $(node, {fill: "url(#" + el.id + ")"});
1247
+ o.pattern = el;
1248
+ o.pattern && updatePosition(o);
1249
+ break;
1250
+ }
1251
+ var clr = R.getRGB(value);
1252
+ if (!clr.error) {
1253
+ delete params.gradient;
1254
+ delete attrs.gradient;
1255
+ !R.is(attrs.opacity, "undefined") &&
1256
+ R.is(params.opacity, "undefined") &&
1257
+ $(node, {opacity: attrs.opacity});
1258
+ !R.is(attrs["fill-opacity"], "undefined") &&
1259
+ R.is(params["fill-opacity"], "undefined") &&
1260
+ $(node, {"fill-opacity": attrs["fill-opacity"]});
1261
+ } else if ((({circle: 1, ellipse: 1})[has](o.type) || (value + E).charAt() != "r") && addGradientFill(node, value, o.paper)) {
1262
+ attrs.gradient = value;
1263
+ attrs.fill = "none";
1264
+ break;
1265
+ }
1266
+ clr[has]("o") && $(node, {"fill-opacity": clr.o / 100});
1267
+ case "stroke":
1268
+ clr = R.getRGB(value);
1269
+ node[setAttribute](att, clr.hex);
1270
+ att == "stroke" && clr[has]("o") && $(node, {"stroke-opacity": clr.o / 100});
1271
+ break;
1272
+ case "gradient":
1273
+ (({circle: 1, ellipse: 1})[has](o.type) || (value + E).charAt() != "r") && addGradientFill(node, value, o.paper);
1274
+ break;
1275
+ case "opacity":
1276
+ case "fill-opacity":
1277
+ if (attrs.gradient) {
1278
+ var gradient = doc.getElementById(node.getAttribute(fillString)[rp](/^url\(#|\)$/g, E));
1279
+ if (gradient) {
1280
+ var stops = gradient.getElementsByTagName("stop");
1281
+ stops[stops[length] - 1][setAttribute]("stop-opacity", value);
1282
+ }
1283
+ break;
1284
+ }
1285
+ default:
1286
+ att == "font-size" && (value = toInt(value, 10) + "px");
1287
+ var cssrule = att[rp](/(\-.)/g, function (w) {
1288
+ return upperCase.call(w.substring(1));
1289
+ });
1290
+ node.style[cssrule] = value;
1291
+ // Need following line for Firefox
1292
+ node[setAttribute](att, value);
1293
+ break;
1294
+ }
1262
1295
  }
1263
1296
  }
1264
1297
 
@@ -1269,8 +1302,8 @@ window.Raphael = (function () {
1269
1302
  toFloat(rot) && o.rotate(rot, true);
1270
1303
  }
1271
1304
  };
1272
- var leading = 1.2;
1273
- var tuneText = function (el, params) {
1305
+ var leading = 1.2,
1306
+ tuneText = function (el, params) {
1274
1307
  if (el.type != "text" || !(params[has]("text") || params[has]("font") || params[has]("font-size") || params[has]("x") || params[has]("y"))) {
1275
1308
  return;
1276
1309
  }
@@ -1291,8 +1324,8 @@ window.Raphael = (function () {
1291
1324
  node[appendChild](tspan);
1292
1325
  }
1293
1326
  } else {
1294
- var texts = node.getElementsByTagName("tspan");
1295
- for (var i = 0, ii = texts[length]; i < ii; i++) {
1327
+ texts = node.getElementsByTagName("tspan");
1328
+ for (i = 0, ii = texts[length]; i < ii; i++) {
1296
1329
  i && $(texts[i], {dy: fontSize * leading, x: a.x});
1297
1330
  }
1298
1331
  }
@@ -1300,8 +1333,8 @@ window.Raphael = (function () {
1300
1333
  var bb = el.getBBox(),
1301
1334
  dif = a.y - (bb.y + bb.height / 2);
1302
1335
  dif && isFinite(dif) && $(node, {y: a.y + dif});
1303
- };
1304
- var Element = function (node, svg) {
1336
+ },
1337
+ Element = function (node, svg) {
1305
1338
  var X = 0,
1306
1339
  Y = 0;
1307
1340
  this[0] = node;
@@ -1411,11 +1444,11 @@ window.Raphael = (function () {
1411
1444
  hide && this.hide();
1412
1445
  return bbox;
1413
1446
  };
1414
- Element[proto].attr = function () {
1447
+ Element[proto].attr = function (name, value) {
1415
1448
  if (this.removed) {
1416
1449
  return this;
1417
1450
  }
1418
- if (arguments[length] == 0) {
1451
+ if (name == null) {
1419
1452
  var res = {};
1420
1453
  for (var i in this.attrs) if (this.attrs[has](i)) {
1421
1454
  res[i] = this.attrs[i];
@@ -1425,34 +1458,34 @@ window.Raphael = (function () {
1425
1458
  res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient;
1426
1459
  return res;
1427
1460
  }
1428
- if (arguments[length] == 1 && R.is(arguments[0], "string")) {
1429
- if (arguments[0] == "translation") {
1461
+ if (value == null && R.is(name, string)) {
1462
+ if (name == "translation") {
1430
1463
  return translate.call(this);
1431
1464
  }
1432
- if (arguments[0] == "rotation") {
1465
+ if (name == "rotation") {
1433
1466
  return this.rotate();
1434
1467
  }
1435
- if (arguments[0] == "scale") {
1468
+ if (name == "scale") {
1436
1469
  return this.scale();
1437
1470
  }
1438
- if (arguments[0] == "fill" && this.attrs.fill == "none" && this.attrs.gradient) {
1471
+ if (name == fillString && this.attrs.fill == "none" && this.attrs.gradient) {
1439
1472
  return this.attrs.gradient;
1440
1473
  }
1441
- return this.attrs[arguments[0]];
1474
+ return this.attrs[name];
1442
1475
  }
1443
- if (arguments[length] == 1 && R.is(arguments[0], "array")) {
1476
+ if (value == null && R.is(name, array)) {
1444
1477
  var values = {};
1445
- for (var j in arguments[0]) if (arguments[0][has](j)) {
1446
- values[arguments[0][j]] = this.attrs[arguments[0][j]];
1478
+ for (var j = 0, jj = name.length; j < jj; j++) {
1479
+ values[name[j]] = this.attr(name[j]);
1447
1480
  }
1448
1481
  return values;
1449
1482
  }
1450
- if (arguments[length] == 2) {
1483
+ if (value != null) {
1451
1484
  var params = {};
1452
- params[arguments[0]] = arguments[1];
1485
+ params[name] = value;
1453
1486
  setFillAndStroke(this, params);
1454
- } else if (arguments[length] == 1 && R.is(arguments[0], "object")) {
1455
- setFillAndStroke(this, arguments[0]);
1487
+ } else if (name != null && R.is(name, "object")) {
1488
+ setFillAndStroke(this, name);
1456
1489
  }
1457
1490
  return this;
1458
1491
  };
@@ -1498,6 +1531,28 @@ window.Raphael = (function () {
1498
1531
  insertbefore(this, element, this.paper);
1499
1532
  return this;
1500
1533
  };
1534
+ Element[proto].blur = function (size) {
1535
+ // Experimental. No Safari support. Use it on your own risk.
1536
+ var t = this;
1537
+ if (+size !== 0) {
1538
+ var fltr = $("filter"),
1539
+ blur = $("feGaussianBlur");
1540
+ t.attrs.blur = size;
1541
+ fltr.id = "r" + (R._id++)[toString](36);
1542
+ $(blur, {stdDeviation: +size || 1.5});
1543
+ fltr.appendChild(blur);
1544
+ t.paper.defs.appendChild(fltr);
1545
+ t._blur = fltr;
1546
+ $(t.node, {filter: "url(#" + fltr.id + ")"});
1547
+ } else {
1548
+ if (t._blur) {
1549
+ t._blur.parentNode.removeChild(t._blur);
1550
+ delete t._blur;
1551
+ delete t.attrs.blur;
1552
+ }
1553
+ t.node.removeAttribute("filter");
1554
+ }
1555
+ };
1501
1556
  var theCircle = function (svg, x, y, r) {
1502
1557
  x = round(x);
1503
1558
  y = round(y);
@@ -1559,7 +1614,7 @@ window.Raphael = (function () {
1559
1614
  return this;
1560
1615
  };
1561
1616
  var create = function () {
1562
- var con = getContainer[apply](null, arguments),
1617
+ var con = getContainer[apply](0, arguments),
1563
1618
  container = con && con.container,
1564
1619
  x = con.x,
1565
1620
  y = con.y,
@@ -1569,6 +1624,8 @@ window.Raphael = (function () {
1569
1624
  throw new Error("SVG container not found.");
1570
1625
  }
1571
1626
  var cnvs = $("svg");
1627
+ x = x || 0;
1628
+ y = y || 0;
1572
1629
  width = width || 512;
1573
1630
  height = height || 342;
1574
1631
  $(cnvs, {
@@ -1612,80 +1669,101 @@ window.Raphael = (function () {
1612
1669
  }
1613
1670
  };
1614
1671
  }
1615
-
1672
+
1616
1673
  // VML
1617
1674
  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));
1675
+ var map = {M: "m", L: "l", C: "c", Z: "x", m: "t", l: "r", c: "v", z: "x"},
1676
+ bites = /([clmz]),?([^clmz]*)/gi,
1677
+ val = /-?[^,\s-]+/g,
1678
+ coordsize = 1e3 + S + 1e3,
1679
+ zoom = 10,
1680
+ pathlike = {path: 1, rect: 1},
1681
+ path2vml = function (path) {
1682
+ var total = /[ahqstv]/ig,
1683
+ command = pathToAbsolute;
1684
+ (path + E).match(total) && (command = path2curve);
1685
+ total = /[clmz]/g;
1686
+ if (command == pathToAbsolute && !(path + E).match(total)) {
1687
+ var res = (path + E)[rp](bites, function (all, command, args) {
1688
+ var vals = [],
1689
+ isMove = lowerCase.call(command) == "m",
1690
+ res = map[command];
1691
+ args[rp](val, function (value) {
1692
+ if (isMove && vals[length] == 2) {
1693
+ res += vals + map[command == "m" ? "l" : "L"];
1694
+ vals = [];
1695
+ }
1696
+ vals[push](round(value * zoom));
1697
+ });
1698
+ return res + vals;
1631
1699
  });
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);
1700
+ return res;
1701
+ }
1702
+ var pa = command(path), p, r;
1703
+ res = [];
1704
+ for (var i = 0, ii = pa[length]; i < ii; i++) {
1705
+ p = pa[i];
1706
+ r = lowerCase.call(pa[i][0]);
1707
+ r == "z" && (r = "x");
1708
+ for (var j = 1, jj = p[length]; j < jj; j++) {
1709
+ r += round(p[j] * zoom) + (j != jj - 1 ? "," : E);
1710
+ }
1711
+ res[push](r);
1643
1712
  }
1644
- res[push](r);
1645
- }
1646
- return res[join](S);
1647
- };
1713
+ return res[join](S);
1714
+ };
1648
1715
 
1649
1716
  R[toString] = function () {
1650
1717
  return "Your browser doesn\u2019t support SVG. Falling down to VML.\nYou are running Rapha\xebl " + this.version;
1651
1718
  };
1652
- var thePath = function (pathString, VML) {
1719
+ thePath = function (pathString, vml) {
1653
1720
  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;
1721
+ g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";
1722
+ g.coordsize = vml.coordsize;
1723
+ g.coordorigin = vml.coordorigin;
1657
1724
  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;
1725
+ ol.width = vml.width + "px";
1726
+ ol.height = vml.height + "px";
1727
+ el.coordsize = coordsize;
1728
+ el.coordorigin = vml.coordorigin;
1662
1729
  g[appendChild](el);
1663
- var p = new Element(el, g, VML);
1730
+ var p = new Element(el, g, vml),
1731
+ attr = {fill: "none", stroke: "#000"};
1732
+ pathString && (attr.path = pathString);
1664
1733
  p.isAbsolute = true;
1665
1734
  p.type = "path";
1666
1735
  p.path = [];
1667
1736
  p.Path = E;
1668
- pathString && setFillAndStroke(p, {fill: "none", stroke: "#000", path: pathString});
1669
- VML.canvas[appendChild](g);
1737
+ setFillAndStroke(p, attr);
1738
+ vml.canvas[appendChild](g);
1670
1739
  return p;
1671
1740
  };
1672
- var setFillAndStroke = function (o, params) {
1741
+ setFillAndStroke = function (o, params) {
1673
1742
  o.attrs = o.attrs || {};
1674
1743
  var node = o.node,
1675
1744
  a = o.attrs,
1676
1745
  s = node.style,
1677
1746
  xy,
1747
+ newpath = (params.x != a.x || params.y != a.y || params.width != a.width || params.height != a.height || params.r != a.r) && o.type == "rect",
1678
1748
  res = o;
1749
+
1679
1750
  for (var par in params) if (params[has](par)) {
1680
1751
  a[par] = params[par];
1681
1752
  }
1753
+ if (newpath) {
1754
+ a.path = rectPath(a.x, a.y, a.width, a.height, a.r);
1755
+ o.X = a.x;
1756
+ o.Y = a.y;
1757
+ o.W = a.width;
1758
+ o.H = a.height;
1759
+ }
1682
1760
  params.href && (node.href = params.href);
1683
1761
  params.title && (node.title = params.title);
1684
1762
  params.target && (node.target = params.target);
1685
1763
  params.cursor && (s.cursor = params.cursor);
1686
- if (params.path && o.type == "path") {
1687
- a.path = params.path;
1688
- node.path = path2vml(a.path);
1764
+ "blur" in params && o.blur(params.blur);
1765
+ if (params.path && o.type == "path" || newpath) {
1766
+ node.path = path2vml(a.path);
1689
1767
  }
1690
1768
  if (params.rotation != null) {
1691
1769
  o.rotate(params.rotation, true);
@@ -1731,7 +1809,7 @@ window.Raphael = (function () {
1731
1809
  node.src = params.src;
1732
1810
  }
1733
1811
  if (o.type == "image" && params.opacity) {
1734
- node.filterOpacity = " progid:DXImageTransform.Microsoft.Alpha(opacity=" + (params.opacity * 100) + ")";
1812
+ node.filterOpacity = ms + ".Alpha(opacity=" + (params.opacity * 100) + ")";
1735
1813
  s.filter = (node.filterMatrix || E) + (node.filterOpacity || E);
1736
1814
  }
1737
1815
  params.font && (s.font = params.font);
@@ -1751,11 +1829,11 @@ window.Raphael = (function () {
1751
1829
  params["stroke-linejoin"] != null ||
1752
1830
  params["stroke-linecap"] != null) {
1753
1831
  node = o.shape || node;
1754
- var fill = (node.getElementsByTagName("fill") && node.getElementsByTagName("fill")[0]),
1832
+ var fill = (node.getElementsByTagName(fillString) && node.getElementsByTagName(fillString)[0]),
1755
1833
  newfill = false;
1756
- !fill && (newfill = fill = createNode("fill"));
1834
+ !fill && (newfill = fill = createNode(fillString));
1757
1835
  if ("fill-opacity" in params || "opacity" in params) {
1758
- var opacity = ((+a["fill-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1);
1836
+ var opacity = ((+a["fill-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+R.getRGB(params.fill).o + 1 || 2) - 1);
1759
1837
  opacity < 0 && (opacity = 0);
1760
1838
  opacity > 1 && (opacity = 1);
1761
1839
  fill.opacity = opacity;
@@ -1793,9 +1871,10 @@ window.Raphael = (function () {
1793
1871
  stroke.on = true;
1794
1872
  }
1795
1873
  (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;
1874
+ var strokeColor = R.getRGB(params.stroke);
1875
+ stroke.on && params.stroke && (stroke.color = strokeColor.hex);
1876
+ opacity = ((+a["stroke-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+strokeColor.o + 1 || 2) - 1);
1877
+ var width = (toFloat(params["stroke-width"]) || 1) * .75;
1799
1878
  opacity < 0 && (opacity = 0);
1800
1879
  opacity > 1 && (opacity = 1);
1801
1880
  params["stroke-width"] == null && (width = a["stroke-width"]);
@@ -1824,7 +1903,7 @@ window.Raphael = (function () {
1824
1903
  newstroke && node[appendChild](stroke);
1825
1904
  }
1826
1905
  if (res.type == "text") {
1827
- var s = res.paper.span.style;
1906
+ s = res.paper.span.style;
1828
1907
  a.font && (s.font = a.font);
1829
1908
  a["font-family"] && (s.fontFamily = a["font-family"]);
1830
1909
  a["font-size"] && (s.fontSize = a["font-size"]);
@@ -1852,10 +1931,10 @@ window.Raphael = (function () {
1852
1931
  }
1853
1932
  }
1854
1933
  };
1855
- var addGradientFill = function (o, gradient) {
1934
+ addGradientFill = function (o, gradient) {
1856
1935
  o.attrs = o.attrs || {};
1857
1936
  var attrs = o.attrs,
1858
- fill = o.node.getElementsByTagName("fill"),
1937
+ fill,
1859
1938
  type = "linear",
1860
1939
  fxfy = ".5 .5";
1861
1940
  o.attrs.gradient = gradient;
@@ -1882,29 +1961,31 @@ window.Raphael = (function () {
1882
1961
  return null;
1883
1962
  }
1884
1963
  o = o.shape || o.node;
1885
- fill = fill[0] || createNode("fill");
1964
+ fill = o.getElementsByTagName(fillString)[0] || createNode(fillString);
1965
+ !fill.parentNode && o.appendChild(fill);
1886
1966
  if (dots[length]) {
1887
1967
  fill.on = true;
1888
1968
  fill.method = "none";
1889
- fill.type = (type == "radial") ? "gradientradial" : "gradient";
1890
1969
  fill.color = dots[0].color;
1891
1970
  fill.color2 = dots[dots[length] - 1].color;
1892
1971
  var clrs = [];
1893
1972
  for (var i = 0, ii = dots[length]; i < ii; i++) {
1894
1973
  dots[i].offset && clrs[push](dots[i].offset + S + dots[i].color);
1895
1974
  }
1896
- fill.colors && (fill.colors.value = clrs[length] ? clrs[join](",") : "0% " + fill.color);
1975
+ fill.colors && (fill.colors.value = clrs[length] ? clrs[join]() : "0% " + fill.color);
1897
1976
  if (type == "radial") {
1977
+ fill.type = "gradientradial";
1898
1978
  fill.focus = "100%";
1899
1979
  fill.focussize = fxfy;
1900
1980
  fill.focusposition = fxfy;
1901
1981
  } else {
1982
+ fill.type = "gradient";
1902
1983
  fill.angle = (270 - angle) % 360;
1903
1984
  }
1904
1985
  }
1905
1986
  return 1;
1906
1987
  };
1907
- var Element = function (node, group, vml) {
1988
+ Element = function (node, group, vml) {
1908
1989
  var Rotation = 0,
1909
1990
  RotX = 0,
1910
1991
  RotY = 0,
@@ -1958,7 +2039,7 @@ window.Raphael = (function () {
1958
2039
  this.setBox(this.attrs, cx, cy);
1959
2040
  this.Group.style.rotation = this._.rt.deg;
1960
2041
  // gradient fix for rotation. TODO
1961
- // var fill = (this.shape || this.node).getElementsByTagName("fill");
2042
+ // var fill = (this.shape || this.node).getElementsByTagName(fillString);
1962
2043
  // fill = fill[0] || {};
1963
2044
  // var b = ((360 - this._.rt.deg) - 270) % 360;
1964
2045
  // !R.is(fill.angle, "undefined") && (fill.angle = b);
@@ -1993,7 +2074,6 @@ window.Raphael = (function () {
1993
2074
  w = attr.rx * 2;
1994
2075
  h = attr.ry * 2;
1995
2076
  break;
1996
- case "rect":
1997
2077
  case "image":
1998
2078
  x = +attr.x;
1999
2079
  y = +attr.y;
@@ -2007,6 +2087,7 @@ window.Raphael = (function () {
2007
2087
  w = this.W;
2008
2088
  h = this.H;
2009
2089
  break;
2090
+ case "rect":
2010
2091
  case "path":
2011
2092
  if (!this.attrs.path) {
2012
2093
  x = 0;
@@ -2031,51 +2112,26 @@ window.Raphael = (function () {
2031
2112
  cx = (cx == null) ? x + w / 2 : cx;
2032
2113
  cy = (cy == null) ? y + h / 2 : cy;
2033
2114
  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");
2115
+ top = cy - this.paper.height / 2, t;
2116
+ gs.left != (t = left + "px") && (gs.left = t);
2117
+ gs.top != (t = top + "px") && (gs.top = t);
2118
+ this.X = pathlike[has](this.type) ? -left : x;
2119
+ this.Y = pathlike[has](this.type) ? -top : y;
2120
+ this.W = w;
2121
+ this.H = h;
2122
+ if (pathlike[has](this.type)) {
2123
+ os.left != (t = -left * zoom + "px") && (os.left = t);
2124
+ os.top != (t = -top * zoom + "px") && (os.top = t);
2125
+ } else if (this.type == "text") {
2126
+ os.left != (t = -left + "px") && (os.left = t);
2127
+ os.top != (t = -top + "px") && (os.top = t);
2044
2128
  } 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 one
2060
- 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
- }
2129
+ gs.width != (t = this.paper.width + "px") && (gs.width = t);
2130
+ gs.height != (t = this.paper.height + "px") && (gs.height = t);
2131
+ os.left != (t = x - left + "px") && (os.left = t);
2132
+ os.top != (t = y - top + "px") && (os.top = t);
2133
+ os.width != (t = w + "px") && (os.width = t);
2134
+ os.height != (t = h + "px") && (os.height = t);
2079
2135
  }
2080
2136
  };
2081
2137
  Element[proto].hide = function () {
@@ -2090,7 +2146,7 @@ window.Raphael = (function () {
2090
2146
  if (this.removed) {
2091
2147
  return this;
2092
2148
  }
2093
- if (this.type == "path") {
2149
+ if (pathlike[has](this.type)) {
2094
2150
  return pathDimensions(this.attrs.path);
2095
2151
  }
2096
2152
  return {
@@ -2113,11 +2169,11 @@ window.Raphael = (function () {
2113
2169
  }
2114
2170
  this.removed = true;
2115
2171
  };
2116
- Element[proto].attr = function () {
2172
+ Element[proto].attr = function (name, value) {
2117
2173
  if (this.removed) {
2118
2174
  return this;
2119
2175
  }
2120
- if (arguments[length] == 0) {
2176
+ if (name == null) {
2121
2177
  var res = {};
2122
2178
  for (var i in this.attrs) if (this.attrs[has](i)) {
2123
2179
  res[i] = this.attrs[i];
@@ -2127,34 +2183,34 @@ window.Raphael = (function () {
2127
2183
  res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient;
2128
2184
  return res;
2129
2185
  }
2130
- if (arguments[length] == 1 && R.is(arguments[0], "string")) {
2131
- if (arguments[0] == "translation") {
2186
+ if (value == null && R.is(name, string)) {
2187
+ if (name == "translation") {
2132
2188
  return translate.call(this);
2133
2189
  }
2134
- if (arguments[0] == "rotation") {
2190
+ if (name == "rotation") {
2135
2191
  return this.rotate();
2136
2192
  }
2137
- if (arguments[0] == "scale") {
2193
+ if (name == "scale") {
2138
2194
  return this.scale();
2139
2195
  }
2140
- if (arguments[0] == "fill" && this.attrs.fill == "none" && this.attrs.gradient) {
2196
+ if (name == fillString && this.attrs.fill == "none" && this.attrs.gradient) {
2141
2197
  return this.attrs.gradient;
2142
2198
  }
2143
- return this.attrs[arguments[0]];
2199
+ return this.attrs[name];
2144
2200
  }
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
- };
2201
+ if (this.attrs && value == null && R.is(name, array)) {
2202
+ var ii, values = {};
2203
+ for (i = 0, ii = name[length]; i < ii; i++) {
2204
+ values[name[i]] = this.attr(name[i]);
2205
+ }
2150
2206
  return values;
2151
2207
  }
2152
2208
  var params;
2153
- if (arguments[length] == 2) {
2209
+ if (value != null) {
2154
2210
  params = {};
2155
- params[arguments[0]] = arguments[1];
2211
+ params[name] = value;
2156
2212
  }
2157
- arguments[length] == 1 && R.is(arguments[0], "object") && (params = arguments[0]);
2213
+ value == null && R.is(name, "object") && (params = name);
2158
2214
  if (params) {
2159
2215
  if (params.text && this.type == "text") {
2160
2216
  this.node.string = params.text;
@@ -2163,7 +2219,7 @@ window.Raphael = (function () {
2163
2219
  if (params.gradient && (({circle: 1, ellipse: 1})[has](this.type) || (params.gradient + E).charAt() != "r")) {
2164
2220
  addGradientFill(this, params.gradient);
2165
2221
  }
2166
- (this.type != "path" || this._.rt.deg) && this.setBox(this.attrs);
2222
+ (!pathlike[has](this.type) || this._.rt.deg) && this.setBox(this.attrs);
2167
2223
  }
2168
2224
  return this;
2169
2225
  };
@@ -2202,13 +2258,28 @@ window.Raphael = (function () {
2202
2258
  insertbefore(this, element, this.paper);
2203
2259
  return this;
2204
2260
  };
2261
+ var blurregexp = / progid:\S+Blur\([^\)]+\)/g;
2262
+ Element[proto].blur = function (size) {
2263
+ var s = this.node.style,
2264
+ f = s.filter;
2265
+ f = f.replace(blurregexp, "");
2266
+ if (+size !== 0) {
2267
+ this.attrs.blur = size;
2268
+ s.filter = f + ms + ".Blur(pixelradius=" + (+size || 1.5) + ")";
2269
+ s.margin = Raphael.format("-{0}px 0 0 -{0}px", Math.round(+size || 1.5));
2270
+ } else {
2271
+ s.filter = f;
2272
+ s.margin = 0;
2273
+ delete this.attrs.blur;
2274
+ }
2275
+ };
2205
2276
 
2206
- var theCircle = function (vml, x, y, r) {
2277
+ theCircle = function (vml, x, y, r) {
2207
2278
  var g = createNode("group"),
2208
2279
  o = createNode("oval"),
2209
2280
  ol = o.style;
2210
2281
  g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";
2211
- g.coordsize = vml.coordsize;
2282
+ g.coordsize = coordsize;
2212
2283
  g.coordorigin = vml.coordorigin;
2213
2284
  g[appendChild](o);
2214
2285
  var res = new Element(o, g, vml);
@@ -2220,30 +2291,33 @@ window.Raphael = (function () {
2220
2291
  res.setBox({x: x - r, y: y - r, width: r * 2, height: r * 2});
2221
2292
  vml.canvas[appendChild](g);
2222
2293
  return res;
2223
- },
2294
+ };
2295
+ function rectPath(x, y, w, h, r) {
2296
+ if (r) {
2297
+ return R.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z", x + r, y, w - r * 2, r, -r, h - r * 2, r * 2 - w, r * 2 - h);
2298
+ } else {
2299
+ return R.format("M{0},{1}l{2},0,0,{3},{4},0z", x, y, w, h, -w);
2300
+ }
2301
+ }
2224
2302
  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);
2303
+ var path = rectPath(x, y, w, h, r),
2304
+ res = vml.path(path),
2305
+ a = res.attrs;
2306
+ res.X = a.x = x;
2307
+ res.Y = a.y = y;
2308
+ res.W = a.width = w;
2309
+ res.H = a.height = h;
2310
+ a.r = r;
2311
+ a.path = path;
2234
2312
  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
2313
  return res;
2240
- },
2314
+ };
2241
2315
  theEllipse = function (vml, x, y, rx, ry) {
2242
2316
  var g = createNode("group"),
2243
2317
  o = createNode("oval"),
2244
2318
  ol = o.style;
2245
2319
  g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";
2246
- g.coordsize = vml.coordsize;
2320
+ g.coordsize = coordsize;
2247
2321
  g.coordorigin = vml.coordorigin;
2248
2322
  g[appendChild](o);
2249
2323
  var res = new Element(o, g, vml);
@@ -2256,13 +2330,13 @@ window.Raphael = (function () {
2256
2330
  res.setBox({x: x - rx, y: y - ry, width: rx * 2, height: ry * 2});
2257
2331
  vml.canvas[appendChild](g);
2258
2332
  return res;
2259
- },
2333
+ };
2260
2334
  theImage = function (vml, src, x, y, w, h) {
2261
2335
  var g = createNode("group"),
2262
2336
  o = createNode("image"),
2263
2337
  ol = o.style;
2264
2338
  g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";
2265
- g.coordsize = vml.coordsize;
2339
+ g.coordsize = coordsize;
2266
2340
  g.coordorigin = vml.coordorigin;
2267
2341
  o.src = src;
2268
2342
  g[appendChild](o);
@@ -2276,7 +2350,7 @@ window.Raphael = (function () {
2276
2350
  res.setBox({x: x, y: y, width: w, height: h});
2277
2351
  vml.canvas[appendChild](g);
2278
2352
  return res;
2279
- },
2353
+ };
2280
2354
  theText = function (vml, x, y, text) {
2281
2355
  var g = createNode("group"),
2282
2356
  el = createNode("shape"),
@@ -2285,9 +2359,9 @@ window.Raphael = (function () {
2285
2359
  ps = path.style,
2286
2360
  o = createNode("textpath");
2287
2361
  g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";
2288
- g.coordsize = vml.coordsize;
2362
+ g.coordsize = coordsize;
2289
2363
  g.coordorigin = vml.coordorigin;
2290
- path.v = R.format("m{0},{1}l{2},{1}", round(x), round(y), round(x) + 1);
2364
+ path.v = R.format("m{0},{1}l{2},{1}", round(x * 10), round(y * 10), round(x * 10) + 1);
2291
2365
  path.textpathok = true;
2292
2366
  ol.width = vml.width;
2293
2367
  ol.height = vml.height;
@@ -2309,7 +2383,7 @@ window.Raphael = (function () {
2309
2383
  res.setBox();
2310
2384
  vml.canvas[appendChild](g);
2311
2385
  return res;
2312
- },
2386
+ };
2313
2387
  setSize = function (width, height) {
2314
2388
  var cs = this.canvas.style;
2315
2389
  width == +width && (width += "px");
@@ -2318,8 +2392,8 @@ window.Raphael = (function () {
2318
2392
  cs.height = height;
2319
2393
  cs.clip = "rect(0 " + width + " " + height + " 0)";
2320
2394
  return this;
2321
- },
2322
- createNode;
2395
+ };
2396
+ var createNode;
2323
2397
  doc.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)");
2324
2398
  try {
2325
2399
  !doc.namespaces.rvml && doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");
@@ -2331,8 +2405,8 @@ window.Raphael = (function () {
2331
2405
  return doc.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
2332
2406
  };
2333
2407
  }
2334
- var create = function () {
2335
- var con = getContainer[apply](null, arguments),
2408
+ create = function () {
2409
+ var con = getContainer[apply](0, arguments),
2336
2410
  container = con.container,
2337
2411
  height = con.height,
2338
2412
  s,
@@ -2345,25 +2419,26 @@ window.Raphael = (function () {
2345
2419
  var res = new Paper,
2346
2420
  c = res.canvas = doc.createElement("div"),
2347
2421
  cs = c.style;
2422
+ x = x || 0;
2423
+ y = y || 0;
2348
2424
  width = width || 512;
2349
2425
  height = height || 342;
2350
2426
  width == +width && (width += "px");
2351
2427
  height == +height && (height += "px");
2352
2428
  res.width = 1e3;
2353
2429
  res.height = 1e3;
2354
- res.coordsize = "1000 1000";
2430
+ res.coordsize = zoom * 1e3 + S + zoom * 1e3;
2355
2431
  res.coordorigin = "0 0";
2356
2432
  res.span = doc.createElement("span");
2357
2433
  res.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";
2358
2434
  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);
2435
+ cs.cssText = R.format("width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden", width, height);
2360
2436
  if (container == 1) {
2361
2437
  doc.body[appendChild](c);
2362
2438
  cs.left = x + "px";
2363
2439
  cs.top = y + "px";
2440
+ cs.position = "absolute";
2364
2441
  } else {
2365
- container.style.width = width;
2366
- container.style.height = height;
2367
2442
  if (container.firstChild) {
2368
2443
  container.insertBefore(c, container.firstChild);
2369
2444
  } else {
@@ -2385,37 +2460,66 @@ window.Raphael = (function () {
2385
2460
  for (var i in this) {
2386
2461
  this[i] = removed(i);
2387
2462
  }
2463
+ return true;
2388
2464
  };
2389
2465
  }
2390
2466
 
2391
2467
  // rest
2392
2468
  // Safari or Chrome (WebKit) rendering bug workaround method
2393
- if ((/^Apple|^Google/).test(navigator.vendor) && !(navigator.userAgent.indexOf("Version/4.0") + 1)) {
2469
+ if ((/^Apple|^Google/).test(win.navigator.vendor) && (!(win.navigator.userAgent.indexOf("Version/4.0") + 1) || win.navigator.platform.slice(0, 2) == "iP")) {
2394
2470
  Paper[proto].safari = function () {
2395
2471
  var rect = this.rect(-99, -99, this.width + 99, this.height + 99);
2396
- setTimeout(function () {rect.remove();});
2472
+ win.setTimeout(function () {rect.remove();});
2397
2473
  };
2398
2474
  } else {
2399
2475
  Paper[proto].safari = function () {};
2400
2476
  }
2401
2477
 
2402
2478
  // Events
2403
- var addEvent = (function () {
2479
+ var preventDefault = function () {
2480
+ this.returnValue = false;
2481
+ },
2482
+ preventTouch = function () {
2483
+ return this.originalEvent.preventDefault();
2484
+ },
2485
+ stopPropagation = function () {
2486
+ this.cancelBubble = true;
2487
+ },
2488
+ stopTouch = function () {
2489
+ return this.originalEvent.stopPropagation();
2490
+ },
2491
+ addEvent = (function () {
2404
2492
  if (doc.addEventListener) {
2405
2493
  return function (obj, type, fn, element) {
2494
+ var realName = supportsTouch && touchMap[type] ? touchMap[type] : type;
2406
2495
  var f = function (e) {
2496
+ if (supportsTouch && touchMap[has](type)) {
2497
+ for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) {
2498
+ if (e.targetTouches[i].target == obj) {
2499
+ var olde = e;
2500
+ e = e.targetTouches[i];
2501
+ e.originalEvent = olde;
2502
+ e.preventDefault = preventTouch;
2503
+ e.stopPropagation = stopTouch;
2504
+ break;
2505
+ }
2506
+ }
2507
+ }
2407
2508
  return fn.call(element, e);
2408
2509
  };
2409
- obj.addEventListener(type, f, false);
2510
+ obj.addEventListener(realName, f, false);
2410
2511
  return function () {
2411
- obj.removeEventListener(type, f, false);
2512
+ obj.removeEventListener(realName, f, false);
2412
2513
  return true;
2413
2514
  };
2414
2515
  };
2415
2516
  } else if (doc.attachEvent) {
2416
2517
  return function (obj, type, fn, element) {
2417
2518
  var f = function (e) {
2418
- return fn.call(element, e || win.event);
2519
+ e = e || win.event;
2520
+ e.preventDefault = e.preventDefault || preventDefault;
2521
+ e.stopPropagation = e.stopPropagation || stopPropagation;
2522
+ return fn.call(element, e);
2419
2523
  };
2420
2524
  obj.attachEvent("on" + type, f);
2421
2525
  var detacher = function () {
@@ -2428,14 +2532,14 @@ window.Raphael = (function () {
2428
2532
  })();
2429
2533
  for (var i = events[length]; i--;) {
2430
2534
  (function (eventName) {
2431
- Element[proto][eventName] = function (fn) {
2535
+ R[eventName] = Element[proto][eventName] = function (fn) {
2432
2536
  if (R.is(fn, "function")) {
2433
2537
  this.events = this.events || [];
2434
- this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node, eventName, fn, this)});
2538
+ this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node || doc, eventName, fn, this)});
2435
2539
  }
2436
2540
  return this;
2437
2541
  };
2438
- Element[proto]["un" + eventName] = function (fn) {
2542
+ R["un" + eventName] = Element[proto]["un" + eventName] = function (fn) {
2439
2543
  var events = this.events,
2440
2544
  l = events[length];
2441
2545
  while (l--) if (events[l].name == eventName && events[l].f == fn) {
@@ -2454,6 +2558,43 @@ window.Raphael = (function () {
2454
2558
  Element[proto].unhover = function (f_in, f_out) {
2455
2559
  return this.unmouseover(f_in).unmouseout(f_out);
2456
2560
  };
2561
+ Element[proto].drag = function (onmove, onstart, onend) {
2562
+ this._drag = {};
2563
+ var el = this.mousedown(function (e) {
2564
+ (e.originalEvent ? e.originalEvent : e).preventDefault();
2565
+ this._drag.x = e.clientX;
2566
+ this._drag.y = e.clientY;
2567
+ this._drag.id = e.identifier;
2568
+ onstart && onstart.call(this, e.clientX, e.clientY);
2569
+ Raphael.mousemove(move).mouseup(up);
2570
+ }),
2571
+ move = function (e) {
2572
+ var x = e.clientX,
2573
+ y = e.clientY;
2574
+ if (supportsTouch) {
2575
+ var i = e.touches.length,
2576
+ touch;
2577
+ while (i--) {
2578
+ touch = e.touches[i];
2579
+ if (touch.identifier == el._drag.id) {
2580
+ x = touch.clientX;
2581
+ y = touch.clientY;
2582
+ (e.originalEvent ? e.originalEvent : e).preventDefault();
2583
+ break;
2584
+ }
2585
+ }
2586
+ } else {
2587
+ e.preventDefault();
2588
+ }
2589
+ onmove && onmove.call(el, x - el._drag.x, y - el._drag.y, x, y);
2590
+ },
2591
+ up = function () {
2592
+ el._drag = {};
2593
+ Raphael.unmousemove(move).unmouseup(up);
2594
+ onend && onend.call(el);
2595
+ };
2596
+ return this;
2597
+ };
2457
2598
  Paper[proto].circle = function (x, y, r) {
2458
2599
  return theCircle(this, x || 0, y || 0, r || 0);
2459
2600
  };
@@ -2464,7 +2605,7 @@ window.Raphael = (function () {
2464
2605
  return theEllipse(this, x || 0, y || 0, rx || 0, ry || 0);
2465
2606
  };
2466
2607
  Paper[proto].path = function (pathString) {
2467
- pathString && !R.is(pathString, "string") && !R.is(pathString[0], "array") && (pathString += E);
2608
+ pathString && !R.is(pathString, string) && !R.is(pathString[0], array) && (pathString += E);
2468
2609
  return thePath(R.format[apply](R, arguments), this);
2469
2610
  };
2470
2611
  Paper[proto].image = function (src, x, y, w, h) {
@@ -2482,8 +2623,19 @@ window.Raphael = (function () {
2482
2623
  Paper[proto].raphael = R;
2483
2624
  function x_y() {
2484
2625
  return this.x + S + this.y;
2626
+ }
2627
+ Element[proto].resetScale = function () {
2628
+ if (this.removed) {
2629
+ return this;
2630
+ }
2631
+ this._.sx = 1;
2632
+ this._.sy = 1;
2633
+ this.attrs.scale = "1 1";
2485
2634
  };
2486
2635
  Element[proto].scale = function (x, y, cx, cy) {
2636
+ if (this.removed) {
2637
+ return this;
2638
+ }
2487
2639
  if (x == null && y == null) {
2488
2640
  return {
2489
2641
  x: this._.sx,
@@ -2534,12 +2686,17 @@ window.Raphael = (function () {
2534
2686
  cy: ncy
2535
2687
  });
2536
2688
  break;
2689
+ case "text":
2690
+ this.attr({
2691
+ x: ncx,
2692
+ y: ncy
2693
+ });
2694
+ break;
2537
2695
  case "path":
2538
2696
  var path = pathToRelative(a.path),
2539
2697
  skip = true;
2540
2698
  for (var i = 0, ii = path[length]; i < ii; i++) {
2541
2699
  var p = path[i],
2542
- j,
2543
2700
  P0 = upperCase.call(p[0]);
2544
2701
  if (P0 == "M" && skip) {
2545
2702
  continue;
@@ -2551,9 +2708,9 @@ window.Raphael = (function () {
2551
2708
  p[path[i][length] - 1] *= ky;
2552
2709
  p[1] *= dirx * kx;
2553
2710
  p[2] *= diry * ky;
2554
- p[5] = +(dirx + diry ? !!+p[5] : !+p[5]);
2711
+ p[5] = +!(dirx + diry ? !+p[5] : +p[5]);
2555
2712
  } else if (P0 == "H") {
2556
- for (j = 1, jj = p[length]; j < jj; j++) {
2713
+ for (var j = 1, jj = p[length]; j < jj; j++) {
2557
2714
  p[j] *= kx;
2558
2715
  }
2559
2716
  } else if (P0 == "V") {
@@ -2566,9 +2723,9 @@ window.Raphael = (function () {
2566
2723
  }
2567
2724
  }
2568
2725
  }
2569
- var dim2 = pathDimensions(path),
2570
- dx = ncx - dim2.x - dim2.width / 2,
2571
- dy = ncy - dim2.y - dim2.height / 2;
2726
+ var dim2 = pathDimensions(path);
2727
+ dx = ncx - dim2.x - dim2.width / 2;
2728
+ dy = ncy - dim2.y - dim2.height / 2;
2572
2729
  path[0][1] += dx;
2573
2730
  path[0][2] += dy;
2574
2731
  this.attr({path: path});
@@ -2584,7 +2741,7 @@ window.Raphael = (function () {
2584
2741
  a.fx = dirx - 1;
2585
2742
  a.fy = diry - 1;
2586
2743
  } else {
2587
- this.node.filterMatrix = " progid:DXImageTransform.Microsoft.Matrix(M11="[concat](dirx,
2744
+ this.node.filterMatrix = ms + ".Matrix(M11="[concat](dirx,
2588
2745
  ", M12=0, M21=0, M22=", diry,
2589
2746
  ", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");
2590
2747
  s.filter = (this.node.filterMatrix || E) + (this.node.filterOpacity || E);
@@ -2607,12 +2764,27 @@ window.Raphael = (function () {
2607
2764
  return this;
2608
2765
  };
2609
2766
  Element[proto].clone = function () {
2767
+ if (this.removed) {
2768
+ return null;
2769
+ }
2610
2770
  var attr = this.attr();
2611
2771
  delete attr.scale;
2612
2772
  delete attr.translation;
2613
2773
  return this.paper[this.type]().attr(attr);
2614
2774
  };
2615
- var getLengthFactory = function (istotal, subpath) {
2775
+ var getPointAtSegmentLength = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) {
2776
+ var len = 0,
2777
+ old;
2778
+ for (var i = 0; i < 1.001; i+=.001) {
2779
+ var dot = R.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, i);
2780
+ i && (len += pow(pow(old.x - dot.x, 2) + pow(old.y - dot.y, 2), .5));
2781
+ if (len >= length) {
2782
+ return dot;
2783
+ }
2784
+ old = dot;
2785
+ }
2786
+ }),
2787
+ getLengthFactory = function (istotal, subpath) {
2616
2788
  return function (path, length, onlystart) {
2617
2789
  path = path2curve(path);
2618
2790
  var x, y, p, l, sp = "", subpaths = {}, point,
@@ -2626,20 +2798,18 @@ window.Raphael = (function () {
2626
2798
  l = segmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
2627
2799
  if (len + l > length) {
2628
2800
  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);
2801
+ point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);
2630
2802
  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
- }
2803
+ if (onlystart) {return sp;}
2634
2804
  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]();
2805
+ 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
2806
  len += l;
2637
2807
  x = +p[5];
2638
2808
  y = +p[6];
2639
2809
  continue;
2640
2810
  }
2641
2811
  if (!istotal && !subpath) {
2642
- point = R.findDotsAtSegment(x, y, p[1], p[2], p[3], p[4], p[5], p[6], (length - len) / l);
2812
+ point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);
2643
2813
  return {x: point.x, y: point.y, alpha: point.alpha};
2644
2814
  }
2645
2815
  }
@@ -2660,7 +2830,7 @@ window.Raphael = (function () {
2660
2830
  len = 0;
2661
2831
  for (var i = 0; i < 1.01; i+=.01) {
2662
2832
  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)));
2833
+ i && (len += pow(pow(old.x - dot.x, 2) + pow(old.y - dot.y, 2), .5));
2664
2834
  old = dot;
2665
2835
  }
2666
2836
  return len;
@@ -2669,15 +2839,21 @@ window.Raphael = (function () {
2669
2839
  getPointAtLength = getLengthFactory(),
2670
2840
  getSubpathsAtLength = getLengthFactory(0, 1);
2671
2841
  Element[proto].getTotalLength = function () {
2672
- if (this.type != "path") return;
2842
+ if (this.type != "path") {return;}
2843
+ if (this.node.getTotalLength) {
2844
+ return this.node.getTotalLength();
2845
+ }
2673
2846
  return getTotalLength(this.attrs.path);
2674
2847
  };
2675
2848
  Element[proto].getPointAtLength = function (length) {
2676
- if (this.type != "path") return;
2849
+ if (this.type != "path") {return;}
2677
2850
  return getPointAtLength(this.attrs.path, length);
2678
2851
  };
2679
2852
  Element[proto].getSubpath = function (from, to) {
2680
- if (this.type != "path") return;
2853
+ if (this.type != "path") {return;}
2854
+ if (math.abs(this.getTotalLength() - to) < 1e-6) {
2855
+ return getSubpathsAtLength(this.attrs.path, from).end;
2856
+ }
2681
2857
  var a = getSubpathsAtLength(this.attrs.path, to, 1);
2682
2858
  return from ? getSubpathsAtLength(a, from).end : a;
2683
2859
  };
@@ -2741,13 +2917,13 @@ window.Raphael = (function () {
2741
2917
  return l;
2742
2918
  }
2743
2919
  };
2744
-
2920
+
2745
2921
  var animationElements = {length : 0},
2746
2922
  animation = function () {
2747
2923
  var Now = +new Date;
2748
2924
  for (var l in animationElements) if (l != "length" && animationElements[has](l)) {
2749
2925
  var e = animationElements[l];
2750
- if (e.stop) {
2926
+ if (e.stop || e.el.removed) {
2751
2927
  delete animationElements[l];
2752
2928
  animationElements[length]--;
2753
2929
  continue;
@@ -2778,7 +2954,7 @@ window.Raphael = (function () {
2778
2954
  that.translate(point.x - diff.sx, point.y - diff.sy);
2779
2955
  to.rot && that.rotate(diff.r + point.alpha, point.x, point.y);
2780
2956
  break;
2781
- case "number":
2957
+ case nu:
2782
2958
  now = +from[attr] + pos * ms * diff[attr];
2783
2959
  break;
2784
2960
  case "colour":
@@ -2817,7 +2993,7 @@ window.Raphael = (function () {
2817
2993
  break;
2818
2994
  case "clip-rect":
2819
2995
  now = [];
2820
- var i = 4;
2996
+ i = 4;
2821
2997
  while (i--) {
2822
2998
  now[i] = +from[attr][i] + pos * ms * diff[attr][i];
2823
2999
  }
@@ -2831,12 +3007,12 @@ window.Raphael = (function () {
2831
3007
  that._run && that._run.call(that);
2832
3008
  } else {
2833
3009
  if (to.along) {
2834
- var point = getPointAtLength(to.along, to.len * !to.back);
3010
+ point = getPointAtLength(to.along, to.len * !to.back);
2835
3011
  that.translate(diff.sx - (diff.x || 0) + point.x - diff.sx, diff.sy - (diff.y || 0) + point.y - diff.sy);
2836
3012
  to.rot && that.rotate(diff.r + point.alpha, point.x, point.y);
2837
3013
  }
2838
3014
  (t.x || t.y) && that.translate(-t.x, -t.y);
2839
- to.scale && (to.scale = to.scale + E);
3015
+ to.scale && (to.scale += E);
2840
3016
  that.attr(to);
2841
3017
  delete animationElements[l];
2842
3018
  animationElements[length]--;
@@ -2845,11 +3021,11 @@ window.Raphael = (function () {
2845
3021
  }
2846
3022
  e.prev = time;
2847
3023
  }
2848
- R.svg && that && that.paper.safari();
2849
- animationElements[length] && setTimeout(animation);
3024
+ R.svg && that && that.paper && that.paper.safari();
3025
+ animationElements[length] && win.setTimeout(animation);
2850
3026
  },
2851
3027
  upto255 = function (color) {
2852
- return color > 255 ? 255 : (color < 0 ? 0 : color);
3028
+ return mmax(mmin(color, 255), 0);
2853
3029
  },
2854
3030
  translate = function (x, y) {
2855
3031
  if (x == null) {
@@ -2922,7 +3098,7 @@ window.Raphael = (function () {
2922
3098
  to.len = len;
2923
3099
  params.rot && (diff.r = toFloat(this.rotate()) || 0);
2924
3100
  break;
2925
- case "number":
3101
+ case nu:
2926
3102
  diff[attr] = (to[attr] - from[attr]) / ms;
2927
3103
  break;
2928
3104
  case "colour":
@@ -2966,7 +3142,7 @@ window.Raphael = (function () {
2966
3142
  case "clip-rect":
2967
3143
  from[attr] = (from[attr] + E)[split](separator);
2968
3144
  diff[attr] = [];
2969
- var i = 4;
3145
+ i = 4;
2970
3146
  while (i--) {
2971
3147
  diff[attr][i] = (values[i] - from[attr][i]) / ms;
2972
3148
  }
@@ -3009,6 +3185,7 @@ window.Raphael = (function () {
3009
3185
  var Set = function (items) {
3010
3186
  this.items = [];
3011
3187
  this[length] = 0;
3188
+ this.type = "set";
3012
3189
  if (items) {
3013
3190
  for (var i = 0, ii = items[length]; i < ii; i++) {
3014
3191
  if (items[i] && (items[i].constructor == Element || items[i].constructor == Set)) {
@@ -3046,13 +3223,13 @@ window.Raphael = (function () {
3046
3223
  })(method);
3047
3224
  }
3048
3225
  Set[proto].attr = function (name, value) {
3049
- if (name && R.is(name, "array") && R.is(name[0], "object")) {
3226
+ if (name && R.is(name, array) && R.is(name[0], "object")) {
3050
3227
  for (var j = 0, jj = name[length]; j < jj; j++) {
3051
3228
  this.items[j].attr(name[j]);
3052
3229
  }
3053
3230
  } else {
3054
3231
  for (var i = 0, ii = this.items[length]; i < ii; i++) {
3055
- this.items[i].attr[apply](this.items[i], arguments);
3232
+ this.items[i].attr(name, value);
3056
3233
  }
3057
3234
  }
3058
3235
  return this;
@@ -3061,14 +3238,16 @@ window.Raphael = (function () {
3061
3238
  (R.is(easing, "function") || !easing) && (callback = easing || null);
3062
3239
  var len = this.items[length],
3063
3240
  i = len,
3241
+ item,
3064
3242
  set = this,
3065
3243
  collector;
3066
3244
  callback && (collector = function () {
3067
3245
  !--len && callback.call(set);
3068
3246
  });
3069
- this.items[--i].animate(params, ms, easing || collector, collector);
3247
+ easing = R.is(easing, string) ? easing : collector;
3248
+ item = this.items[--i].animate(params, ms, easing, collector);
3070
3249
  while (i--) {
3071
- this.items[i].animateWith(this.items[len - 1], params, ms, easing || collector, collector);
3250
+ this.items[i].animateWith(item, params, ms, easing, collector);
3072
3251
  }
3073
3252
  return this;
3074
3253
  };
@@ -3100,7 +3279,14 @@ window.Raphael = (function () {
3100
3279
  height: mmax[apply](0, h) - y
3101
3280
  };
3102
3281
  };
3103
-
3282
+ Set[proto].clone = function (s) {
3283
+ s = new Set;
3284
+ for (var i = 0, ii = this.items[length]; i < ii; i++) {
3285
+ s[push](this.items[i].clone());
3286
+ }
3287
+ return s;
3288
+ };
3289
+
3104
3290
  R.registerFont = function (font) {
3105
3291
  if (!font.face) {
3106
3292
  return font;
@@ -3144,6 +3330,9 @@ window.Raphael = (function () {
3144
3330
  stretch = stretch || "normal";
3145
3331
  style = style || "normal";
3146
3332
  weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400;
3333
+ if (!R.fonts) {
3334
+ return;
3335
+ }
3147
3336
  var font = R.fonts[family];
3148
3337
  if (!font) {
3149
3338
  var name = new RegExp("(^|\\s)" + family[rp](/[^\w\d\s+!~.:_-]/g, E) + "(\\s|$)", "i");
@@ -3172,7 +3361,7 @@ window.Raphael = (function () {
3172
3361
  shift = 0,
3173
3362
  path = E,
3174
3363
  scale;
3175
- R.is(font, "string") && (font = this.getFont(font));
3364
+ R.is(font, string) && (font = this.getFont(font));
3176
3365
  if (font) {
3177
3366
  scale = (size || 16) / font.face["units-per-em"];
3178
3367
  var bb = font.face.bbox.split(separator),
@@ -3188,28 +3377,19 @@ window.Raphael = (function () {
3188
3377
  }
3189
3378
  return out;
3190
3379
  };
3191
-
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) {
3380
+
3381
+ var formatrg = /\{(\d+)\}/g;
3382
+ R.format = function (token, params) {
3383
+ var args = R.is(params, array) ? [0][concat](params) : arguments;
3384
+ token && R.is(token, string) && args[length] - 1 && (token = token[rp](formatrg, function (str, i) {
3196
3385
  return args[++i] == null ? E : args[i];
3197
3386
  }));
3198
3387
  return token || E;
3199
3388
  };
3200
3389
  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;
3390
+ oldRaphael.was ? (Raphael = oldRaphael.is) : delete Raphael;
3391
+ return R;
3212
3392
  };
3213
3393
  R.el = Element[proto];
3214
3394
  return R;
3215
- })();
3395
+ })();