Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Checkpoint website.

  • Loading branch information...
commit de957eca7d7b2864f87bb273072f6ab91aba8ff5 1 parent 5ea2a63
Mike Bostock mbostock authored
1  .gitignore
... ... @@ -0,0 +1 @@
  1 +_site
5 _config.yml
... ... @@ -0,0 +1,5 @@
  1 +safe: true
  2 +source: .
  3 +destination: _site
  4 +lsi: false
  5 +pygments: true
22 _layouts/default.html
... ... @@ -0,0 +1,22 @@
  1 +<!DOCTYPE html>
  2 +<html>
  3 + <head>
  4 + <meta http-equiv="content-type" content="text/html;charset=utf-8">
  5 + <title>d3{% if page.title %} - {{ page.title }}{% endif %}</title>
  6 + <script type="text/javascript" src="/d3.js?0.0.0"></script>
  7 + <style type="text/css">
  8 +
  9 +@import url("/style.css?0.0.0");
  10 +@import url("/syntax.css?0.0.0");
  11 +
  12 + </style>
  13 + </head>
  14 + <body>
  15 + <div class="body">
  16 +
  17 +{{ content }}
  18 +
  19 + </div>
  20 + <div class="foot">Copyright &copy; 2010 <a href="http://bost.ocks.org/mike">Mike Bostock</a></div>
  21 + </body>
  22 +</html>
1,429 d3.js
... ... @@ -0,0 +1,1429 @@
  1 +if (!Date.now) Date.now = function() {
  2 + return +new Date();
  3 +};
  4 +if (!Object.create) Object.create = function(o) {
  5 + /** @constructor */ function f() {}
  6 + f.prototype = o;
  7 + return new f();
  8 +};
  9 +(function(_) {
  10 + var d3 = _.d3 = {};
  11 + d3.version = "0.0.0"; // semver
  12 +var ns = {
  13 +
  14 + prefix: {
  15 + svg: "http://www.w3.org/2000/svg",
  16 + xhtml: "http://www.w3.org/1999/xhtml",
  17 + xlink: "http://www.w3.org/1999/xlink",
  18 + xml: "http://www.w3.org/XML/1998/namespace",
  19 + xmlns: "http://www.w3.org/2000/xmlns/"
  20 + },
  21 +
  22 + resolve: function(prefix) {
  23 + return ns.prefix[prefix] || null;
  24 + },
  25 +
  26 + qualify: function(name) {
  27 + var i = name.indexOf(":");
  28 + return i < 0 ? name : {
  29 + space: ns.prefix[name.substring(0, i)],
  30 + local: name.substring(i + 1)
  31 + };
  32 + }
  33 +
  34 +};
  35 +d3.dispatch = function(that) {
  36 + var types = {};
  37 +
  38 + that.on = function(type, handler) {
  39 + var listeners = types[type] || (types[type] = []);
  40 + for (var i = 0; i < listeners.length; i++) {
  41 + if (listeners[i].handler == handler) return that; // already registered
  42 + }
  43 + listeners.push({handler: handler, on: true});
  44 + return that;
  45 + };
  46 +
  47 + that.off = function(type, handler) {
  48 + var listeners = types[type];
  49 + if (listeners) for (var i = 0; i < listeners.length; i++) {
  50 + var l = listeners[i];
  51 + if (l.handler == handler) {
  52 + l.on = false;
  53 + listeners.splice(i, 1);
  54 + break;
  55 + }
  56 + }
  57 + return that;
  58 + };
  59 +
  60 + that.dispatch = function(event) {
  61 + var listeners = types[event.type];
  62 + if (!listeners) return;
  63 + listeners = listeners.slice(); // defensive copy
  64 + for (var i = 0; i < listeners.length; i++) {
  65 + var l = listeners[i];
  66 + if (l.on) l.handler.call(that, event);
  67 + }
  68 + };
  69 +
  70 + return that;
  71 +};
  72 +/*
  73 + * TERMS OF USE - EASING EQUATIONS
  74 + *
  75 + * Open source under the BSD License.
  76 + *
  77 + * Copyright 2001 Robert Penner
  78 + * All rights reserved.
  79 + *
  80 + * Redistribution and use in source and binary forms, with or without
  81 + * modification, are permitted provided that the following conditions are met:
  82 + *
  83 + * - Redistributions of source code must retain the above copyright notice, this
  84 + * list of conditions and the following disclaimer.
  85 + *
  86 + * - Redistributions in binary form must reproduce the above copyright notice,
  87 + * this list of conditions and the following disclaimer in the documentation
  88 + * and/or other materials provided with the distribution.
  89 + *
  90 + * - Neither the name of the author nor the names of contributors may be used to
  91 + * endorse or promote products derived from this software without specific
  92 + * prior written permission.
  93 + *
  94 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  95 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  96 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  97 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  98 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  99 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  100 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  101 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  102 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  103 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  104 + * POSSIBILITY OF SUCH DAMAGE.
  105 + */
  106 +
  107 +var quad = poly(2),
  108 + cubic = poly(3);
  109 +
  110 +var ease = {
  111 + "linear": function() { return linear; },
  112 + "poly": poly,
  113 + "quad": function() { return quad; },
  114 + "cubic": function() { return cubic; },
  115 + "sin": function() { return sin; },
  116 + "exp": function() { return exp; },
  117 + "circle": function() { return circle; },
  118 + "elastic": elastic,
  119 + "back": back,
  120 + "bounce": function() { return bounce; }
  121 +};
  122 +
  123 +var mode = {
  124 + "in": function(f) { return f; },
  125 + "out": reverse,
  126 + "in-out": reflect,
  127 + "out-int": function(f) { return reflect(reverse(f)); }
  128 +};
  129 +
  130 +d3.ease = function(name) {
  131 + var i = name.indexOf("-"),
  132 + t = i >= 0 ? name.substring(0, i) : name,
  133 + m = i >= 0 ? name.substring(i + 1) : "in";
  134 + return mode[m](ease[t].apply(null, Array.prototype.slice.call(arguments, 1)));
  135 +};
  136 +
  137 +function reverse(f) {
  138 + return function(t) {
  139 + return 1 - f(1 - t);
  140 + };
  141 +}
  142 +
  143 +function reflect(f) {
  144 + return function(t) {
  145 + return .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t)));
  146 + };
  147 +}
  148 +
  149 +function linear(t) {
  150 + return t;
  151 +}
  152 +
  153 +function poly(e) {
  154 + return function(t) {
  155 + return Math.pow(t, e);
  156 + }
  157 +}
  158 +
  159 +function sin(t) {
  160 + return 1 - Math.cos(t * Math.PI / 2);
  161 +}
  162 +
  163 +function exp(t) {
  164 + return t ? Math.pow(2, 10 * (t - 1)) - 1e-3 : 0;
  165 +}
  166 +
  167 +function circle(t) {
  168 + return 1 - Math.sqrt(1 - t * t);
  169 +}
  170 +
  171 +function elastic(a, p) {
  172 + var s;
  173 + if (arguments.length < 2) p = 0.45;
  174 + if (arguments.length < 1) { a = 1; s = p / 4; }
  175 + else s = p / (2 * Math.PI) * Math.asin(1 / a);
  176 + return function(t) {
  177 + return 1 + a * Math.pow(2, 10 * -t) * Math.sin(-(t + s) * 2 * Math.PI / p);
  178 + };
  179 +}
  180 +
  181 +function back(s) {
  182 + if (!s) s = 1.70158;
  183 + return function(t) {
  184 + return t * t * ((s + 1) * t - s);
  185 + };
  186 +}
  187 +
  188 +function bounce(t) {
  189 + return t < 1 / 2.75 ? 7.5625 * t * t
  190 + : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75
  191 + : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375
  192 + : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
  193 +}
  194 +d3.interpolate = function(a, b) {
  195 + if (typeof b == "number") return d3.interpolateNumber(+a, b);
  196 + if (typeof b == "string") return d3.interpolateString(String(a), b);
  197 + if (b instanceof Array) return d3.interpolateArray(a, b);
  198 + return d3.interpolateObject(a, b);
  199 +};
  200 +
  201 +d3.interpolateNumber = function(a, b) {
  202 + b -= a;
  203 + return function(t) { return a + b * t; };
  204 +};
  205 +
  206 +d3.interpolateString = function(a, b) {
  207 + var m, // current match
  208 + i, // current index
  209 + j, // current index (for coallescing)
  210 + s0 = 0, // start index of current string prefix
  211 + s1 = 0, // end index of current string prefix
  212 + s = [], // string constants and placeholders
  213 + q = [], // number interpolators
  214 + n, // q.length
  215 + o;
  216 +
  217 + // Find all numbers in b.
  218 + for (i = 0; m = d3_interpolate_number.exec(b); ++i) {
  219 + if (m.index) s.push(b.substring(s0, s1 = m.index));
  220 + q.push({i: s.length, x: m[0]});
  221 + s.push(null);
  222 + s0 = d3_interpolate_number.lastIndex;
  223 + }
  224 + if (s0 < b.length) s.push(b.substring(s0));
  225 +
  226 + // Find all numbers in a.
  227 + for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) {
  228 + o = q[i];
  229 + if (o.x == m[0]) { // The numbers match, so coallesce.
  230 + if (o.i) {
  231 + if (s[o.i + 1] == null) { // This match is followed by another number.
  232 + s[o.i - 1] += o.x;
  233 + s.splice(o.i, 1);
  234 + for (j = i + 1; j < n; ++j) q[j].i--;
  235 + } else { // This match is followed by a string, so coallesce twice.
  236 + s[o.i - 1] += o.x + s[o.i + 1];
  237 + s.splice(o.i, 2);
  238 + for (j = i + 1; j < n; ++j) q[j].i -= 2;
  239 + }
  240 + } else {
  241 + if (s[o.i + 1] == null) { // This match is followed by another number.
  242 + s[o.i] = o.x;
  243 + } else { // This match is followed by a string, so coallesce twice.
  244 + s[o.i] = o.x + s[o.i + 1];
  245 + s.splice(o.i + 1, 1);
  246 + for (j = i + 1; j < n; ++j) q[j].i--;
  247 + }
  248 + }
  249 + q.splice(i, 1);
  250 + n--;
  251 + i--;
  252 + } else {
  253 + o.x = d3.interpolateNumber(parseFloat(m[0]), parseFloat(o.x));
  254 + }
  255 + }
  256 +
  257 + // Remove any numbers in b not found in a.
  258 + while (i < n) {
  259 + o = q.pop();
  260 + if (s[o.i + 1] == null) { // This match is followed by another number.
  261 + s[o.i] = o.x;
  262 + } else { // This match is followed by a string, so coallesce twice.
  263 + s[o.i] = o.x + s[o.i + 1];
  264 + s.splice(o.i + 1, 1);
  265 + }
  266 + n--;
  267 + }
  268 +
  269 + // Special optimization for only a single match.
  270 + if (s.length == 1) {
  271 + return s[0] == null ? q[0].x : function() { return b; };
  272 + }
  273 +
  274 + // Otherwise, interpolate each of the numbers and rejoin the string.
  275 + return function(t) {
  276 + for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t);
  277 + return s.join("");
  278 + };
  279 +};
  280 +
  281 +d3.interpolateRgb = function(a, b) {
  282 + a = d3_rgb(a);
  283 + b = d3_rgb(b);
  284 + var ar = a.r,
  285 + ag = a.g,
  286 + ab = a.b,
  287 + br = b.r - ar,
  288 + bg = b.g - ag,
  289 + bb = b.b - ab;
  290 + return function(t) {
  291 + return "rgb(" + Math.round(ar + br * t)
  292 + + "," + Math.round(ag + bg * t)
  293 + + "," + Math.round(ab + bb * t)
  294 + + ")";
  295 + };
  296 +};
  297 +
  298 +d3.interpolateArray = function(a, b) {
  299 + var x = [],
  300 + c = [],
  301 + na = a.length,
  302 + nb = b.length,
  303 + n0 = Math.min(a.length, b.length),
  304 + i;
  305 + for (i = 0; i < n0; ++i) x.push(d3.interpolate(a[i], b[i]));
  306 + for (; i < na; ++i) c[i] = a[i];
  307 + for (; i < nb; ++i) c[i] = b[i];
  308 + return function(t) {
  309 + for (i = 0; i < n0; ++i) c[i] = x[i](t);
  310 + return c;
  311 + };
  312 +};
  313 +
  314 +d3.interpolateObject = function(a, b) {
  315 + var i = {},
  316 + c = {},
  317 + k;
  318 + for (k in a) {
  319 + if (k in b) {
  320 + i[k] = d3_interpolateByName(k)(a[k], b[k]);
  321 + } else {
  322 + c[k] = a[k];
  323 + }
  324 + }
  325 + for (k in b) {
  326 + if (!(k in a)) {
  327 + c[k] = b[k];
  328 + }
  329 + }
  330 + return function(t) {
  331 + for (k in i) c[k] = i[k](t);
  332 + return c;
  333 + };
  334 +}
  335 +
  336 +var d3_interpolate_number = /[-+]?(?:\d+\.\d+|\d+\.|\.\d+|\d+)(?:[eE][-]?\d+)?/g,
  337 + d3_interpolate_digits = /[-+]?\d*\.?\d*(?:[eE][-]?\d+)?(.*)/,
  338 + d3_interpolate_rgb = {background: 1, fill: 1, stroke: 1};
  339 +
  340 +function d3_interpolateByName(n) {
  341 + return n in d3_interpolate_rgb || /\bcolor\b/.test(n)
  342 + ? d3.interpolateRgb
  343 + : d3.interpolate;
  344 +}
  345 +d3.tween = d3_tweenInterpolate(d3.interpolate);
  346 +d3.tweenRgb = d3_tweenInterpolate(d3.interpolateRgb);
  347 +
  348 +function d3_tweenInterpolate(I) {
  349 + return function(a, b) {
  350 + var i = I(a, b);
  351 + return function() {
  352 + return i(d3.time);
  353 + };
  354 + };
  355 +}
  356 +
  357 +function d3_tweenByName(n) {
  358 + return n in d3_interpolate_rgb || /\bcolor\b/.test(n)
  359 + ? d3.tweenRgb
  360 + : d3.tween;
  361 +}
  362 +function d3_rgb(format) {
  363 + var r, // red channel; int in [0, 255]
  364 + g, // green channel; int in [0, 255]
  365 + b, // blue channel; int in [0, 255]
  366 + m1, // CSS color specification match
  367 + m2, // CSS color specification type (e.g., rgb)
  368 + name;
  369 +
  370 + /* Handle hsl, rgb. */
  371 + m1 = /([a-z]+)\((.*)\)/i.exec(format);
  372 + if (m1) {
  373 + m2 = m1[2].split(",");
  374 + switch (m1[1]) {
  375 + case "hsl": {
  376 + return d3_rgb_hsl(
  377 + parseFloat(m2[0]), // degrees
  378 + parseFloat(m2[1]) / 100, // percentage
  379 + parseFloat(m2[2]) / 100); // percentage
  380 + }
  381 + case "rgb": {
  382 + return {
  383 + r: d3_rgb_parse(m2[0]),
  384 + g: d3_rgb_parse(m2[1]),
  385 + b: d3_rgb_parse(m2[2])
  386 + };
  387 + }
  388 + }
  389 + }
  390 +
  391 + /* Named colors. */
  392 + if (name = d3_rgb_names[format]) return name;
  393 +
  394 + /* Null or undefined. */
  395 + if (format == null) return d3_rgb_names.black;
  396 +
  397 + /* Hexadecimal colors: #rgb and #rrggbb. */
  398 + if (format.charAt(0) == "#") {
  399 + if (format.length == 4) {
  400 + r = format.charAt(1); r += r;
  401 + g = format.charAt(2); g += g;
  402 + b = format.charAt(3); b += b;
  403 + } else if (format.length == 7) {
  404 + r = format.substring(1, 3);
  405 + g = format.substring(3, 5);
  406 + b = format.substring(5, 7);
  407 + }
  408 + r = parseInt(r, 16);
  409 + g = parseInt(g, 16);
  410 + b = parseInt(b, 16);
  411 + }
  412 +
  413 + return {r: r, g: g, b: b};
  414 +};
  415 +
  416 +function d3_rgb_hsl(h, s, l) {
  417 + var m1,
  418 + m2;
  419 +
  420 + /* Some simple corrections for h, s and l. */
  421 + h = h % 360; if (h < 0) h += 360;
  422 + s = s < 0 ? 0 : s > 1 ? 1 : s;
  423 + l = l < 0 ? 0 : l > 1 ? 1 : l;
  424 +
  425 + /* From FvD 13.37, CSS Color Module Level 3 */
  426 + m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
  427 + m1 = 2 * l - m2;
  428 +
  429 + function v(h) {
  430 + if (h > 360) h -= 360;
  431 + else if (h < 0) h += 360;
  432 + if (h < 60) return m1 + (m2 - m1) * h / 60;
  433 + if (h < 180) return m2;
  434 + if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
  435 + return m1;
  436 + }
  437 +
  438 + function vv(h) {
  439 + return Math.round(v(h) * 255);
  440 + }
  441 +
  442 + return {r: vv(h + 120), g: vv(h), b: vv(h - 120)};
  443 +}
  444 +
  445 +function d3_rgb_parse(c) { // either integer or percentage
  446 + var f = parseFloat(c);
  447 + return c.charAt(c.length - 1) == "%" ? Math.round(f * 2.55) : f;
  448 +}
  449 +
  450 +var d3_rgb_names = {
  451 + aliceblue: "#f0f8ff",
  452 + antiquewhite: "#faebd7",
  453 + aqua: "#00ffff",
  454 + aquamarine: "#7fffd4",
  455 + azure: "#f0ffff",
  456 + beige: "#f5f5dc",
  457 + bisque: "#ffe4c4",
  458 + black: "#000000",
  459 + blanchedalmond: "#ffebcd",
  460 + blue: "#0000ff",
  461 + blueviolet: "#8a2be2",
  462 + brown: "#a52a2a",
  463 + burlywood: "#deb887",
  464 + cadetblue: "#5f9ea0",
  465 + chartreuse: "#7fff00",
  466 + chocolate: "#d2691e",
  467 + coral: "#ff7f50",
  468 + cornflowerblue: "#6495ed",
  469 + cornsilk: "#fff8dc",
  470 + crimson: "#dc143c",
  471 + cyan: "#00ffff",
  472 + darkblue: "#00008b",
  473 + darkcyan: "#008b8b",
  474 + darkgoldenrod: "#b8860b",
  475 + darkgray: "#a9a9a9",
  476 + darkgreen: "#006400",
  477 + darkgrey: "#a9a9a9",
  478 + darkkhaki: "#bdb76b",
  479 + darkmagenta: "#8b008b",
  480 + darkolivegreen: "#556b2f",
  481 + darkorange: "#ff8c00",
  482 + darkorchid: "#9932cc",
  483 + darkred: "#8b0000",
  484 + darksalmon: "#e9967a",
  485 + darkseagreen: "#8fbc8f",
  486 + darkslateblue: "#483d8b",
  487 + darkslategray: "#2f4f4f",
  488 + darkslategrey: "#2f4f4f",
  489 + darkturquoise: "#00ced1",
  490 + darkviolet: "#9400d3",
  491 + deeppink: "#ff1493",
  492 + deepskyblue: "#00bfff",
  493 + dimgray: "#696969",
  494 + dimgrey: "#696969",
  495 + dodgerblue: "#1e90ff",
  496 + firebrick: "#b22222",
  497 + floralwhite: "#fffaf0",
  498 + forestgreen: "#228b22",
  499 + fuchsia: "#ff00ff",
  500 + gainsboro: "#dcdcdc",
  501 + ghostwhite: "#f8f8ff",
  502 + gold: "#ffd700",
  503 + goldenrod: "#daa520",
  504 + gray: "#808080",
  505 + green: "#008000",
  506 + greenyellow: "#adff2f",
  507 + grey: "#808080",
  508 + honeydew: "#f0fff0",
  509 + hotpink: "#ff69b4",
  510 + indianred: "#cd5c5c",
  511 + indigo: "#4b0082",
  512 + ivory: "#fffff0",
  513 + khaki: "#f0e68c",
  514 + lavender: "#e6e6fa",
  515 + lavenderblush: "#fff0f5",
  516 + lawngreen: "#7cfc00",
  517 + lemonchiffon: "#fffacd",
  518 + lightblue: "#add8e6",
  519 + lightcoral: "#f08080",
  520 + lightcyan: "#e0ffff",
  521 + lightgoldenrodyellow: "#fafad2",
  522 + lightgray: "#d3d3d3",
  523 + lightgreen: "#90ee90",
  524 + lightgrey: "#d3d3d3",
  525 + lightpink: "#ffb6c1",
  526 + lightsalmon: "#ffa07a",
  527 + lightseagreen: "#20b2aa",
  528 + lightskyblue: "#87cefa",
  529 + lightslategray: "#778899",
  530 + lightslategrey: "#778899",
  531 + lightsteelblue: "#b0c4de",
  532 + lightyellow: "#ffffe0",
  533 + lime: "#00ff00",
  534 + limegreen: "#32cd32",
  535 + linen: "#faf0e6",
  536 + magenta: "#ff00ff",
  537 + maroon: "#800000",
  538 + mediumaquamarine: "#66cdaa",
  539 + mediumblue: "#0000cd",
  540 + mediumorchid: "#ba55d3",
  541 + mediumpurple: "#9370db",
  542 + mediumseagreen: "#3cb371",
  543 + mediumslateblue: "#7b68ee",
  544 + mediumspringgreen: "#00fa9a",
  545 + mediumturquoise: "#48d1cc",
  546 + mediumvioletred: "#c71585",
  547 + midnightblue: "#191970",
  548 + mintcream: "#f5fffa",
  549 + mistyrose: "#ffe4e1",
  550 + moccasin: "#ffe4b5",
  551 + navajowhite: "#ffdead",
  552 + navy: "#000080",
  553 + oldlace: "#fdf5e6",
  554 + olive: "#808000",
  555 + olivedrab: "#6b8e23",
  556 + orange: "#ffa500",
  557 + orangered: "#ff4500",
  558 + orchid: "#da70d6",
  559 + palegoldenrod: "#eee8aa",
  560 + palegreen: "#98fb98",
  561 + paleturquoise: "#afeeee",
  562 + palevioletred: "#db7093",
  563 + papayawhip: "#ffefd5",
  564 + peachpuff: "#ffdab9",
  565 + peru: "#cd853f",
  566 + pink: "#ffc0cb",
  567 + plum: "#dda0dd",
  568 + powderblue: "#b0e0e6",
  569 + purple: "#800080",
  570 + red: "#ff0000",
  571 + rosybrown: "#bc8f8f",
  572 + royalblue: "#4169e1",
  573 + saddlebrown: "#8b4513",
  574 + salmon: "#fa8072",
  575 + sandybrown: "#f4a460",
  576 + seagreen: "#2e8b57",
  577 + seashell: "#fff5ee",
  578 + sienna: "#a0522d",
  579 + silver: "#c0c0c0",
  580 + skyblue: "#87ceeb",
  581 + slateblue: "#6a5acd",
  582 + slategray: "#708090",
  583 + slategrey: "#708090",
  584 + snow: "#fffafa",
  585 + springgreen: "#00ff7f",
  586 + steelblue: "#4682b4",
  587 + tan: "#d2b48c",
  588 + teal: "#008080",
  589 + thistle: "#d8bfd8",
  590 + tomato: "#ff6347",
  591 + turquoise: "#40e0d0",
  592 + violet: "#ee82ee",
  593 + wheat: "#f5deb3",
  594 + white: "#ffffff",
  595 + whitesmoke: "#f5f5f5",
  596 + yellow: "#ffff00",
  597 + yellowgreen: "#9acd32"
  598 +};
  599 +
  600 +for (var x in d3_rgb_names) d3_rgb_names[x] = d3_rgb(d3_rgb_names[x]);
  601 +var d3_transform_stack = [];
  602 +
  603 +function d3_transform() {
  604 + var transform = {},
  605 + actions = [];
  606 +
  607 + // TODO reorder elements
  608 + // convenience method for replacing elements?
  609 + // how to insert new element at a given location?
  610 + // how to move elements around, sort, reverse or reorder?
  611 +
  612 + // TODO value transforms
  613 + // how to inspect current attr/style/text value from transform?
  614 + // perhaps push/pop values for temporary change (e.g., :hover)?
  615 + // this.value retrieves current attr / style / text? or this.value()?
  616 +
  617 + // TODO extensibility
  618 + // register hooks for transform extensibility outside the library?
  619 + // how to encapsulate higher level logic (e.g., bars, wedges, charts)?
  620 + // virtual nodes? map to canvas?
  621 +
  622 + // TODO composition
  623 + // transform.apply(nodes) to transform specific nodes? (set root context)
  624 + // transform.transform(transform) to chain transforms?
  625 +
  626 + // TODO selectors
  627 + // allow select / selectAll argument to be function
  628 + // allow select / selectAll argument to be node / nodes
  629 + // allow select / selectAll argument to be xpath
  630 + // allow selectParent?
  631 + // allow selectFirstChild, selectLastChild, selectChildren?
  632 + // allow selectNext, selectPrevious?
  633 +
  634 + // TODO performance
  635 + // dispatch to different impl based on ns.qualify, typeof v === "function", etc.
  636 +
  637 + // TODO transitions
  638 + // how to do staggered transition on line control points? (virtual nodes?)
  639 +
  640 + function transform_scope(parent, actions) {
  641 + var scope = Object.create(transform);
  642 +
  643 + scope.pop = parent;
  644 +
  645 + scope.data = function(v) {
  646 + var subscope, action = {
  647 + impl: d3_transform_data,
  648 + value: v,
  649 + actions: [],
  650 + enterActions: [],
  651 + exitActions: []
  652 + };
  653 + actions.push(action);
  654 + subscope = transform_scope(scope, action.actions);
  655 + subscope.enter = transform_scope(scope, action.enterActions);
  656 + subscope.exit = transform_scope(scope, action.exitActions);
  657 + subscope.key = function(n, v) {
  658 + action.key = {name: ns.qualify(n), value: v};
  659 + return subscope;
  660 + };
  661 + return subscope;
  662 + };
  663 +
  664 + scope.tweenData = function(v, t) {
  665 + actions.push({
  666 + impl: d3_transform_data_tween,
  667 + bind: d3_transform_data_tween_bind,
  668 + value: v,
  669 + tween: arguments.length < 2 ? d3.tween : t
  670 + });
  671 + return scope;
  672 + };
  673 +
  674 + scope.attr = function(n, v) {
  675 + actions.push({
  676 + impl: d3_transform_attr,
  677 + name: ns.qualify(n),
  678 + value: v
  679 + });
  680 + return scope;
  681 + };
  682 +
  683 + scope.tweenAttr = function(n, v, t) {
  684 + actions.push({
  685 + impl: d3_transform_attr_tween,
  686 + bind: d3_transform_attr_tween_bind,
  687 + name: ns.qualify(n),
  688 + key: "attr." + n,
  689 + value: v,
  690 + tween: arguments.length < 3 ? d3_tweenByName(n) : t
  691 + });
  692 + return scope;
  693 + };
  694 +
  695 + scope.style = function(n, v, p) {
  696 + actions.push({
  697 + impl: d3_transform_style,
  698 + name: n,
  699 + value: v,
  700 + priority: arguments.length < 3 ? null : p
  701 + });
  702 + return scope;
  703 + };
  704 +
  705 + scope.tweenStyle = function(n, v, p, t) {
  706 + actions.push({
  707 + impl: d3_transform_style_tween,
  708 + bind: d3_transform_style_tween_bind,
  709 + name: n,
  710 + key: "style." + n,
  711 + value: v,
  712 + priority: arguments.length < 3 ? null : p,
  713 + tween: arguments.length < 4 ? d3_tweenByName(n) : t
  714 + });
  715 + return scope;
  716 + };
  717 +
  718 + scope.add = function(n, v) {
  719 + var action = {
  720 + impl: d3_transform_add,
  721 + name: ns.qualify(n),
  722 + value: v,
  723 + actions: []
  724 + };
  725 + actions.push(action);
  726 + return transform_scope(scope, action.actions);
  727 + };
  728 +
  729 + scope.remove = function(s) {
  730 + actions.push({
  731 + impl: d3_transform_remove,
  732 + selector: s
  733 + });
  734 + return scope;
  735 + };
  736 +
  737 + scope.text = function(v) {
  738 + actions.push({
  739 + impl: d3_transform_text,
  740 + value: v
  741 + });
  742 + return scope;
  743 + };
  744 +
  745 + scope.on = function(t) {
  746 + var action = {
  747 + impl: d3_transform_on,
  748 + type: t,
  749 + actions: []
  750 + };
  751 + actions.push(action);
  752 + return transform_scope(scope, action.actions);
  753 + };
  754 +
  755 + scope.filter = function(f) {
  756 + var action = {
  757 + impl: d3_transform_filter,
  758 + filter: f,
  759 + actions: []
  760 + };
  761 + actions.push(action);
  762 + return transform_scope(scope, action.actions);
  763 + };
  764 +
  765 + scope.select = function(s) {
  766 + var action = {
  767 + impl: d3_transform_select,
  768 + selector: s,
  769 + actions: []
  770 + };
  771 + actions.push(action);
  772 + return transform_scope(scope, action.actions);
  773 + };
  774 +
  775 + scope.selectAll = function(s) {
  776 + var action = {
  777 + impl: d3_transform_select_all,
  778 + selector: s,
  779 + actions: []
  780 + };
  781 + actions.push(action);
  782 + return transform_scope(scope, action.actions);
  783 + };
  784 +
  785 + scope.transition = function() {
  786 + var subscope, action = {
  787 + impl: d3_transform_transition,
  788 + actions: [],
  789 + endActions: [],
  790 + ease: d3.ease("cubic-in-out"),
  791 + delay: 0,
  792 + duration: 250
  793 + };
  794 + actions.push(action);
  795 + subscope = transform_scope(scope, action.actions);
  796 + subscope.end = transform_scope(scope, action.endActions);
  797 + subscope.ease = function(x) {
  798 + action.ease = typeof x == "string" ? d3.ease(x) : x;
  799 + return subscope;
  800 + };
  801 + subscope.delay = function(x) {
  802 + action.delay = x;
  803 + return subscope;
  804 + };
  805 + subscope.duration = function(x) {
  806 + action.duration = x;
  807 + return subscope;
  808 + };
  809 + return subscope;
  810 + };
  811 +
  812 + return scope;
  813 + }
  814 +
  815 + transform.select = function(s) {
  816 + var action = {
  817 + impl: d3_transform_select,
  818 + selector: s,
  819 + actions: []
  820 + };
  821 + actions.push(action);
  822 + return transform_scope(transform, action.actions);
  823 + };
  824 +
  825 + transform.selectAll = function(s) {
  826 + var action = {
  827 + impl: d3_transform_select_all,
  828 + selector: s,
  829 + actions: []
  830 + };
  831 + actions.push(action);
  832 + return transform_scope(transform, action.actions);
  833 + };
  834 +
  835 + transform.apply = function() {
  836 + d3_transform_stack.unshift(null);
  837 + d3_transform_impl(actions, [{node: document, index: 0}]);
  838 + d3_transform_stack.shift();
  839 + return transform;
  840 + };
  841 +
  842 + return transform;
  843 +}
  844 +
  845 +function d3_transform_impl(actions, nodes) {
  846 + var n = actions.length,
  847 + i; // current index
  848 + for (i = 0; i < n; ++i) actions[i].impl(nodes, d3_transform_impl);
  849 +}
  850 +function d3_transform_add(nodes, pass) {
  851 + var m = nodes.length,
  852 + n = this.name,
  853 + childNodes = [],
  854 + i, // current index
  855 + o, // current node
  856 + c; // current child
  857 + if (n.local) {
  858 + for (i = 0; i < m; ++i) {
  859 + childNodes.push(c = Object.create(o = nodes[i]));
  860 + c.node = (c.parentNode = o.node).appendChild(document.createElementNS(n.space, n.local));
  861 + }
  862 + } else {
  863 + for (i = 0; i < m; ++i) {
  864 + childNodes.push(c = Object.create(o = nodes[i]));
  865 + c.node = (c.parentNode = o.node).appendChild(document.createElement(n));
  866 + }
  867 + }
  868 + pass(this.actions, childNodes);
  869 +}
  870 +function d3_transform_attr(nodes) {
  871 + var m = nodes.length,
  872 + n = this.name,
  873 + v = this.value,
  874 + i, // current index
  875 + o, // current node
  876 + x; // current value (for value functions)
  877 + if (n.local) {
  878 + if (v == null) {
  879 + for (i = 0; i < m; ++i) {
  880 + nodes[i].node.removeAttributeNS(n.space, n.local);
  881 + }
  882 + } else if (typeof v == "function") {
  883 + for (i = 0; i < m; ++i) {
  884 + d3_transform_stack[0] = (o = nodes[i]).data;
  885 + x = v.apply(o, d3_transform_stack);
  886 + x == null
  887 + ? o.node.removeAttributeNS(n.space, n.local)
  888 + : o.node.setAttributeNS(n.space, n.local, x);
  889 + }
  890 + } else {
  891 + for (i = 0; i < m; ++i) {
  892 + nodes[i].node.setAttributeNS(n.space, n.local, v);
  893 + }
  894 + }
  895 + } else if (v == null) {
  896 + for (i = 0; i < m; ++i) {
  897 + nodes[i].node.removeAttribute(n);
  898 + }
  899 + } else if (typeof v == "function") {
  900 + for (i = 0; i < m; ++i) {
  901 + d3_transform_stack[0] = (o = nodes[i]).data;
  902 + x = v.apply(o, d3_transform_stack);
  903 + x == null
  904 + ? o.node.removeAttribute(n)
  905 + : o.node.setAttribute(n, x);
  906 + }
  907 + } else {
  908 + for (i = 0; i < m; ++i) {
  909 + nodes[i].node.setAttribute(n, v);
  910 + }
  911 + }
  912 +}
  913 +
  914 +function d3_transform_attr_tween(nodes) {
  915 + var m = nodes.length,
  916 + n = this.name,
  917 + k = this.key,
  918 + i, // current index
  919 + o; // current node
  920 + if (n.local) {
  921 + for (i = 0; i < m; ++i) {
  922 + (o = nodes[i]).node.setAttributeNS(n.space, n.local, o.tween[k]());
  923 + }
  924 + } else {
  925 + for (i = 0; i < m; ++i) {
  926 + (o = nodes[i]).node.setAttribute(n, o.tween[k]());
  927 + }
  928 + }
  929 +}
  930 +
  931 +function d3_transform_attr_tween_bind(nodes) {
  932 + var m = nodes.length,
  933 + n = this.name,
  934 + k = this.key,
  935 + v = this.value,
  936 + T = this.tween,
  937 + i, // current index
  938 + o; // current node
  939 + if (n.local) {
  940 + if (typeof v === "function") {
  941 + for (i = 0; i < m; ++i) {
  942 + d3_transform_stack[0] = (o = nodes[i]).data;
  943 + o.tween[k] = T(o.node.getAttributeNS(n.local, n.space), v.apply(o, d3_transform_stack));
  944 + }
  945 + } else {
  946 + for (i = 0; i < m; ++i) {
  947 + (o = nodes[i]).tween[k] = T(o.node.getAttributeNS(n.local, n.space), v);
  948 + }
  949 + }
  950 + } else if (typeof v === "function") {
  951 + for (i = 0; i < m; ++i) {
  952 + d3_transform_stack[0] = (o = nodes[i]).data;
  953 + o.tween[k] = T(o.node.getAttribute(n), v.apply(o, d3_transform_stack));
  954 + }
  955 + } else {
  956 + for (i = 0; i < m; ++i) {
  957 + (o = nodes[i]).tween[k] = T(o.node.getAttribute(n), v);
  958 + }
  959 + }
  960 +}
  961 +function d3_transform_data(nodes, pass) {
  962 + var data = this.value,
  963 + m = nodes.length,
  964 + n, // data length
  965 + key = this.key,
  966 + kn, // key name
  967 + kv, // key value
  968 + k, // current key
  969 + i, // current index
  970 + j, // current index
  971 + d, // current datum
  972 + o, // current node
  973 + enterNodes = [],
  974 + updateNodes = [],
  975 + exitNodes = [],
  976 + nodesByKey, // map key -> node
  977 + dataByKey, // map key -> data
  978 + indexesByKey; // map key -> index
  979 +
  980 + if (typeof data == "function") {
  981 + d = d3_transform_stack.shift();
  982 + data = data.apply(null, d3_transform_stack);
  983 + d3_transform_stack.unshift(d);
  984 + }
  985 +
  986 + n = data.length;
  987 +
  988 + if (key) {
  989 + kn = key.name;
  990 + kv = key.value;
  991 + nodesByKey = {};
  992 + dataByKey = {};
  993 + indexesByKey = {};
  994 +
  995 + // compute map from key -> node
  996 + if (kn.local) {
  997 + for (i = 0; i < m; ++i) {
  998 + o = nodes[i].node;
  999 + if (o) {
  1000 + k = o.getAttributeNS(kn.space, kn.local);
  1001 + if (k != null) nodesByKey[k] = o;
  1002 + }
  1003 + }
  1004 + } else {
  1005 + for (i = 0; i < m; ++i) {
  1006 + o = nodes[i].node;
  1007 + if (o) {
  1008 + k = o.getAttribute(kn);
  1009 + if (k != null) nodesByKey[k] = o;
  1010 + }
  1011 + }
  1012 + }
  1013 +
  1014 + // compute map from key -> data
  1015 + for (i = 0; i < n; ++i) {
  1016 + d3_transform_stack[0] = d = data[i];
  1017 + k = kv.apply(null, d3_transform_stack);
  1018 + if (k != null) {
  1019 + dataByKey[k] = d;
  1020 + indexesByKey[k] = i;
  1021 + }
  1022 + }
  1023 +
  1024 + // compute entering and updating nodes
  1025 + for (k in dataByKey) {
  1026 + d = dataByKey[k];
  1027 + i = indexesByKey[k];
  1028 + if (o = nodesByKey[k]) {
  1029 + updateNodes.push({
  1030 + node: o,
  1031 + data: d,
  1032 + key: k,
  1033 + index: i
  1034 + });
  1035 + } else {
  1036 + enterNodes.push({
  1037 + node: nodes.parentNode,
  1038 + data: d,
  1039 + key: k,
  1040 + index: i
  1041 + });
  1042 + }
  1043 + }
  1044 +
  1045 + // compute exiting nodes
  1046 + for (k in nodesByKey) {
  1047 + if (!(k in dataByKey)) {
  1048 + exitNodes.push({node: nodesByKey[k]});
  1049 + }
  1050 + }
  1051 + } else {
  1052 + k = n < m ? n : m;
  1053 +
  1054 + // compute updating nodes
  1055 + for (i = 0; i < k; ++i) {
  1056 + (o = nodes[i]).data = data[i];
  1057 + if (o.node) {
  1058 + updateNodes.push(o);
  1059 + } else {
  1060 + o.node = o.parentNode;
  1061 + enterNodes.push(o);
  1062 + }
  1063 + }
  1064 +
  1065 + // compute entering nodes
  1066 + for (j = i; j < n; ++j) {
  1067 + enterNodes.push({
  1068 + node: nodes.parentNode,
  1069 + data: data[j],
  1070 + index: j
  1071 + });
  1072 + }
  1073 +
  1074 + // compute exiting nodes
  1075 + for (j = i; j < m; ++j) {
  1076 + exitNodes.push(nodes[j]);
  1077 + }
  1078 + }
  1079 +
  1080 + pass(this.enterActions, enterNodes);
  1081 + pass(this.actions, updateNodes);
  1082 + pass(this.exitActions, exitNodes);
  1083 +}
  1084 +
  1085 +function d3_transform_data_tween(nodes) {
  1086 + var m = nodes.length,
  1087 + i, // current index
  1088 + o; // current node
  1089 + for (i = 0; i < m; ++i) {
  1090 + (o = nodes[i]).data = o.tween.data();
  1091 + }
  1092 +}
  1093 +
  1094 +function d3_transform_data_tween_bind(nodes) {
  1095 + var m = nodes.length,
  1096 + v = this.value,
  1097 + T = this.tween,
  1098 + i, // current index
  1099 + o; // current node
  1100 + if (typeof v === "function") {
  1101 + for (i = 0; i < m; ++i) {
  1102 + (o = nodes[i]).tween.data = T(d3_transform_stack[0] = o.data, v.apply(o, d3_transform_stack));
  1103 + }
  1104 + } else {
  1105 + for (i = 0; i < m; ++i) {
  1106 + (o = nodes[i]).tween.data = T(o.data, v);
  1107 + }
  1108 + }
  1109 +}
  1110 +function d3_transform_remove(nodes) {
  1111 + var m = nodes.length,
  1112 + s = this.selector,
  1113 + r, // the selected nodes (for selectors)
  1114 + i, // current node index
  1115 + j, // current selector index
  1116 + k, // current selector length
  1117 + o; // current node to remove
  1118 + if (s == null) {
  1119 + for (i = 0; i < m; ++i) {
  1120 + o = nodes[i].node;
  1121 + o.parentNode.removeChild(o);
  1122 + }
  1123 + } else {
  1124 + for (i = 0; i < m; ++i) {
  1125 + r = nodes[i].node.querySelectorAll(s);
  1126 + for (j = 0, k = r.length; j < k; j++) {
  1127 + o = r[j];
  1128 + o.parentNode.removeChild(o);
  1129 + }
  1130 + }
  1131 + }
  1132 +}
  1133 +function d3_transform_on(nodes) {
  1134 + var actions = this.actions,
  1135 + n = actions.length,
  1136 + m = nodes.length,
  1137 + t = "on" + this.type,
  1138 + i = 0, // current index
  1139 + o, // curent node
  1140 + stack = d3_transform_stack.slice(); // stack snapshot
  1141 +
  1142 + if (n) {
  1143 + for (; i < m; ++i) {
  1144 + o = nodes[i];
  1145 + o.node[t] = bind([o]);
  1146 + }
  1147 + } else {
  1148 + for (; i < m; ++i) {
  1149 + nodes[i].node[t] = null;
  1150 + }
  1151 + }
  1152 +
  1153 + function bind(o) {
  1154 + return function(e) {
  1155 + var s = d3_transform_stack;
  1156 + try {
  1157 + d3_transform_stack = stack;
  1158 + d3.event = e;
  1159 + for (i = 0; i < n; ++i) actions[i].impl(o, d3_transform_impl);
  1160 + } finally {
  1161 + delete d3.event;
  1162 + d3_transform_stack = s;
  1163 + }
  1164 + };
  1165 + }
  1166 +}
  1167 +function d3_transform_filter(nodes, pass) {
  1168 + var filteredNodes = [],
  1169 + m = nodes.length,
  1170 + f = this.filter,
  1171 + i, // the node index
  1172 + o; // current item
  1173 + for (i = 0; i < m; ++i) {
  1174 + d3_transform_stack[0] = (o = nodes[i]).data;
  1175 + if (f.apply(o, d3_transform_stack)) filteredNodes.push(o);
  1176 + }
  1177 + pass(this.actions, filteredNodes);
  1178 +}
  1179 +d3.select = function(s) {
  1180 + return d3_transform().select(s);
  1181 +};
  1182 +
  1183 +function d3_transform_select(nodes, pass) {
  1184 + var selectedNodes = [],
  1185 + m = nodes.length,
  1186 + s = this.selector,
  1187 + i, // the node index
  1188 + o, // current item
  1189 + p, // current node
  1190 + c, // current selected item
  1191 + e; // current selected node
  1192 + for (i = 0; i < m; ++i) {
  1193 + e = (p = (o = nodes[i]).node).querySelector(s);
  1194 + if (e != null) {
  1195 + selectedNodes.push(c = Object.create(o));
  1196 + c.parentNode = p;
  1197 + c.node = e;
  1198 + }
  1199 + }
  1200 + pass(this.actions, selectedNodes);
  1201 +}
  1202 +d3.selectAll = function(s) {
  1203 + return d3_transform().selectAll(s);
  1204 +};
  1205 +
  1206 +function d3_transform_select_all(nodes, pass) {
  1207 + var m = nodes.length,
  1208 + s = this.selector,
  1209 + i, // the node index
  1210 + o, // the current node
  1211 + p; // the current node
  1212 + d3_transform_stack.unshift(null);
  1213 + for (i = 0; i < m; ++i) {
  1214 + d3_transform_stack[1] = (o = nodes[i]).data;
  1215 + pass(this.actions, d3_transform_nodes((p = o.node).querySelectorAll(s), p));
  1216 + }
  1217 + d3_transform_stack.shift();
  1218 +}
  1219 +
  1220 +function d3_transform_nodes(x, p) {
  1221 + var nodes = [],
  1222 + i = 0,
  1223 + n = x.length;
  1224 + nodes.parentNode = p;
  1225 + for (; i < n; i++) nodes.push({node: x[i], index: i});
  1226 + return nodes;
  1227 +}
  1228 +function d3_transform_style(nodes) {
  1229 + var m = nodes.length,
  1230 + n = this.name,
  1231 + v = this.value,
  1232 + p = this.priority,
  1233 + i, // current index
  1234 + o, // current node
  1235 + x; // current value (for value functions)
  1236 + if (v == null) {
  1237 + for (i = 0; i < m; ++i) {
  1238 + nodes[i].node.style.removeProperty(n);
  1239 + }
  1240 + } else if (typeof v == "function") {
  1241 + for (i = 0; i < m; ++i) {
  1242 + o = nodes[i];
  1243 + d3_transform_stack[0] = o.data;
  1244 + x = v.apply(o, d3_transform_stack);
  1245 + x == null
  1246 + ? o.node.style.removeProperty(n)
  1247 + : o.node.style.setProperty(n, x, p);
  1248 + }
  1249 + } else {
  1250 + for (i = 0; i < m; ++i) {
  1251 + nodes[i].node.style.setProperty(n, v, p);
  1252 + }
  1253 + }
  1254 +}
  1255 +
  1256 +function d3_transform_style_tween(nodes) {
  1257 + var m = nodes.length,
  1258 + n = this.name,
  1259 + k = this.key,
  1260 + p = this.priority,
  1261 + i, // current index
  1262 + o; // current node
  1263 + for (i = 0; i < m; ++i) {
  1264 + (o = nodes[i]).node.style.setProperty(n, o.tween[k](), p);
  1265 + }
  1266 +}
  1267 +
  1268 +function d3_transform_style_tween_bind(nodes) {
  1269 + var m = nodes.length,
  1270 + n = this.name,
  1271 + k = this.key,
  1272 + v = this.value,