PageRenderTime 118ms CodeModel.GetById 19ms app.highlight 76ms RepoModel.GetById 1ms app.codeStats 2ms

/public/js/lib/raphael.js

https://gitlab.com/webster5361/UserFrosting
JavaScript | 8111 lines | 5696 code | 93 blank | 2322 comment | 1780 complexity | c751a1cbe6ccf9aaa97e379046e21555 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1// ┌────────────────────────────────────────────────────────────────────┐ \\
   2// │ Raphaël 2.1.1 - JavaScript Vector Library                          │ \\
   3// ├────────────────────────────────────────────────────────────────────┤ \\
   4// │ Copyright © 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com)    │ \\
   5// │ Copyright © 2008-2012 Sencha Labs (http://sencha.com)              │ \\
   6// ├────────────────────────────────────────────────────────────────────┤ \\
   7// │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\
   8// └────────────────────────────────────────────────────────────────────┘ \\
   9// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
  10// 
  11// Licensed under the Apache License, Version 2.0 (the "License");
  12// you may not use this file except in compliance with the License.
  13// You may obtain a copy of the License at
  14// 
  15// http://www.apache.org/licenses/LICENSE-2.0
  16// 
  17// Unless required by applicable law or agreed to in writing, software
  18// distributed under the License is distributed on an "AS IS" BASIS,
  19// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20// See the License for the specific language governing permissions and
  21// limitations under the License.
  22// ┌────────────────────────────────────────────────────────────┐ \\
  23// │ Eve 0.4.2 - JavaScript Events Library                      │ \\
  24// ├────────────────────────────────────────────────────────────┤ \\
  25// │ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\
  26// └────────────────────────────────────────────────────────────┘ \\
  27
  28(function (glob) {
  29    var version = "0.4.2",
  30        has = "hasOwnProperty",
  31        separator = /[\.\/]/,
  32        wildcard = "*",
  33        fun = function () {},
  34        numsort = function (a, b) {
  35            return a - b;
  36        },
  37        current_event,
  38        stop,
  39        events = {n: {}},
  40    /*\
  41     * eve
  42     [ method ]
  43
  44     * Fires event with given `name`, given scope and other parameters.
  45
  46     > Arguments
  47
  48     - name (string) name of the *event*, dot (`.`) or slash (`/`) separated
  49     - scope (object) context for the event handlers
  50     - varargs (...) the rest of arguments will be sent to event handlers
  51
  52     = (object) array of returned values from the listeners
  53    \*/
  54        eve = function (name, scope) {
  55			name = String(name);
  56            var e = events,
  57                oldstop = stop,
  58                args = Array.prototype.slice.call(arguments, 2),
  59                listeners = eve.listeners(name),
  60                z = 0,
  61                f = false,
  62                l,
  63                indexed = [],
  64                queue = {},
  65                out = [],
  66                ce = current_event,
  67                errors = [];
  68            current_event = name;
  69            stop = 0;
  70            for (var i = 0, ii = listeners.length; i < ii; i++) if ("zIndex" in listeners[i]) {
  71                indexed.push(listeners[i].zIndex);
  72                if (listeners[i].zIndex < 0) {
  73                    queue[listeners[i].zIndex] = listeners[i];
  74                }
  75            }
  76            indexed.sort(numsort);
  77            while (indexed[z] < 0) {
  78                l = queue[indexed[z++]];
  79                out.push(l.apply(scope, args));
  80                if (stop) {
  81                    stop = oldstop;
  82                    return out;
  83                }
  84            }
  85            for (i = 0; i < ii; i++) {
  86                l = listeners[i];
  87                if ("zIndex" in l) {
  88                    if (l.zIndex == indexed[z]) {
  89                        out.push(l.apply(scope, args));
  90                        if (stop) {
  91                            break;
  92                        }
  93                        do {
  94                            z++;
  95                            l = queue[indexed[z]];
  96                            l && out.push(l.apply(scope, args));
  97                            if (stop) {
  98                                break;
  99                            }
 100                        } while (l)
 101                    } else {
 102                        queue[l.zIndex] = l;
 103                    }
 104                } else {
 105                    out.push(l.apply(scope, args));
 106                    if (stop) {
 107                        break;
 108                    }
 109                }
 110            }
 111            stop = oldstop;
 112            current_event = ce;
 113            return out.length ? out : null;
 114        };
 115		// Undocumented. Debug only.
 116		eve._events = events;
 117    /*\
 118     * eve.listeners
 119     [ method ]
 120
 121     * Internal method which gives you array of all event handlers that will be triggered by the given `name`.
 122
 123     > Arguments
 124
 125     - name (string) name of the event, dot (`.`) or slash (`/`) separated
 126
 127     = (array) array of event handlers
 128    \*/
 129    eve.listeners = function (name) {
 130        var names = name.split(separator),
 131            e = events,
 132            item,
 133            items,
 134            k,
 135            i,
 136            ii,
 137            j,
 138            jj,
 139            nes,
 140            es = [e],
 141            out = [];
 142        for (i = 0, ii = names.length; i < ii; i++) {
 143            nes = [];
 144            for (j = 0, jj = es.length; j < jj; j++) {
 145                e = es[j].n;
 146                items = [e[names[i]], e[wildcard]];
 147                k = 2;
 148                while (k--) {
 149                    item = items[k];
 150                    if (item) {
 151                        nes.push(item);
 152                        out = out.concat(item.f || []);
 153                    }
 154                }
 155            }
 156            es = nes;
 157        }
 158        return out;
 159    };
 160    
 161    /*\
 162     * eve.on
 163     [ method ]
 164     **
 165     * Binds given event handler with a given name. You can use wildcards “`*`” for the names:
 166     | eve.on("*.under.*", f);
 167     | eve("mouse.under.floor"); // triggers f
 168     * Use @eve to trigger the listener.
 169     **
 170     > Arguments
 171     **
 172     - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
 173     - f (function) event handler function
 174     **
 175     = (function) returned function accepts a single numeric parameter that represents z-index of the handler. It is an optional feature and only used when you need to ensure that some subset of handlers will be invoked in a given order, despite of the order of assignment. 
 176     > Example:
 177     | eve.on("mouse", eatIt)(2);
 178     | eve.on("mouse", scream);
 179     | eve.on("mouse", catchIt)(1);
 180     * This will ensure that `catchIt()` function will be called before `eatIt()`.
 181	 *
 182     * If you want to put your handler before non-indexed handlers, specify a negative value.
 183     * Note: I assume most of the time you don’t need to worry about z-index, but it’s nice to have this feature “just in case”.
 184    \*/
 185    eve.on = function (name, f) {
 186		name = String(name);
 187		if (typeof f != "function") {
 188			return function () {};
 189		}
 190        var names = name.split(separator),
 191            e = events;
 192        for (var i = 0, ii = names.length; i < ii; i++) {
 193            e = e.n;
 194            e = e.hasOwnProperty(names[i]) && e[names[i]] || (e[names[i]] = {n: {}});
 195        }
 196        e.f = e.f || [];
 197        for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) {
 198            return fun;
 199        }
 200        e.f.push(f);
 201        return function (zIndex) {
 202            if (+zIndex == +zIndex) {
 203                f.zIndex = +zIndex;
 204            }
 205        };
 206    };
 207    /*\
 208     * eve.f
 209     [ method ]
 210     **
 211     * Returns function that will fire given event with optional arguments.
 212	 * Arguments that will be passed to the result function will be also
 213	 * concated to the list of final arguments.
 214 	 | el.onclick = eve.f("click", 1, 2);
 215 	 | eve.on("click", function (a, b, c) {
 216 	 |     console.log(a, b, c); // 1, 2, [event object]
 217 	 | });
 218     > Arguments
 219	 - event (string) event name
 220	 - varargs (…) and any other arguments
 221	 = (function) possible event handler function
 222    \*/
 223	eve.f = function (event) {
 224		var attrs = [].slice.call(arguments, 1);
 225		return function () {
 226			eve.apply(null, [event, null].concat(attrs).concat([].slice.call(arguments, 0)));
 227		};
 228	};
 229    /*\
 230     * eve.stop
 231     [ method ]
 232     **
 233     * Is used inside an event handler to stop the event, preventing any subsequent listeners from firing.
 234    \*/
 235    eve.stop = function () {
 236        stop = 1;
 237    };
 238    /*\
 239     * eve.nt
 240     [ method ]
 241     **
 242     * Could be used inside event handler to figure out actual name of the event.
 243     **
 244     > Arguments
 245     **
 246     - subname (string) #optional subname of the event
 247     **
 248     = (string) name of the event, if `subname` is not specified
 249     * or
 250     = (boolean) `true`, if current event’s name contains `subname`
 251    \*/
 252    eve.nt = function (subname) {
 253        if (subname) {
 254            return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(current_event);
 255        }
 256        return current_event;
 257    };
 258    /*\
 259     * eve.nts
 260     [ method ]
 261     **
 262     * Could be used inside event handler to figure out actual name of the event.
 263     **
 264     **
 265     = (array) names of the event
 266    \*/
 267    eve.nts = function () {
 268        return current_event.split(separator);
 269    };
 270    /*\
 271     * eve.off
 272     [ method ]
 273     **
 274     * Removes given function from the list of event listeners assigned to given name.
 275	 * If no arguments specified all the events will be cleared.
 276     **
 277     > Arguments
 278     **
 279     - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
 280     - f (function) event handler function
 281    \*/
 282    /*\
 283     * eve.unbind
 284     [ method ]
 285     **
 286     * See @eve.off
 287    \*/
 288    eve.off = eve.unbind = function (name, f) {
 289		if (!name) {
 290		    eve._events = events = {n: {}};
 291			return;
 292		}
 293        var names = name.split(separator),
 294            e,
 295            key,
 296            splice,
 297            i, ii, j, jj,
 298            cur = [events];
 299        for (i = 0, ii = names.length; i < ii; i++) {
 300            for (j = 0; j < cur.length; j += splice.length - 2) {
 301                splice = [j, 1];
 302                e = cur[j].n;
 303                if (names[i] != wildcard) {
 304                    if (e[names[i]]) {
 305                        splice.push(e[names[i]]);
 306                    }
 307                } else {
 308                    for (key in e) if (e[has](key)) {
 309                        splice.push(e[key]);
 310                    }
 311                }
 312                cur.splice.apply(cur, splice);
 313            }
 314        }
 315        for (i = 0, ii = cur.length; i < ii; i++) {
 316            e = cur[i];
 317            while (e.n) {
 318                if (f) {
 319                    if (e.f) {
 320                        for (j = 0, jj = e.f.length; j < jj; j++) if (e.f[j] == f) {
 321                            e.f.splice(j, 1);
 322                            break;
 323                        }
 324                        !e.f.length && delete e.f;
 325                    }
 326                    for (key in e.n) if (e.n[has](key) && e.n[key].f) {
 327                        var funcs = e.n[key].f;
 328                        for (j = 0, jj = funcs.length; j < jj; j++) if (funcs[j] == f) {
 329                            funcs.splice(j, 1);
 330                            break;
 331                        }
 332                        !funcs.length && delete e.n[key].f;
 333                    }
 334                } else {
 335                    delete e.f;
 336                    for (key in e.n) if (e.n[has](key) && e.n[key].f) {
 337                        delete e.n[key].f;
 338                    }
 339                }
 340                e = e.n;
 341            }
 342        }
 343    };
 344    /*\
 345     * eve.once
 346     [ method ]
 347     **
 348     * Binds given event handler with a given name to only run once then unbind itself.
 349     | eve.once("login", f);
 350     | eve("login"); // triggers f
 351     | eve("login"); // no listeners
 352     * Use @eve to trigger the listener.
 353     **
 354     > Arguments
 355     **
 356     - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
 357     - f (function) event handler function
 358     **
 359     = (function) same return function as @eve.on
 360    \*/
 361    eve.once = function (name, f) {
 362        var f2 = function () {
 363            eve.unbind(name, f2);
 364            return f.apply(this, arguments);
 365        };
 366        return eve.on(name, f2);
 367    };
 368    /*\
 369     * eve.version
 370     [ property (string) ]
 371     **
 372     * Current version of the library.
 373    \*/
 374    eve.version = version;
 375    eve.toString = function () {
 376        return "You are running Eve " + version;
 377    };
 378    (typeof module != "undefined" && module.exports) ? (module.exports = eve) : (typeof define != "undefined" ? (define("eve", [], function() { return eve; })) : (glob.eve = eve));
 379})(this);
 380// ┌─────────────────────────────────────────────────────────────────────┐ \\
 381// │ "Raphaël 2.1.0" - JavaScript Vector Library                         │ \\
 382// ├─────────────────────────────────────────────────────────────────────┤ \\
 383// │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com)   │ \\
 384// │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com)             │ \\
 385// │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\
 386// └─────────────────────────────────────────────────────────────────────┘ \\
 387
 388(function (glob, factory) {
 389    // AMD support
 390    if (typeof define === "function" && define.amd) {
 391        // Define as an anonymous module
 392        define(["eve"], function( eve ) {
 393            return factory(glob, eve);
 394        });
 395    } else {
 396        // Browser globals (glob is window)
 397        // Raphael adds itself to window
 398        factory(glob, glob.eve);
 399    }
 400}(this, function (window, eve) {
 401    /*\
 402     * Raphael
 403     [ method ]
 404     **
 405     * Creates a canvas object on which to draw.
 406     * You must do this first, as all future calls to drawing methods
 407     * from this instance will be bound to this canvas.
 408     > Parameters
 409     **
 410     - container (HTMLElement|string) DOM element or its ID which is going to be a parent for drawing surface
 411     - width (number)
 412     - height (number)
 413     - callback (function) #optional callback function which is going to be executed in the context of newly created paper
 414     * or
 415     - x (number)
 416     - y (number)
 417     - width (number)
 418     - height (number)
 419     - callback (function) #optional callback function which is going to be executed in the context of newly created paper
 420     * or
 421     - all (array) (first 3 or 4 elements in the array are equal to [containerID, width, height] or [x, y, width, height]. The rest are element descriptions in format {type: type, <attributes>}). See @Paper.add.
 422     - callback (function) #optional callback function which is going to be executed in the context of newly created paper
 423     * or
 424     - onReadyCallback (function) function that is going to be called on DOM ready event. You can also subscribe to this event via Eve’s “DOMLoad” event. In this case method returns `undefined`.
 425     = (object) @Paper
 426     > Usage
 427     | // Each of the following examples create a canvas
 428     | // that is 320px wide by 200px high.
 429     | // Canvas is created at the viewport’s 10,50 coordinate.
 430     | var paper = Raphael(10, 50, 320, 200);
 431     | // Canvas is created at the top left corner of the #notepad element
 432     | // (or its top right corner in dir="rtl" elements)
 433     | var paper = Raphael(document.getElementById("notepad"), 320, 200);
 434     | // Same as above
 435     | var paper = Raphael("notepad", 320, 200);
 436     | // Image dump
 437     | var set = Raphael(["notepad", 320, 200, {
 438     |     type: "rect",
 439     |     x: 10,
 440     |     y: 10,
 441     |     width: 25,
 442     |     height: 25,
 443     |     stroke: "#f00"
 444     | }, {
 445     |     type: "text",
 446     |     x: 30,
 447     |     y: 40,
 448     |     text: "Dump"
 449     | }]);
 450    \*/
 451    function R(first) {
 452        if (R.is(first, "function")) {
 453            return loaded ? first() : eve.on("raphael.DOMload", first);
 454        } else if (R.is(first, array)) {
 455            return R._engine.create[apply](R, first.splice(0, 3 + R.is(first[0], nu))).add(first);
 456        } else {
 457            var args = Array.prototype.slice.call(arguments, 0);
 458            if (R.is(args[args.length - 1], "function")) {
 459                var f = args.pop();
 460                return loaded ? f.call(R._engine.create[apply](R, args)) : eve.on("raphael.DOMload", function () {
 461                    f.call(R._engine.create[apply](R, args));
 462                });
 463            } else {
 464                return R._engine.create[apply](R, arguments);
 465            }
 466        }
 467    }
 468    R.version = "2.1.0";
 469    R.eve = eve;
 470    var loaded,
 471        separator = /[, ]+/,
 472        elements = {circle: 1, rect: 1, path: 1, ellipse: 1, text: 1, image: 1},
 473        formatrg = /\{(\d+)\}/g,
 474        proto = "prototype",
 475        has = "hasOwnProperty",
 476        g = {
 477            doc: document,
 478            win: window
 479        },
 480        oldRaphael = {
 481            was: Object.prototype[has].call(g.win, "Raphael"),
 482            is: g.win.Raphael
 483        },
 484        Paper = function () {
 485            /*\
 486             * Paper.ca
 487             [ property (object) ]
 488             **
 489             * Shortcut for @Paper.customAttributes
 490            \*/
 491            /*\
 492             * Paper.customAttributes
 493             [ property (object) ]
 494             **
 495             * If you have a set of attributes that you would like to represent
 496             * as a function of some number you can do it easily with custom attributes:
 497             > Usage
 498             | paper.customAttributes.hue = function (num) {
 499             |     num = num % 1;
 500             |     return {fill: "hsb(" + num + ", 0.75, 1)"};
 501             | };
 502             | // Custom attribute “hue” will change fill
 503             | // to be given hue with fixed saturation and brightness.
 504             | // Now you can use it like this:
 505             | var c = paper.circle(10, 10, 10).attr({hue: .45});
 506             | // or even like this:
 507             | c.animate({hue: 1}, 1e3);
 508             | 
 509             | // You could also create custom attribute
 510             | // with multiple parameters:
 511             | paper.customAttributes.hsb = function (h, s, b) {
 512             |     return {fill: "hsb(" + [h, s, b].join(",") + ")"};
 513             | };
 514             | c.attr({hsb: "0.5 .8 1"});
 515             | c.animate({hsb: [1, 0, 0.5]}, 1e3);
 516            \*/
 517            this.ca = this.customAttributes = {};
 518        },
 519        paperproto,
 520        appendChild = "appendChild",
 521        apply = "apply",
 522        concat = "concat",
 523        supportsTouch = ('ontouchstart' in g.win) || g.win.DocumentTouch && g.doc instanceof DocumentTouch, //taken from Modernizr touch test
 524        E = "",
 525        S = " ",
 526        Str = String,
 527        split = "split",
 528        events = "click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel"[split](S),
 529        touchMap = {
 530            mousedown: "touchstart",
 531            mousemove: "touchmove",
 532            mouseup: "touchend"
 533        },
 534        lowerCase = Str.prototype.toLowerCase,
 535        math = Math,
 536        mmax = math.max,
 537        mmin = math.min,
 538        abs = math.abs,
 539        pow = math.pow,
 540        PI = math.PI,
 541        nu = "number",
 542        string = "string",
 543        array = "array",
 544        toString = "toString",
 545        fillString = "fill",
 546        objectToString = Object.prototype.toString,
 547        paper = {},
 548        push = "push",
 549        ISURL = R._ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i,
 550        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,
 551        isnan = {"NaN": 1, "Infinity": 1, "-Infinity": 1},
 552        bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
 553        round = math.round,
 554        setAttribute = "setAttribute",
 555        toFloat = parseFloat,
 556        toInt = parseInt,
 557        upperCase = Str.prototype.toUpperCase,
 558        availableAttrs = R._availableAttrs = {
 559            "arrow-end": "none",
 560            "arrow-start": "none",
 561            blur: 0,
 562            "clip-rect": "0 0 1e9 1e9",
 563            cursor: "default",
 564            cx: 0,
 565            cy: 0,
 566            fill: "#fff",
 567            "fill-opacity": 1,
 568            font: '10px "Arial"',
 569            "font-family": '"Arial"',
 570            "font-size": "10",
 571            "font-style": "normal",
 572            "font-weight": 400,
 573            gradient: 0,
 574            height: 0,
 575            href: "http://raphaeljs.com/",
 576            "letter-spacing": 0,
 577            opacity: 1,
 578            path: "M0,0",
 579            r: 0,
 580            rx: 0,
 581            ry: 0,
 582            src: "",
 583            stroke: "#000",
 584            "stroke-dasharray": "",
 585            "stroke-linecap": "butt",
 586            "stroke-linejoin": "butt",
 587            "stroke-miterlimit": 0,
 588            "stroke-opacity": 1,
 589            "stroke-width": 1,
 590            target: "_blank",
 591            "text-anchor": "middle",
 592            title: "Raphael",
 593            transform: "",
 594            width: 0,
 595            x: 0,
 596            y: 0
 597        },
 598        availableAnimAttrs = R._availableAnimAttrs = {
 599            blur: nu,
 600            "clip-rect": "csv",
 601            cx: nu,
 602            cy: nu,
 603            fill: "colour",
 604            "fill-opacity": nu,
 605            "font-size": nu,
 606            height: nu,
 607            opacity: nu,
 608            path: "path",
 609            r: nu,
 610            rx: nu,
 611            ry: nu,
 612            stroke: "colour",
 613            "stroke-opacity": nu,
 614            "stroke-width": nu,
 615            transform: "transform",
 616            width: nu,
 617            x: nu,
 618            y: nu
 619        },
 620        whitespace = /[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]/g,
 621        commaSpaces = /[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/,
 622        hsrg = {hs: 1, rg: 1},
 623        p2s = /,?([achlmqrstvxz]),?/gi,
 624        pathCommand = /([achlmrqstvz])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/ig,
 625        tCommand = /([rstm])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/ig,
 626        pathValues = /(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/ig,
 627        radial_gradient = R._radial_gradient = /^r(?:\(([^,]+?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*([^\)]+?)\))?/,
 628        eldata = {},
 629        sortByKey = function (a, b) {
 630            return a.key - b.key;
 631        },
 632        sortByNumber = function (a, b) {
 633            return toFloat(a) - toFloat(b);
 634        },
 635        fun = function () {},
 636        pipe = function (x) {
 637            return x;
 638        },
 639        rectPath = R._rectPath = function (x, y, w, h, r) {
 640            if (r) {
 641                return [["M", x + r, y], ["l", w - r * 2, 0], ["a", r, r, 0, 0, 1, r, r], ["l", 0, h - r * 2], ["a", r, r, 0, 0, 1, -r, r], ["l", r * 2 - w, 0], ["a", r, r, 0, 0, 1, -r, -r], ["l", 0, r * 2 - h], ["a", r, r, 0, 0, 1, r, -r], ["z"]];
 642            }
 643            return [["M", x, y], ["l", w, 0], ["l", 0, h], ["l", -w, 0], ["z"]];
 644        },
 645        ellipsePath = function (x, y, rx, ry) {
 646            if (ry == null) {
 647                ry = rx;
 648            }
 649            return [["M", x, y], ["m", 0, -ry], ["a", rx, ry, 0, 1, 1, 0, 2 * ry], ["a", rx, ry, 0, 1, 1, 0, -2 * ry], ["z"]];
 650        },
 651        getPath = R._getPath = {
 652            path: function (el) {
 653                return el.attr("path");
 654            },
 655            circle: function (el) {
 656                var a = el.attrs;
 657                return ellipsePath(a.cx, a.cy, a.r);
 658            },
 659            ellipse: function (el) {
 660                var a = el.attrs;
 661                return ellipsePath(a.cx, a.cy, a.rx, a.ry);
 662            },
 663            rect: function (el) {
 664                var a = el.attrs;
 665                return rectPath(a.x, a.y, a.width, a.height, a.r);
 666            },
 667            image: function (el) {
 668                var a = el.attrs;
 669                return rectPath(a.x, a.y, a.width, a.height);
 670            },
 671            text: function (el) {
 672                var bbox = el._getBBox();
 673                return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);
 674            },
 675            set : function(el) {
 676                var bbox = el._getBBox();
 677                return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);
 678            }
 679        },
 680        /*\
 681         * Raphael.mapPath
 682         [ method ]
 683         **
 684         * Transform the path string with given matrix.
 685         > Parameters
 686         - path (string) path string
 687         - matrix (object) see @Matrix
 688         = (string) transformed path string
 689        \*/
 690        mapPath = R.mapPath = function (path, matrix) {
 691            if (!matrix) {
 692                return path;
 693            }
 694            var x, y, i, j, ii, jj, pathi;
 695            path = path2curve(path);
 696            for (i = 0, ii = path.length; i < ii; i++) {
 697                pathi = path[i];
 698                for (j = 1, jj = pathi.length; j < jj; j += 2) {
 699                    x = matrix.x(pathi[j], pathi[j + 1]);
 700                    y = matrix.y(pathi[j], pathi[j + 1]);
 701                    pathi[j] = x;
 702                    pathi[j + 1] = y;
 703                }
 704            }
 705            return path;
 706        };
 707
 708    R._g = g;
 709    /*\
 710     * Raphael.type
 711     [ property (string) ]
 712     **
 713     * Can be “SVG”, “VML” or empty, depending on browser support.
 714    \*/
 715    R.type = (g.win.SVGAngle || g.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML");
 716    if (R.type == "VML") {
 717        var d = g.doc.createElement("div"),
 718            b;
 719        d.innerHTML = '<v:shape adj="1"/>';
 720        b = d.firstChild;
 721        b.style.behavior = "url(#default#VML)";
 722        if (!(b && typeof b.adj == "object")) {
 723            return (R.type = E);
 724        }
 725        d = null;
 726    }
 727    /*\
 728     * Raphael.svg
 729     [ property (boolean) ]
 730     **
 731     * `true` if browser supports SVG.
 732    \*/
 733    /*\
 734     * Raphael.vml
 735     [ property (boolean) ]
 736     **
 737     * `true` if browser supports VML.
 738    \*/
 739    R.svg = !(R.vml = R.type == "VML");
 740    R._Paper = Paper;
 741    /*\
 742     * Raphael.fn
 743     [ property (object) ]
 744     **
 745     * You can add your own method to the canvas. For example if you want to draw a pie chart,
 746     * you can create your own pie chart function and ship it as a Raphaël plugin. To do this
 747     * you need to extend the `Raphael.fn` object. You should modify the `fn` object before a
 748     * Raphaël instance is created, otherwise it will take no effect. Please note that the
 749     * ability for namespaced plugins was removed in Raphael 2.0. It is up to the plugin to
 750     * ensure any namespacing ensures proper context.
 751     > Usage
 752     | Raphael.fn.arrow = function (x1, y1, x2, y2, size) {
 753     |     return this.path( ... );
 754     | };
 755     | // or create namespace
 756     | Raphael.fn.mystuff = {
 757     |     arrow: function () {…},
 758     |     star: function () {…},
 759     |     // etc…
 760     | };
 761     | var paper = Raphael(10, 10, 630, 480);
 762     | // then use it
 763     | paper.arrow(10, 10, 30, 30, 5).attr({fill: "#f00"});
 764     | paper.mystuff.arrow();
 765     | paper.mystuff.star();
 766    \*/
 767    R.fn = paperproto = Paper.prototype = R.prototype;
 768    R._id = 0;
 769    R._oid = 0;
 770    /*\
 771     * Raphael.is
 772     [ method ]
 773     **
 774     * Handfull replacement for `typeof` operator.
 775     > Parameters
 776     - o (…) any object or primitive
 777     - type (string) name of the type, i.e. “string”, “function”, “number”, etc.
 778     = (boolean) is given value is of given type
 779    \*/
 780    R.is = function (o, type) {
 781        type = lowerCase.call(type);
 782        if (type == "finite") {
 783            return !isnan[has](+o);
 784        }
 785        if (type == "array") {
 786            return o instanceof Array;
 787        }
 788        return  (type == "null" && o === null) ||
 789                (type == typeof o && o !== null) ||
 790                (type == "object" && o === Object(o)) ||
 791                (type == "array" && Array.isArray && Array.isArray(o)) ||
 792                objectToString.call(o).slice(8, -1).toLowerCase() == type;
 793    };
 794
 795    function clone(obj) {
 796        if (typeof obj == "function" || Object(obj) !== obj) {
 797            return obj;
 798        }
 799        var res = new obj.constructor;
 800        for (var key in obj) if (obj[has](key)) {
 801            res[key] = clone(obj[key]);
 802        }
 803        return res;
 804    }
 805
 806    /*\
 807     * Raphael.angle
 808     [ method ]
 809     **
 810     * Returns angle between two or three points
 811     > Parameters
 812     - x1 (number) x coord of first point
 813     - y1 (number) y coord of first point
 814     - x2 (number) x coord of second point
 815     - y2 (number) y coord of second point
 816     - x3 (number) #optional x coord of third point
 817     - y3 (number) #optional y coord of third point
 818     = (number) angle in degrees.
 819    \*/
 820    R.angle = function (x1, y1, x2, y2, x3, y3) {
 821        if (x3 == null) {
 822            var x = x1 - x2,
 823                y = y1 - y2;
 824            if (!x && !y) {
 825                return 0;
 826            }
 827            return (180 + math.atan2(-y, -x) * 180 / PI + 360) % 360;
 828        } else {
 829            return R.angle(x1, y1, x3, y3) - R.angle(x2, y2, x3, y3);
 830        }
 831    };
 832    /*\
 833     * Raphael.rad
 834     [ method ]
 835     **
 836     * Transform angle to radians
 837     > Parameters
 838     - deg (number) angle in degrees
 839     = (number) angle in radians.
 840    \*/
 841    R.rad = function (deg) {
 842        return deg % 360 * PI / 180;
 843    };
 844    /*\
 845     * Raphael.deg
 846     [ method ]
 847     **
 848     * Transform angle to degrees
 849     > Parameters
 850     - deg (number) angle in radians
 851     = (number) angle in degrees.
 852    \*/
 853    R.deg = function (rad) {
 854        return rad * 180 / PI % 360;
 855    };
 856    /*\
 857     * Raphael.snapTo
 858     [ method ]
 859     **
 860     * Snaps given value to given grid.
 861     > Parameters
 862     - values (array|number) given array of values or step of the grid
 863     - value (number) value to adjust
 864     - tolerance (number) #optional tolerance for snapping. Default is `10`.
 865     = (number) adjusted value.
 866    \*/
 867    R.snapTo = function (values, value, tolerance) {
 868        tolerance = R.is(tolerance, "finite") ? tolerance : 10;
 869        if (R.is(values, array)) {
 870            var i = values.length;
 871            while (i--) if (abs(values[i] - value) <= tolerance) {
 872                return values[i];
 873            }
 874        } else {
 875            values = +values;
 876            var rem = value % values;
 877            if (rem < tolerance) {
 878                return value - rem;
 879            }
 880            if (rem > values - tolerance) {
 881                return value - rem + values;
 882            }
 883        }
 884        return value;
 885    };
 886
 887    /*\
 888     * Raphael.createUUID
 889     [ method ]
 890     **
 891     * Returns RFC4122, version 4 ID
 892    \*/
 893    var createUUID = R.createUUID = (function (uuidRegEx, uuidReplacer) {
 894        return function () {
 895            return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(uuidRegEx, uuidReplacer).toUpperCase();
 896        };
 897    })(/[xy]/g, function (c) {
 898        var r = math.random() * 16 | 0,
 899            v = c == "x" ? r : (r & 3 | 8);
 900        return v.toString(16);
 901    });
 902
 903    /*\
 904     * Raphael.setWindow
 905     [ method ]
 906     **
 907     * Used when you need to draw in `&lt;iframe>`. Switched window to the iframe one.
 908     > Parameters
 909     - newwin (window) new window object
 910    \*/
 911    R.setWindow = function (newwin) {
 912        eve("raphael.setWindow", R, g.win, newwin);
 913        g.win = newwin;
 914        g.doc = g.win.document;
 915        if (R._engine.initWin) {
 916            R._engine.initWin(g.win);
 917        }
 918    };
 919    var toHex = function (color) {
 920        if (R.vml) {
 921            // http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/
 922            var trim = /^\s+|\s+$/g;
 923            var bod;
 924            try {
 925                var docum = new ActiveXObject("htmlfile");
 926                docum.write("<body>");
 927                docum.close();
 928                bod = docum.body;
 929            } catch(e) {
 930                bod = createPopup().document.body;
 931            }
 932            var range = bod.createTextRange();
 933            toHex = cacher(function (color) {
 934                try {
 935                    bod.style.color = Str(color).replace(trim, E);
 936                    var value = range.queryCommandValue("ForeColor");
 937                    value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16);
 938                    return "#" + ("000000" + value.toString(16)).slice(-6);
 939                } catch(e) {
 940                    return "none";
 941                }
 942            });
 943        } else {
 944            var i = g.doc.createElement("i");
 945            i.title = "Rapha\xebl Colour Picker";
 946            i.style.display = "none";
 947            g.doc.body.appendChild(i);
 948            toHex = cacher(function (color) {
 949                i.style.color = color;
 950                return g.doc.defaultView.getComputedStyle(i, E).getPropertyValue("color");
 951            });
 952        }
 953        return toHex(color);
 954    },
 955    hsbtoString = function () {
 956        return "hsb(" + [this.h, this.s, this.b] + ")";
 957    },
 958    hsltoString = function () {
 959        return "hsl(" + [this.h, this.s, this.l] + ")";
 960    },
 961    rgbtoString = function () {
 962        return this.hex;
 963    },
 964    prepareRGB = function (r, g, b) {
 965        if (g == null && R.is(r, "object") && "r" in r && "g" in r && "b" in r) {
 966            b = r.b;
 967            g = r.g;
 968            r = r.r;
 969        }
 970        if (g == null && R.is(r, string)) {
 971            var clr = R.getRGB(r);
 972            r = clr.r;
 973            g = clr.g;
 974            b = clr.b;
 975        }
 976        if (r > 1 || g > 1 || b > 1) {
 977            r /= 255;
 978            g /= 255;
 979            b /= 255;
 980        }
 981
 982        return [r, g, b];
 983    },
 984    packageRGB = function (r, g, b, o) {
 985        r *= 255;
 986        g *= 255;
 987        b *= 255;
 988        var rgb = {
 989            r: r,
 990            g: g,
 991            b: b,
 992            hex: R.rgb(r, g, b),
 993            toString: rgbtoString
 994        };
 995        R.is(o, "finite") && (rgb.opacity = o);
 996        return rgb;
 997    };
 998
 999    /*\
1000     * Raphael.color
1001     [ method ]
1002     **
1003     * Parses the color string and returns object with all values for the given color.
1004     > Parameters
1005     - clr (string) color string in one of the supported formats (see @Raphael.getRGB)
1006     = (object) Combined RGB & HSB object in format:
1007     o {
1008     o     r (number) red,
1009     o     g (number) green,
1010     o     b (number) blue,
1011     o     hex (string) color in HTML/CSS format: #••••••,
1012     o     error (boolean) `true` if string can’t be parsed,
1013     o     h (number) hue,
1014     o     s (number) saturation,
1015     o     v (number) value (brightness),
1016     o     l (number) lightness
1017     o }
1018    \*/
1019    R.color = function (clr) {
1020        var rgb;
1021        if (R.is(clr, "object") && "h" in clr && "s" in clr && "b" in clr) {
1022            rgb = R.hsb2rgb(clr);
1023            clr.r = rgb.r;
1024            clr.g = rgb.g;
1025            clr.b = rgb.b;
1026            clr.hex = rgb.hex;
1027        } else if (R.is(clr, "object") && "h" in clr && "s" in clr && "l" in clr) {
1028            rgb = R.hsl2rgb(clr);
1029            clr.r = rgb.r;
1030            clr.g = rgb.g;
1031            clr.b = rgb.b;
1032            clr.hex = rgb.hex;
1033        } else {
1034            if (R.is(clr, "string")) {
1035                clr = R.getRGB(clr);
1036            }
1037            if (R.is(clr, "object") && "r" in clr && "g" in clr && "b" in clr) {
1038                rgb = R.rgb2hsl(clr);
1039                clr.h = rgb.h;
1040                clr.s = rgb.s;
1041                clr.l = rgb.l;
1042                rgb = R.rgb2hsb(clr);
1043                clr.v = rgb.b;
1044            } else {
1045                clr = {hex: "none"};
1046                clr.r = clr.g = clr.b = clr.h = clr.s = clr.v = clr.l = -1;
1047            }
1048        }
1049        clr.toString = rgbtoString;
1050        return clr;
1051    };
1052    /*\
1053     * Raphael.hsb2rgb
1054     [ method ]
1055     **
1056     * Converts HSB values to RGB object.
1057     > Parameters
1058     - h (number) hue
1059     - s (number) saturation
1060     - v (number) value or brightness
1061     = (object) RGB object in format:
1062     o {
1063     o     r (number) red,
1064     o     g (number) green,
1065     o     b (number) blue,
1066     o     hex (string) color in HTML/CSS format: #••••••
1067     o }
1068    \*/
1069    R.hsb2rgb = function (h, s, v, o) {
1070        if (this.is(h, "object") && "h" in h && "s" in h && "b" in h) {
1071            v = h.b;
1072            s = h.s;
1073            h = h.h;
1074            o = h.o;
1075        }
1076        h *= 360;
1077        var R, G, B, X, C;
1078        h = (h % 360) / 60;
1079        C = v * s;
1080        X = C * (1 - abs(h % 2 - 1));
1081        R = G = B = v - C;
1082
1083        h = ~~h;
1084        R += [C, X, 0, 0, X, C][h];
1085        G += [X, C, C, X, 0, 0][h];
1086        B += [0, 0, X, C, C, X][h];
1087        return packageRGB(R, G, B, o);
1088    };
1089    /*\
1090     * Raphael.hsl2rgb
1091     [ method ]
1092     **
1093     * Converts HSL values to RGB object.
1094     > Parameters
1095     - h (number) hue
1096     - s (number) saturation
1097     - l (number) luminosity
1098     = (object) RGB object in format:
1099     o {
1100     o     r (number) red,
1101     o     g (number) green,
1102     o     b (number) blue,
1103     o     hex (string) color in HTML/CSS format: #••••••
1104     o }
1105    \*/
1106    R.hsl2rgb = function (h, s, l, o) {
1107        if (this.is(h, "object") && "h" in h && "s" in h && "l" in h) {
1108            l = h.l;
1109            s = h.s;
1110            h = h.h;
1111        }
1112        if (h > 1 || s > 1 || l > 1) {
1113            h /= 360;
1114            s /= 100;
1115            l /= 100;
1116        }
1117        h *= 360;
1118        var R, G, B, X, C;
1119        h = (h % 360) / 60;
1120        C = 2 * s * (l < .5 ? l : 1 - l);
1121        X = C * (1 - abs(h % 2 - 1));
1122        R = G = B = l - C / 2;
1123
1124        h = ~~h;
1125        R += [C, X, 0, 0, X, C][h];
1126        G += [X, C, C, X, 0, 0][h];
1127        B += [0, 0, X, C, C, X][h];
1128        return packageRGB(R, G, B, o);
1129    };
1130    /*\
1131     * Raphael.rgb2hsb
1132     [ method ]
1133     **
1134     * Converts RGB values to HSB object.
1135     > Parameters
1136     - r (number) red
1137     - g (number) green
1138     - b (number) blue
1139     = (object) HSB object in format:
1140     o {
1141     o     h (number) hue
1142     o     s (number) saturation
1143     o     b (number) brightness
1144     o }
1145    \*/
1146    R.rgb2hsb = function (r, g, b) {
1147        b = prepareRGB(r, g, b);
1148        r = b[0];
1149        g = b[1];
1150        b = b[2];
1151
1152        var H, S, V, C;
1153        V = mmax(r, g, b);
1154        C = V - mmin(r, g, b);
1155        H = (C == 0 ? null :
1156             V == r ? (g - b) / C :
1157             V == g ? (b - r) / C + 2 :
1158                      (r - g) / C + 4
1159            );
1160        H = ((H + 360) % 6) * 60 / 360;
1161        S = C == 0 ? 0 : C / V;
1162        return {h: H, s: S, b: V, toString: hsbtoString};
1163    };
1164    /*\
1165     * Raphael.rgb2hsl
1166     [ method ]
1167     **
1168     * Converts RGB values to HSL object.
1169     > Parameters
1170     - r (number) red
1171     - g (number) green
1172     - b (number) blue
1173     = (object) HSL object in format:
1174     o {
1175     o     h (number) hue
1176     o     s (number) saturation
1177     o     l (number) luminosity
1178     o }
1179    \*/
1180    R.rgb2hsl = function (r, g, b) {
1181        b = prepareRGB(r, g, b);
1182        r = b[0];
1183        g = b[1];
1184        b = b[2];
1185
1186        var H, S, L, M, m, C;
1187        M = mmax(r, g, b);
1188        m = mmin(r, g, b);
1189        C = M - m;
1190        H = (C == 0 ? null :
1191             M == r ? (g - b) / C :
1192             M == g ? (b - r) / C + 2 :
1193                      (r - g) / C + 4);
1194        H = ((H + 360) % 6) * 60 / 360;
1195        L = (M + m) / 2;
1196        S = (C == 0 ? 0 :
1197             L < .5 ? C / (2 * L) :
1198                      C / (2 - 2 * L));
1199        return {h: H, s: S, l: L, toString: hsltoString};
1200    };
1201    R._path2string = function () {
1202        return this.join(",").replace(p2s, "$1");
1203    };
1204    function repush(array, item) {
1205        for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) {
1206            return array.push(array.splice(i, 1)[0]);
1207        }
1208    }
1209    function cacher(f, scope, postprocessor) {
1210        function newf() {
1211            var arg = Array.prototype.slice.call(arguments, 0),
1212                args = arg.join("\u2400"),
1213                cache = newf.cache = newf.cache || {},
1214                count = newf.count = newf.count || [];
1215            if (cache[has](args)) {
1216                repush(count, args);
1217                return postprocessor ? postprocessor(cache[args]) : cache[args];
1218            }
1219            count.length >= 1e3 && delete cache[count.shift()];
1220            count.push(args);
1221            cache[args] = f[apply](scope, arg);
1222            return postprocessor ? postprocessor(cache[args]) : cache[args];
1223        }
1224        return newf;
1225    }
1226
1227    var preload = R._preload = function (src, f) {
1228        var img = g.doc.createElement("img");
1229        img.style.cssText = "position:absolute;left:-9999em;top:-9999em";
1230        img.onload = function () {
1231            f.call(this);
1232            this.onload = null;
1233            g.doc.body.removeChild(this);
1234        };
1235        img.onerror = function () {
1236            g.doc.body.removeChild(this);
1237        };
1238        g.doc.body.appendChild(img);
1239        img.src = src;
1240    };
1241
1242    function clrToString() {
1243        return this.hex;
1244    }
1245
1246    /*\
1247     * Raphael.getRGB
1248     [ method ]
1249     **
1250     * Parses colour string as RGB object
1251     > Parameters
1252     - colour (string) colour string in one of formats:
1253     # <ul>
1254     #     <li>Colour name (“<code>red</code>”, “<code>green</code>”, “<code>cornflowerblue</code>”, etc)</li>
1255     #     <li>#••• — shortened HTML colour: (“<code>#000</code>”, “<code>#fc0</code>”, etc)</li>
1256     #     <li>#•••••• — full length HTML colour: (“<code>#000000</code>”, “<code>#bd2300</code>”)</li>
1257     #     <li>rgb(•••, •••, •••) — red, green and blue channels’ values: (“<code>rgb(200,&nbsp;100,&nbsp;0)</code>”)</li>
1258     #     <li>rgb(•••%, •••%, •••%) — same as above, but in %: (“<code>rgb(100%,&nbsp;175%,&nbsp;0%)</code>”)</li>
1259     #     <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (“<code>hsb(0.5,&nbsp;0.25,&nbsp;1)</code>”)</li>
1260     #     <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>
1261     #     <li>hsl(•••, •••, •••) — same as hsb</li>
1262     #     <li>hsl(•••%, •••%, •••%) — same as hsb</li>
1263     # </ul>
1264     = (object) RGB object in format:
1265     o {
1266     o     r (number) red,
1267     o     g (number) green,
1268     o     b (number) blue
1269     o     hex (string) color in HTML/CSS format: #••••••,
1270     o     error (boolean) true if string can’t be parsed
1271     o }
1272    \*/
1273    R.getRGB = cacher(function (colour) {
1274        if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) {
1275            return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: clrToString};
1276        }
1277        if (colour == "none") {
1278            return {r: -1, g: -1, b: -1, hex: "none", toString: clrToString};
1279        }
1280        !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour));
1281        var res,
1282            red,
1283            green,
1284            blue,
1285            opacity,
1286            t,
1287            values,
1288            rgb = colour.match(colourRegExp);
1289        if (rgb) {
1290            if (rgb[2]) {
1291                blue = toInt(rgb[2].substring(5), 16);
1292                green = toInt(rgb[2].substring(3, 5), 16);
1293                red = toInt(rgb[2].substring(1, 3), 16);
1294            }
1295            if (rgb[3]) {
1296                blue = toInt((t = rgb[3].charAt(3)) + t, 16);
1297                green = toInt((t = rgb[3].charAt(2)) + t, 16);
1298                red = toInt((t = rgb[3].charAt(1)) + t, 16);
1299            }
1300            if (rgb[4]) {
1301                values = rgb[4][split](commaSpaces);
1302                red = toFloat(values[0]);
1303                values[0].slice(-1) == "%" && (red *= 2.55);
1304                green = toFloat(values[1]);
1305                values[1].slice(-1) == "%" && (green *= 2.55);
1306                blue = toFloat(values[2]);
1307                values[2].slice(-1) == "%" && (blue *= 2.55);
1308                rgb[1].toLowerCase().slice(0, 4) == "rgba" && (opacity = toFloat(values[3]));
1309                values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
1310            }
1311            if (rgb[5]) {
1312                values = rgb[5][split](commaSpaces);
1313                red = toFloat(values[0]);
1314                values[0].slice(-1) == "%" && (red *= 2.55);
1315                green = toFloat(values[1]);
1316                values[1].slice(-1) == "%" && (green *= 2.55);
1317                blue = toFloat(values[2]);
1318                values[2].slice(-1) == "%" && (blue *= 2.55);
1319                (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);
1320                rgb[1].toLowerCase().slice(0, 4) == "hsba" && (opacity = toFloat(values[3]));
1321                values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
1322                return R.hsb2rgb(red, green, blue, opacity);
1323            }
1324            if (rgb[6]) {
1325                values = rgb[6][split](commaSpaces);
1326                red = toFloat(values[0]);
1327                values[0].slice(-1) == "%" && (red *= 2.55);
1328                green = toFloat(values[1]);
1329                values[1].slice(-1) == "%" && (green *= 2.55);
1330                blue = toFloat(values[2]);
1331                values[2].slice(-1) == "%" && (blue *= 2.55);
1332                (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);
1333                rgb[1].toLowerCase().slice(0, 4) == "hsla" && (opacity = toFloat(values[3]));
1334                values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
1335                return R.hsl2rgb(red, green, blue, opacity);
1336            }
1337            rgb = {r: red, g: green, b: blue, toString: clrToString};
1338            rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1);
1339            R.is(opacity, "finite") && (rgb.opacity = opacity);
1340            return rgb;
1341        }
1342        return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: clrToString};
1343    }, R);
1344    /*\
1345     * Raphael.hsb
1346     [ method ]
1347     **
1348     * Converts HSB values to hex representation of the colour.
1349     > Parameters
1350     - h (number) hue
1351     - s (number) saturation
1352     - b (number) value or brightness
1353     = (string) hex representation of the colour.
1354    \*/
1355    R.hsb = cacher(function (h, s, b) {
1356        return R.hsb2rgb(h, s, b).hex;
1357    });
1358    /*\
1359     * Raphael.hsl
1360     [ method ]
1361     **
1362     * Converts HSL values to hex representation of the colour.
1363     > Parameters
1364     - h (number) hue
1365   

Large files files are truncated, but you can click here to view the full file