/*!
* Raphael 1.5.2 - JavaScript Vector Library
*
* Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
* Licensed under the MIT (http://raphaeljs.com/license.html) license.
*/
(function () {
function R() {
if (R.is(arguments[0], array)) {
var a = arguments[0],
cnv = create[apply](R, a.splice(0, 3 + R.is(a[0], nu))),
res = cnv.set();
for (var i = 0, ii = a[length]; i < ii; i++) {
var j = a[i] || {};
elements[has](j.type) && res[push](cnv[j.type]().attr(j));
}
return res;
}
return create[apply](R, arguments);
}
R.version = "1.5.2";
var separator = /[, ]+/,
elements = {circle: 1, rect: 1, path: 1, ellipse: 1, text: 1, image: 1},
formatrg = /\{(\d+)\}/g,
proto = "prototype",
has = "hasOwnProperty",
doc = document,
win = window,
oldRaphael = {
was: Object[proto][has].call(win, "Raphael"),
is: win.Raphael
},
Paper = function () {
this.customAttributes = {};
},
paperproto,
appendChild = "appendChild",
apply = "apply",
concat = "concat",
supportsTouch = "createTouch" in doc,
E = "",
S = " ",
Str = String,
split = "split",
events = "click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[split](S),
touchMap = {
mousedown: "touchstart",
mousemove: "touchmove",
mouseup: "touchend"
},
join = "join",
length = "length",
lowerCase = Str[proto].toLowerCase,
math = Math,
mmax = math.max,
mmin = math.min,
abs = math.abs,
pow = math.pow,
PI = math.PI,
nu = "number",
string = "string",
array = "array",
toString = "toString",
fillString = "fill",
objectToString = Object[proto][toString],
paper = {},
push = "push",
ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i,
colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,
isnan = {"NaN": 1, "Infinity": 1, "-Infinity": 1},
bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
round = math.round,
setAttribute = "setAttribute",
toFloat = parseFloat,
toInt = parseInt,
ms = " progid:DXImageTransform.Microsoft",
upperCase = Str[proto].toUpperCase,
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},
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},
rp = "replace",
animKeyFrames= /^(from|to|\d+%?)$/,
commaSpaces = /\s*,\s*/,
hsrg = {hs: 1, rg: 1},
p2s = /,?([achlmqrstvxz]),?/gi,
pathCommand = /([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,
pathValues = /(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,
radial_gradient = /^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,
sortByKey = function (a, b) {
return a.key - b.key;
};
R.type = (win.SVGAngle || doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML");
if (R.type == "VML") {
var d = doc.createElement("div"),
b;
d.innerHTML = '<v:shape adj="1"/>';
b = d.firstChild;
b.style.behavior = "url(#default#VML)";
if (!(b && typeof b.adj == "object")) {
return R.type = null;
}
d = null;
}
R.svg = !(R.vml = R.type == "VML");
Paper[proto] = R[proto];
paperproto = Paper[proto];
R._id = 0;
R._oid = 0;
R.fn = {};
R.is = function (o, type) {
type = lowerCase.call(type);
if (type == "finite") {
return !isnan[has](+o);
}
return (type == "null" && o === null) ||
(type == typeof o) ||
(type == "object" && o === Object(o)) ||
(type == "array" && Array.isArray && Array.isArray(o)) ||
objectToString.call(o).slice(8, -1).toLowerCase() == type;
};
R.angle = function (x1, y1, x2, y2, x3, y3) {
if (x3 == null) {
var x = x1 - x2,
y = y1 - y2;
if (!x && !y) {
return 0;
}
return ((x < 0) * 180 + math.atan(-y / -x) * 180 / PI + 360) % 360;
} else {
return R.angle(x1, y1, x3, y3) - R.angle(x2, y2, x3, y3);
}
};
R.rad = function (deg) {
return deg % 360 * PI / 180;
};
R.deg = function (rad) {
return rad * 180 / PI % 360;
};
R.snapTo = function (values, value, tolerance) {
tolerance = R.is(tolerance, "finite") ? tolerance : 10;
if (R.is(values, array)) {
var i = values.length;
while (i--) if (abs(values[i] - value) <= tolerance) {
return values[i];
}
} else {
values = +values;
var rem = value % values;
if (rem < tolerance) {
return value - rem;
}
if (rem > values - tolerance) {
return value - rem + values;
}
}
return value;
};
function createUUID() {
// http://www.ietf.org/rfc/rfc4122.txt
var s = [],
i = 0;
for (; i < 32; i++) {
s[i] = (~~(math.random() * 16))[toString](16);
}
s[12] = 4; // bits 12-15 of the time_hi_and_version field to 0010
s[16] = ((s[16] & 3) | 8)[toString](16); // bits 6-7 of the clock_seq_hi_and_reserved to 01
return "r-" + s[join]("");
}
R.setWindow = function (newwin) {
win = newwin;
doc = win.document;
};
// colour utilities
var toHex = function (color) {
if (R.vml) {
// http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/
var trim = /^\s+|\s+$/g;
var bod;
try {
var docum = new ActiveXObject("htmlfile");
docum.write("<body>");
docum.close();
bod = docum.body;
} catch(e) {
bod = createPopup().document.body;
}
var range = bod.createTextRange();
toHex = cacher(function (color) {
try {
bod.style.color = Str(color)[rp](trim, E);
var value = range.queryCommandValue("ForeColor");
value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16);
return "#" + ("000000" + value[toString](16)).s