integ/js/vs/lib/d3/d3.v2.js
changeset 28 84719280c84d
equal deleted inserted replaced
27:c21cffd36f98 28:84719280c84d
       
     1 (function(){if (!Date.now) Date.now = function() {
       
     2   return +new Date;
       
     3 };
       
     4 try {
       
     5   document.createElement("div").style.setProperty("opacity", 0, "");
       
     6 } catch (error) {
       
     7   var d3_style_prototype = CSSStyleDeclaration.prototype,
       
     8       d3_style_setProperty = d3_style_prototype.setProperty;
       
     9   d3_style_prototype.setProperty = function(name, value, priority) {
       
    10     d3_style_setProperty.call(this, name, value + "", priority);
       
    11   };
       
    12 }
       
    13 d3 = {version: "2.8.1"}; // semver
       
    14 function d3_class(ctor, properties) {
       
    15   try {
       
    16     for (var key in properties) {
       
    17       Object.defineProperty(ctor.prototype, key, {
       
    18         value: properties[key],
       
    19         enumerable: false
       
    20       });
       
    21     }
       
    22   } catch (e) {
       
    23     ctor.prototype = properties;
       
    24   }
       
    25 }
       
    26 var d3_array = d3_arraySlice; // conversion for NodeLists
       
    27 
       
    28 function d3_arrayCopy(pseudoarray) {
       
    29   var i = -1, n = pseudoarray.length, array = [];
       
    30   while (++i < n) array.push(pseudoarray[i]);
       
    31   return array;
       
    32 }
       
    33 
       
    34 function d3_arraySlice(pseudoarray) {
       
    35   return Array.prototype.slice.call(pseudoarray);
       
    36 }
       
    37 
       
    38 try {
       
    39   d3_array(document.documentElement.childNodes)[0].nodeType;
       
    40 } catch(e) {
       
    41   d3_array = d3_arrayCopy;
       
    42 }
       
    43 
       
    44 var d3_arraySubclass = [].__proto__?
       
    45 
       
    46 // Until ECMAScript supports array subclassing, prototype injection works well.
       
    47 function(array, prototype) {
       
    48   array.__proto__ = prototype;
       
    49 }:
       
    50 
       
    51 // And if your browser doesn't support __proto__, we'll use direct extension.
       
    52 function(array, prototype) {
       
    53   for (var property in prototype) array[property] = prototype[property];
       
    54 };
       
    55 d3.map = function(object) {
       
    56   var map = new d3_Map;
       
    57   for (var key in object) map.set(key, object[key]);
       
    58   return map;
       
    59 };
       
    60 
       
    61 function d3_Map() {}
       
    62 
       
    63 d3_class(d3_Map, {
       
    64   has: function(key) {
       
    65     return d3_map_prefix + key in this;
       
    66   },
       
    67   get: function(key) {
       
    68     return this[d3_map_prefix + key];
       
    69   },
       
    70   set: function(key, value) {
       
    71     return this[d3_map_prefix + key] = value;
       
    72   },
       
    73   remove: function(key) {
       
    74     key = d3_map_prefix + key;
       
    75     return key in this && delete this[key];
       
    76   },
       
    77   keys: function() {
       
    78     var keys = [];
       
    79     this.forEach(function(key) { keys.push(key); });
       
    80     return keys;
       
    81   },
       
    82   values: function() {
       
    83     var values = [];
       
    84     this.forEach(function(key, value) { values.push(value); });
       
    85     return values;
       
    86   },
       
    87   entries: function() {
       
    88     var entries = [];
       
    89     this.forEach(function(key, value) { entries.push({key: key, value: value}); });
       
    90     return entries;
       
    91   },
       
    92   forEach: function(f) {
       
    93     for (var key in this) {
       
    94       if (key.charCodeAt(0) === d3_map_prefixCode) {
       
    95         f.call(this, key.substring(1), this[key]);
       
    96       }
       
    97     }
       
    98   }
       
    99 });
       
   100 
       
   101 var d3_map_prefix = "\0", // prevent collision with built-ins
       
   102     d3_map_prefixCode = d3_map_prefix.charCodeAt(0);
       
   103 function d3_this() {
       
   104   return this;
       
   105 }
       
   106 d3.functor = function(v) {
       
   107   return typeof v === "function" ? v : function() { return v; };
       
   108 };
       
   109 // Copies a variable number of methods from source to target.
       
   110 d3.rebind = function(target, source) {
       
   111   var i = 1, n = arguments.length, method;
       
   112   while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);
       
   113   return target;
       
   114 };
       
   115 
       
   116 // Method is assumed to be a standard D3 getter-setter:
       
   117 // If passed with no arguments, gets the value.
       
   118 // If passed with arguments, sets the value and returns the target.
       
   119 function d3_rebind(target, source, method) {
       
   120   return function() {
       
   121     var value = method.apply(source, arguments);
       
   122     return arguments.length ? target : value;
       
   123   };
       
   124 }
       
   125 d3.ascending = function(a, b) {
       
   126   return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
       
   127 };
       
   128 d3.descending = function(a, b) {
       
   129   return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
       
   130 };
       
   131 d3.mean = function(array, f) {
       
   132   var n = array.length,
       
   133       a,
       
   134       m = 0,
       
   135       i = -1,
       
   136       j = 0;
       
   137   if (arguments.length === 1) {
       
   138     while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j;
       
   139   } else {
       
   140     while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j;
       
   141   }
       
   142   return j ? m : undefined;
       
   143 };
       
   144 d3.median = function(array, f) {
       
   145   if (arguments.length > 1) array = array.map(f);
       
   146   array = array.filter(d3_number);
       
   147   return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined;
       
   148 };
       
   149 d3.min = function(array, f) {
       
   150   var i = -1,
       
   151       n = array.length,
       
   152       a,
       
   153       b;
       
   154   if (arguments.length === 1) {
       
   155     while (++i < n && ((a = array[i]) == null || a != a)) a = undefined;
       
   156     while (++i < n) if ((b = array[i]) != null && a > b) a = b;
       
   157   } else {
       
   158     while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined;
       
   159     while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
       
   160   }
       
   161   return a;
       
   162 };
       
   163 d3.max = function(array, f) {
       
   164   var i = -1,
       
   165       n = array.length,
       
   166       a,
       
   167       b;
       
   168   if (arguments.length === 1) {
       
   169     while (++i < n && ((a = array[i]) == null || a != a)) a = undefined;
       
   170     while (++i < n) if ((b = array[i]) != null && b > a) a = b;
       
   171   } else {
       
   172     while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined;
       
   173     while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;
       
   174   }
       
   175   return a;
       
   176 };
       
   177 d3.extent = function(array, f) {
       
   178   var i = -1,
       
   179       n = array.length,
       
   180       a,
       
   181       b,
       
   182       c;
       
   183   if (arguments.length === 1) {
       
   184     while (++i < n && ((a = c = array[i]) == null || a != a)) a = c = undefined;
       
   185     while (++i < n) if ((b = array[i]) != null) {
       
   186       if (a > b) a = b;
       
   187       if (c < b) c = b;
       
   188     }
       
   189   } else {
       
   190     while (++i < n && ((a = c = f.call(array, array[i], i)) == null || a != a)) a = undefined;
       
   191     while (++i < n) if ((b = f.call(array, array[i], i)) != null) {
       
   192       if (a > b) a = b;
       
   193       if (c < b) c = b;
       
   194     }
       
   195   }
       
   196   return [a, c];
       
   197 };
       
   198 d3.random = {
       
   199   normal: function(mean, deviation) {
       
   200     if (arguments.length < 2) deviation = 1;
       
   201     if (arguments.length < 1) mean = 0;
       
   202     return function() {
       
   203       var x, y, r;
       
   204       do {
       
   205         x = Math.random() * 2 - 1;
       
   206         y = Math.random() * 2 - 1;
       
   207         r = x * x + y * y;
       
   208       } while (!r || r > 1);
       
   209       return mean + deviation * x * Math.sqrt(-2 * Math.log(r) / r);
       
   210     };
       
   211   }
       
   212 };
       
   213 function d3_number(x) {
       
   214   return x != null && !isNaN(x);
       
   215 }
       
   216 d3.sum = function(array, f) {
       
   217   var s = 0,
       
   218       n = array.length,
       
   219       a,
       
   220       i = -1;
       
   221 
       
   222   if (arguments.length === 1) {
       
   223     while (++i < n) if (!isNaN(a = +array[i])) s += a;
       
   224   } else {
       
   225     while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a;
       
   226   }
       
   227 
       
   228   return s;
       
   229 };
       
   230 // R-7 per <http://en.wikipedia.org/wiki/Quantile>
       
   231 d3.quantile = function(values, p) {
       
   232   var H = (values.length - 1) * p + 1,
       
   233       h = Math.floor(H),
       
   234       v = values[h - 1],
       
   235       e = H - h;
       
   236   return e ? v + e * (values[h] - v) : v;
       
   237 };
       
   238 d3.transpose = function(matrix) {
       
   239   return d3.zip.apply(d3, matrix);
       
   240 };
       
   241 d3.zip = function() {
       
   242   if (!(n = arguments.length)) return [];
       
   243   for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m;) {
       
   244     for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n;) {
       
   245       zip[j] = arguments[j][i];
       
   246     }
       
   247   }
       
   248   return zips;
       
   249 };
       
   250 
       
   251 function d3_zipLength(d) {
       
   252   return d.length;
       
   253 }
       
   254 d3.bisector = function(f) {
       
   255   return {
       
   256     left: function(a, x, lo, hi) {
       
   257       if (arguments.length < 3) lo = 0;
       
   258       if (arguments.length < 4) hi = a.length;
       
   259       while (lo < hi) {
       
   260         var mid = lo + hi >> 1;
       
   261         if (f.call(a, a[mid], mid) < x) lo = mid + 1;
       
   262         else hi = mid;
       
   263       }
       
   264       return lo;
       
   265     },
       
   266     right: function(a, x, lo, hi) {
       
   267       if (arguments.length < 3) lo = 0;
       
   268       if (arguments.length < 4) hi = a.length;
       
   269       while (lo < hi) {
       
   270         var mid = lo + hi >> 1;
       
   271         if (x < f.call(a, a[mid], mid)) hi = mid;
       
   272         else lo = mid + 1;
       
   273       }
       
   274       return lo;
       
   275     }
       
   276   };
       
   277 };
       
   278 
       
   279 var d3_bisector = d3.bisector(function(d) { return d; });
       
   280 d3.bisectLeft = d3_bisector.left;
       
   281 d3.bisect = d3.bisectRight = d3_bisector.right;
       
   282 d3.first = function(array, f) {
       
   283   var i = 0,
       
   284       n = array.length,
       
   285       a = array[0],
       
   286       b;
       
   287   if (arguments.length === 1) f = d3.ascending;
       
   288   while (++i < n) {
       
   289     if (f.call(array, a, b = array[i]) > 0) {
       
   290       a = b;
       
   291     }
       
   292   }
       
   293   return a;
       
   294 };
       
   295 d3.last = function(array, f) {
       
   296   var i = 0,
       
   297       n = array.length,
       
   298       a = array[0],
       
   299       b;
       
   300   if (arguments.length === 1) f = d3.ascending;
       
   301   while (++i < n) {
       
   302     if (f.call(array, a, b = array[i]) <= 0) {
       
   303       a = b;
       
   304     }
       
   305   }
       
   306   return a;
       
   307 };
       
   308 d3.nest = function() {
       
   309   var nest = {},
       
   310       keys = [],
       
   311       sortKeys = [],
       
   312       sortValues,
       
   313       rollup;
       
   314 
       
   315   function map(array, depth) {
       
   316     if (depth >= keys.length) return rollup
       
   317         ? rollup.call(nest, array) : (sortValues
       
   318         ? array.sort(sortValues)
       
   319         : array);
       
   320 
       
   321     var i = -1,
       
   322         n = array.length,
       
   323         key = keys[depth++],
       
   324         keyValue,
       
   325         object,
       
   326         valuesByKey = new d3_Map,
       
   327         values,
       
   328         o = {};
       
   329 
       
   330     while (++i < n) {
       
   331       if (values = valuesByKey.get(keyValue = key(object = array[i]))) {
       
   332         values.push(object);
       
   333       } else {
       
   334         valuesByKey.set(keyValue, [object]);
       
   335       }
       
   336     }
       
   337 
       
   338     valuesByKey.forEach(function(keyValue) {
       
   339       o[keyValue] = map(valuesByKey.get(keyValue), depth);
       
   340     });
       
   341 
       
   342     return o;
       
   343   }
       
   344 
       
   345   function entries(map, depth) {
       
   346     if (depth >= keys.length) return map;
       
   347 
       
   348     var a = [],
       
   349         sortKey = sortKeys[depth++],
       
   350         key;
       
   351 
       
   352     for (key in map) {
       
   353       a.push({key: key, values: entries(map[key], depth)});
       
   354     }
       
   355 
       
   356     if (sortKey) a.sort(function(a, b) {
       
   357       return sortKey(a.key, b.key);
       
   358     });
       
   359 
       
   360     return a;
       
   361   }
       
   362 
       
   363   nest.map = function(array) {
       
   364     return map(array, 0);
       
   365   };
       
   366 
       
   367   nest.entries = function(array) {
       
   368     return entries(map(array, 0), 0);
       
   369   };
       
   370 
       
   371   nest.key = function(d) {
       
   372     keys.push(d);
       
   373     return nest;
       
   374   };
       
   375 
       
   376   // Specifies the order for the most-recently specified key.
       
   377   // Note: only applies to entries. Map keys are unordered!
       
   378   nest.sortKeys = function(order) {
       
   379     sortKeys[keys.length - 1] = order;
       
   380     return nest;
       
   381   };
       
   382 
       
   383   // Specifies the order for leaf values.
       
   384   // Applies to both maps and entries array.
       
   385   nest.sortValues = function(order) {
       
   386     sortValues = order;
       
   387     return nest;
       
   388   };
       
   389 
       
   390   nest.rollup = function(f) {
       
   391     rollup = f;
       
   392     return nest;
       
   393   };
       
   394 
       
   395   return nest;
       
   396 };
       
   397 d3.keys = function(map) {
       
   398   var keys = [];
       
   399   for (var key in map) keys.push(key);
       
   400   return keys;
       
   401 };
       
   402 d3.values = function(map) {
       
   403   var values = [];
       
   404   for (var key in map) values.push(map[key]);
       
   405   return values;
       
   406 };
       
   407 d3.entries = function(map) {
       
   408   var entries = [];
       
   409   for (var key in map) entries.push({key: key, value: map[key]});
       
   410   return entries;
       
   411 };
       
   412 d3.permute = function(array, indexes) {
       
   413   var permutes = [],
       
   414       i = -1,
       
   415       n = indexes.length;
       
   416   while (++i < n) permutes[i] = array[indexes[i]];
       
   417   return permutes;
       
   418 };
       
   419 d3.merge = function(arrays) {
       
   420   return Array.prototype.concat.apply([], arrays);
       
   421 };
       
   422 d3.split = function(array, f) {
       
   423   var arrays = [],
       
   424       values = [],
       
   425       value,
       
   426       i = -1,
       
   427       n = array.length;
       
   428   if (arguments.length < 2) f = d3_splitter;
       
   429   while (++i < n) {
       
   430     if (f.call(values, value = array[i], i)) {
       
   431       values = [];
       
   432     } else {
       
   433       if (!values.length) arrays.push(values);
       
   434       values.push(value);
       
   435     }
       
   436   }
       
   437   return arrays;
       
   438 };
       
   439 
       
   440 function d3_splitter(d) {
       
   441   return d == null;
       
   442 }
       
   443 function d3_collapse(s) {
       
   444   return s.replace(/(^\s+)|(\s+$)/g, "").replace(/\s+/g, " ");
       
   445 }
       
   446 d3.range = function(start, stop, step) {
       
   447   if (arguments.length < 3) {
       
   448     step = 1;
       
   449     if (arguments.length < 2) {
       
   450       stop = start;
       
   451       start = 0;
       
   452     }
       
   453   }
       
   454   if ((stop - start) / step === Infinity) throw new Error("infinite range");
       
   455   var range = [],
       
   456        k = d3_range_integerScale(Math.abs(step)),
       
   457        i = -1,
       
   458        j;
       
   459   start *= k, stop *= k, step *= k;
       
   460   if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k);
       
   461   else while ((j = start + step * ++i) < stop) range.push(j / k);
       
   462   return range;
       
   463 };
       
   464 
       
   465 function d3_range_integerScale(x) {
       
   466   var k = 1;
       
   467   while (x * k % 1) k *= 10;
       
   468   return k;
       
   469 }
       
   470 d3.requote = function(s) {
       
   471   return s.replace(d3_requote_re, "\\$&");
       
   472 };
       
   473 
       
   474 var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
       
   475 d3.round = function(x, n) {
       
   476   return n
       
   477       ? Math.round(x * (n = Math.pow(10, n))) / n
       
   478       : Math.round(x);
       
   479 };
       
   480 d3.xhr = function(url, mime, callback) {
       
   481   var req = new XMLHttpRequest;
       
   482   if (arguments.length < 3) callback = mime, mime = null;
       
   483   else if (mime && req.overrideMimeType) req.overrideMimeType(mime);
       
   484   req.open("GET", url, true);
       
   485   if (mime) req.setRequestHeader("Accept", mime);
       
   486   req.onreadystatechange = function() {
       
   487     if (req.readyState === 4) callback(req.status < 300 ? req : null);
       
   488   };
       
   489   req.send(null);
       
   490 };
       
   491 d3.text = function(url, mime, callback) {
       
   492   function ready(req) {
       
   493     callback(req && req.responseText);
       
   494   }
       
   495   if (arguments.length < 3) {
       
   496     callback = mime;
       
   497     mime = null;
       
   498   }
       
   499   d3.xhr(url, mime, ready);
       
   500 };
       
   501 d3.json = function(url, callback) {
       
   502   d3.text(url, "application/json", function(text) {
       
   503     callback(text ? JSON.parse(text) : null);
       
   504   });
       
   505 };
       
   506 d3.html = function(url, callback) {
       
   507   d3.text(url, "text/html", function(text) {
       
   508     if (text != null) { // Treat empty string as valid HTML.
       
   509       var range = document.createRange();
       
   510       range.selectNode(document.body);
       
   511       text = range.createContextualFragment(text);
       
   512     }
       
   513     callback(text);
       
   514   });
       
   515 };
       
   516 d3.xml = function(url, mime, callback) {
       
   517   function ready(req) {
       
   518     callback(req && req.responseXML);
       
   519   }
       
   520   if (arguments.length < 3) {
       
   521     callback = mime;
       
   522     mime = null;
       
   523   }
       
   524   d3.xhr(url, mime, ready);
       
   525 };
       
   526 var d3_nsPrefix = {
       
   527   svg: "http://www.w3.org/2000/svg",
       
   528   xhtml: "http://www.w3.org/1999/xhtml",
       
   529   xlink: "http://www.w3.org/1999/xlink",
       
   530   xml: "http://www.w3.org/XML/1998/namespace",
       
   531   xmlns: "http://www.w3.org/2000/xmlns/"
       
   532 };
       
   533 
       
   534 d3.ns = {
       
   535   prefix: d3_nsPrefix,
       
   536   qualify: function(name) {
       
   537     var i = name.indexOf(":"),
       
   538         prefix = name;
       
   539     if (i >= 0) {
       
   540       prefix = name.substring(0, i);
       
   541       name = name.substring(i + 1);
       
   542     }
       
   543     return d3_nsPrefix.hasOwnProperty(prefix)
       
   544         ? {space: d3_nsPrefix[prefix], local: name}
       
   545         : name;
       
   546   }
       
   547 };
       
   548 d3.dispatch = function() {
       
   549   var dispatch = new d3_dispatch,
       
   550       i = -1,
       
   551       n = arguments.length;
       
   552   while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
       
   553   return dispatch;
       
   554 };
       
   555 
       
   556 function d3_dispatch() {}
       
   557 
       
   558 d3_dispatch.prototype.on = function(type, listener) {
       
   559   var i = type.indexOf("."),
       
   560       name = "";
       
   561 
       
   562   // Extract optional namespace, e.g., "click.foo"
       
   563   if (i > 0) {
       
   564     name = type.substring(i + 1);
       
   565     type = type.substring(0, i);
       
   566   }
       
   567 
       
   568   return arguments.length < 2
       
   569       ? this[type].on(name)
       
   570       : this[type].on(name, listener);
       
   571 };
       
   572 
       
   573 function d3_dispatch_event(dispatch) {
       
   574   var listeners = [],
       
   575       listenerByName = new d3_Map;
       
   576 
       
   577   function event() {
       
   578     var z = listeners, // defensive reference
       
   579         i = -1,
       
   580         n = z.length,
       
   581         l;
       
   582     while (++i < n) if (l = z[i].on) l.apply(this, arguments);
       
   583     return dispatch;
       
   584   }
       
   585 
       
   586   event.on = function(name, listener) {
       
   587     var l = listenerByName.get(name),
       
   588         i;
       
   589 
       
   590     // return the current listener, if any
       
   591     if (arguments.length < 2) return l && l.on;
       
   592 
       
   593     // remove the old listener, if any (with copy-on-write)
       
   594     if (l) {
       
   595       l.on = null;
       
   596       listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1));
       
   597       listenerByName.remove(name);
       
   598     }
       
   599 
       
   600     // add the new listener, if any
       
   601     if (listener) listeners.push(listenerByName.set(name, {on: listener}));
       
   602 
       
   603     return dispatch;
       
   604   };
       
   605 
       
   606   return event;
       
   607 }
       
   608 // TODO align
       
   609 d3.format = function(specifier) {
       
   610   var match = d3_format_re.exec(specifier),
       
   611       fill = match[1] || " ",
       
   612       sign = match[3] || "",
       
   613       zfill = match[5],
       
   614       width = +match[6],
       
   615       comma = match[7],
       
   616       precision = match[8],
       
   617       type = match[9],
       
   618       scale = 1,
       
   619       suffix = "",
       
   620       integer = false;
       
   621 
       
   622   if (precision) precision = +precision.substring(1);
       
   623 
       
   624   if (zfill) {
       
   625     fill = "0"; // TODO align = "=";
       
   626     if (comma) width -= Math.floor((width - 1) / 4);
       
   627   }
       
   628 
       
   629   switch (type) {
       
   630     case "n": comma = true; type = "g"; break;
       
   631     case "%": scale = 100; suffix = "%"; type = "f"; break;
       
   632     case "p": scale = 100; suffix = "%"; type = "r"; break;
       
   633     case "d": integer = true; precision = 0; break;
       
   634     case "s": scale = -1; type = "r"; break;
       
   635   }
       
   636 
       
   637   // If no precision is specified for r, fallback to general notation.
       
   638   if (type == "r" && !precision) type = "g";
       
   639 
       
   640   type = d3_format_types.get(type) || d3_format_typeDefault;
       
   641 
       
   642   return function(value) {
       
   643 
       
   644     // Return the empty string for floats formatted as ints.
       
   645     if (integer && (value % 1)) return "";
       
   646 
       
   647     // Convert negative to positive, and record the sign prefix.
       
   648     var negative = (value < 0) && (value = -value) ? "\u2212" : sign;
       
   649 
       
   650     // Apply the scale, computing it from the value's exponent for si format.
       
   651     if (scale < 0) {
       
   652       var prefix = d3.formatPrefix(value, precision);
       
   653       value *= prefix.scale;
       
   654       suffix = prefix.symbol;
       
   655     } else {
       
   656       value *= scale;
       
   657     }
       
   658 
       
   659     // Convert to the desired precision.
       
   660     value = type(value, precision);
       
   661 
       
   662     // If the fill character is 0, the sign and group is applied after the fill.
       
   663     if (zfill) {
       
   664       var length = value.length + negative.length;
       
   665       if (length < width) value = new Array(width - length + 1).join(fill) + value;
       
   666       if (comma) value = d3_format_group(value);
       
   667       value = negative + value;
       
   668     }
       
   669 
       
   670     // Otherwise (e.g., space-filling), the sign and group is applied before.
       
   671     else {
       
   672       if (comma) value = d3_format_group(value);
       
   673       value = negative + value;
       
   674       var length = value.length;
       
   675       if (length < width) value = new Array(width - length + 1).join(fill) + value;
       
   676     }
       
   677 
       
   678     return value + suffix;
       
   679   };
       
   680 };
       
   681 
       
   682 // [[fill]align][sign][#][0][width][,][.precision][type]
       
   683 var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/;
       
   684 
       
   685 var d3_format_types = d3.map({
       
   686   g: function(x, p) { return x.toPrecision(p); },
       
   687   e: function(x, p) { return x.toExponential(p); },
       
   688   f: function(x, p) { return x.toFixed(p); },
       
   689   r: function(x, p) { return d3.round(x, p = d3_format_precision(x, p)).toFixed(Math.max(0, Math.min(20, p))); }
       
   690 });
       
   691 
       
   692 function d3_format_precision(x, p) {
       
   693   return p - (x ? 1 + Math.floor(Math.log(x + Math.pow(10, 1 + Math.floor(Math.log(x) / Math.LN10) - p)) / Math.LN10) : 1);
       
   694 }
       
   695 
       
   696 function d3_format_typeDefault(x) {
       
   697   return x + "";
       
   698 }
       
   699 
       
   700 // Apply comma grouping for thousands.
       
   701 function d3_format_group(value) {
       
   702   var i = value.lastIndexOf("."),
       
   703       f = i >= 0 ? value.substring(i) : (i = value.length, ""),
       
   704       t = [];
       
   705   while (i > 0) t.push(value.substring(i -= 3, i + 3));
       
   706   return t.reverse().join(",") + f;
       
   707 }
       
   708 var d3_formatPrefixes = ["y","z","a","f","p","n","μ","m","","k","M","G","T","P","E","Z","Y"].map(d3_formatPrefix);
       
   709 
       
   710 d3.formatPrefix = function(value, precision) {
       
   711   var i = 0;
       
   712   if (value) {
       
   713     if (value < 0) value *= -1;
       
   714     if (precision) value = d3.round(value, d3_format_precision(value, precision));
       
   715     i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10);
       
   716     i = Math.max(-24, Math.min(24, Math.floor((i <= 0 ? i + 1 : i - 1) / 3) * 3));
       
   717   }
       
   718   return d3_formatPrefixes[8 + i / 3];
       
   719 };
       
   720 
       
   721 function d3_formatPrefix(d, i) {
       
   722   return {
       
   723     scale: Math.pow(10, (8 - i) * 3),
       
   724     symbol: d
       
   725   };
       
   726 }
       
   727 
       
   728 /*
       
   729  * TERMS OF USE - EASING EQUATIONS
       
   730  *
       
   731  * Open source under the BSD License.
       
   732  *
       
   733  * Copyright 2001 Robert Penner
       
   734  * All rights reserved.
       
   735  *
       
   736  * Redistribution and use in source and binary forms, with or without
       
   737  * modification, are permitted provided that the following conditions are met:
       
   738  *
       
   739  * - Redistributions of source code must retain the above copyright notice, this
       
   740  *   list of conditions and the following disclaimer.
       
   741  *
       
   742  * - Redistributions in binary form must reproduce the above copyright notice,
       
   743  *   this list of conditions and the following disclaimer in the documentation
       
   744  *   and/or other materials provided with the distribution.
       
   745  *
       
   746  * - Neither the name of the author nor the names of contributors may be used to
       
   747  *   endorse or promote products derived from this software without specific
       
   748  *   prior written permission.
       
   749  *
       
   750  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
       
   751  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
   752  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
   753  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
       
   754  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
       
   755  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
       
   756  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
       
   757  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
       
   758  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
       
   759  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
       
   760  * POSSIBILITY OF SUCH DAMAGE.
       
   761  */
       
   762 
       
   763 var d3_ease_quad = d3_ease_poly(2),
       
   764     d3_ease_cubic = d3_ease_poly(3),
       
   765     d3_ease_default = function() { return d3_ease_identity; };
       
   766 
       
   767 var d3_ease = d3.map({
       
   768   linear: d3_ease_default,
       
   769   poly: d3_ease_poly,
       
   770   quad: function() { return d3_ease_quad; },
       
   771   cubic: function() { return d3_ease_cubic; },
       
   772   sin: function() { return d3_ease_sin; },
       
   773   exp: function() { return d3_ease_exp; },
       
   774   circle: function() { return d3_ease_circle; },
       
   775   elastic: d3_ease_elastic,
       
   776   back: d3_ease_back,
       
   777   bounce: function() { return d3_ease_bounce; }
       
   778 });
       
   779 
       
   780 var d3_ease_mode = d3.map({
       
   781   "in": d3_ease_identity,
       
   782   "out": d3_ease_reverse,
       
   783   "in-out": d3_ease_reflect,
       
   784   "out-in": function(f) { return d3_ease_reflect(d3_ease_reverse(f)); }
       
   785 });
       
   786 
       
   787 d3.ease = function(name) {
       
   788   var i = name.indexOf("-"),
       
   789       t = i >= 0 ? name.substring(0, i) : name,
       
   790       m = i >= 0 ? name.substring(i + 1) : "in";
       
   791   t = d3_ease.get(t) || d3_ease_default;
       
   792   m = d3_ease_mode.get(m) || d3_ease_identity;
       
   793   return d3_ease_clamp(m(t.apply(null, Array.prototype.slice.call(arguments, 1))));
       
   794 };
       
   795 
       
   796 function d3_ease_clamp(f) {
       
   797   return function(t) {
       
   798     return t <= 0 ? 0 : t >= 1 ? 1 : f(t);
       
   799   };
       
   800 }
       
   801 
       
   802 function d3_ease_reverse(f) {
       
   803   return function(t) {
       
   804     return 1 - f(1 - t);
       
   805   };
       
   806 }
       
   807 
       
   808 function d3_ease_reflect(f) {
       
   809   return function(t) {
       
   810     return .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t)));
       
   811   };
       
   812 }
       
   813 
       
   814 function d3_ease_identity(t) {
       
   815   return t;
       
   816 }
       
   817 
       
   818 function d3_ease_poly(e) {
       
   819   return function(t) {
       
   820     return Math.pow(t, e);
       
   821   };
       
   822 }
       
   823 
       
   824 function d3_ease_sin(t) {
       
   825   return 1 - Math.cos(t * Math.PI / 2);
       
   826 }
       
   827 
       
   828 function d3_ease_exp(t) {
       
   829   return Math.pow(2, 10 * (t - 1));
       
   830 }
       
   831 
       
   832 function d3_ease_circle(t) {
       
   833   return 1 - Math.sqrt(1 - t * t);
       
   834 }
       
   835 
       
   836 function d3_ease_elastic(a, p) {
       
   837   var s;
       
   838   if (arguments.length < 2) p = 0.45;
       
   839   if (arguments.length < 1) { a = 1; s = p / 4; }
       
   840   else s = p / (2 * Math.PI) * Math.asin(1 / a);
       
   841   return function(t) {
       
   842     return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * Math.PI / p);
       
   843   };
       
   844 }
       
   845 
       
   846 function d3_ease_back(s) {
       
   847   if (!s) s = 1.70158;
       
   848   return function(t) {
       
   849     return t * t * ((s + 1) * t - s);
       
   850   };
       
   851 }
       
   852 
       
   853 function d3_ease_bounce(t) {
       
   854   return t < 1 / 2.75 ? 7.5625 * t * t
       
   855       : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75
       
   856       : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375
       
   857       : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
       
   858 }
       
   859 d3.event = null;
       
   860 
       
   861 function d3_eventCancel() {
       
   862   d3.event.stopPropagation();
       
   863   d3.event.preventDefault();
       
   864 }
       
   865 
       
   866 function d3_eventSource() {
       
   867   var e = d3.event, s;
       
   868   while (s = e.sourceEvent) e = s;
       
   869   return e;
       
   870 }
       
   871 
       
   872 // Like d3.dispatch, but for custom events abstracting native UI events. These
       
   873 // events have a target component (such as a brush), a target element (such as
       
   874 // the svg:g element containing the brush) and the standard arguments `d` (the
       
   875 // target element's data) and `i` (the selection index of the target element).
       
   876 function d3_eventDispatch(target) {
       
   877   var dispatch = new d3_dispatch,
       
   878       i = 0,
       
   879       n = arguments.length;
       
   880 
       
   881   while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
       
   882 
       
   883   // Creates a dispatch context for the specified `thiz` (typically, the target
       
   884   // DOM element that received the source event) and `argumentz` (typically, the
       
   885   // data `d` and index `i` of the target element). The returned function can be
       
   886   // used to dispatch an event to any registered listeners; the function takes a
       
   887   // single argument as input, being the event to dispatch. The event must have
       
   888   // a "type" attribute which corresponds to a type registered in the
       
   889   // constructor. This context will automatically populate the "sourceEvent" and
       
   890   // "target" attributes of the event, as well as setting the `d3.event` global
       
   891   // for the duration of the notification.
       
   892   dispatch.of = function(thiz, argumentz) {
       
   893     return function(e1) {
       
   894       try {
       
   895         var e0 =
       
   896         e1.sourceEvent = d3.event;
       
   897         e1.target = target;
       
   898         d3.event = e1;
       
   899         dispatch[e1.type].apply(thiz, argumentz);
       
   900       } finally {
       
   901         d3.event = e0;
       
   902       }
       
   903     };
       
   904   };
       
   905 
       
   906   return dispatch;
       
   907 }
       
   908 d3.interpolate = function(a, b) {
       
   909   var i = d3.interpolators.length, f;
       
   910   while (--i >= 0 && !(f = d3.interpolators[i](a, b)));
       
   911   return f;
       
   912 };
       
   913 
       
   914 d3.interpolateNumber = function(a, b) {
       
   915   b -= a;
       
   916   return function(t) { return a + b * t; };
       
   917 };
       
   918 
       
   919 d3.interpolateRound = function(a, b) {
       
   920   b -= a;
       
   921   return function(t) { return Math.round(a + b * t); };
       
   922 };
       
   923 
       
   924 d3.interpolateString = function(a, b) {
       
   925   var m, // current match
       
   926       i, // current index
       
   927       j, // current index (for coallescing)
       
   928       s0 = 0, // start index of current string prefix
       
   929       s1 = 0, // end index of current string prefix
       
   930       s = [], // string constants and placeholders
       
   931       q = [], // number interpolators
       
   932       n, // q.length
       
   933       o;
       
   934 
       
   935   // Reset our regular expression!
       
   936   d3_interpolate_number.lastIndex = 0;
       
   937 
       
   938   // Find all numbers in b.
       
   939   for (i = 0; m = d3_interpolate_number.exec(b); ++i) {
       
   940     if (m.index) s.push(b.substring(s0, s1 = m.index));
       
   941     q.push({i: s.length, x: m[0]});
       
   942     s.push(null);
       
   943     s0 = d3_interpolate_number.lastIndex;
       
   944   }
       
   945   if (s0 < b.length) s.push(b.substring(s0));
       
   946 
       
   947   // Find all numbers in a.
       
   948   for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) {
       
   949     o = q[i];
       
   950     if (o.x == m[0]) { // The numbers match, so coallesce.
       
   951       if (o.i) {
       
   952         if (s[o.i + 1] == null) { // This match is followed by another number.
       
   953           s[o.i - 1] += o.x;
       
   954           s.splice(o.i, 1);
       
   955           for (j = i + 1; j < n; ++j) q[j].i--;
       
   956         } else { // This match is followed by a string, so coallesce twice.
       
   957           s[o.i - 1] += o.x + s[o.i + 1];
       
   958           s.splice(o.i, 2);
       
   959           for (j = i + 1; j < n; ++j) q[j].i -= 2;
       
   960         }
       
   961       } else {
       
   962           if (s[o.i + 1] == null) { // This match is followed by another number.
       
   963           s[o.i] = o.x;
       
   964         } else { // This match is followed by a string, so coallesce twice.
       
   965           s[o.i] = o.x + s[o.i + 1];
       
   966           s.splice(o.i + 1, 1);
       
   967           for (j = i + 1; j < n; ++j) q[j].i--;
       
   968         }
       
   969       }
       
   970       q.splice(i, 1);
       
   971       n--;
       
   972       i--;
       
   973     } else {
       
   974       o.x = d3.interpolateNumber(parseFloat(m[0]), parseFloat(o.x));
       
   975     }
       
   976   }
       
   977 
       
   978   // Remove any numbers in b not found in a.
       
   979   while (i < n) {
       
   980     o = q.pop();
       
   981     if (s[o.i + 1] == null) { // This match is followed by another number.
       
   982       s[o.i] = o.x;
       
   983     } else { // This match is followed by a string, so coallesce twice.
       
   984       s[o.i] = o.x + s[o.i + 1];
       
   985       s.splice(o.i + 1, 1);
       
   986     }
       
   987     n--;
       
   988   }
       
   989 
       
   990   // Special optimization for only a single match.
       
   991   if (s.length === 1) {
       
   992     return s[0] == null ? q[0].x : function() { return b; };
       
   993   }
       
   994 
       
   995   // Otherwise, interpolate each of the numbers and rejoin the string.
       
   996   return function(t) {
       
   997     for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t);
       
   998     return s.join("");
       
   999   };
       
  1000 };
       
  1001 
       
  1002 d3.interpolateTransform = function(a, b) {
       
  1003   var s = [], // string constants and placeholders
       
  1004       q = [], // number interpolators
       
  1005       n,
       
  1006       A = d3.transform(a),
       
  1007       B = d3.transform(b),
       
  1008       ta = A.translate,
       
  1009       tb = B.translate,
       
  1010       ra = A.rotate,
       
  1011       rb = B.rotate,
       
  1012       wa = A.skew,
       
  1013       wb = B.skew,
       
  1014       ka = A.scale,
       
  1015       kb = B.scale;
       
  1016 
       
  1017   if (ta[0] != tb[0] || ta[1] != tb[1]) {
       
  1018     s.push("translate(", null, ",", null, ")");
       
  1019     q.push({i: 1, x: d3.interpolateNumber(ta[0], tb[0])}, {i: 3, x: d3.interpolateNumber(ta[1], tb[1])});
       
  1020   } else if (tb[0] || tb[1]) {
       
  1021     s.push("translate(" + tb + ")");
       
  1022   } else {
       
  1023     s.push("");
       
  1024   }
       
  1025 
       
  1026   if (ra != rb) {
       
  1027     q.push({i: s.push(s.pop() + "rotate(", null, ")") - 2, x: d3.interpolateNumber(ra, rb)});
       
  1028   } else if (rb) {
       
  1029     s.push(s.pop() + "rotate(" + rb + ")");
       
  1030   }
       
  1031 
       
  1032   if (wa != wb) {
       
  1033     q.push({i: s.push(s.pop() + "skewX(", null, ")") - 2, x: d3.interpolateNumber(wa, wb)});
       
  1034   } else if (wb) {
       
  1035     s.push(s.pop() + "skewX(" + wb + ")");
       
  1036   }
       
  1037 
       
  1038   if (ka[0] != kb[0] || ka[1] != kb[1]) {
       
  1039     n = s.push(s.pop() + "scale(", null, ",", null, ")");
       
  1040     q.push({i: n - 4, x: d3.interpolateNumber(ka[0], kb[0])}, {i: n - 2, x: d3.interpolateNumber(ka[1], kb[1])});
       
  1041   } else if (kb[0] != 1 || kb[1] != 1) {
       
  1042     s.push(s.pop() + "scale(" + kb + ")");
       
  1043   }
       
  1044 
       
  1045   n = q.length;
       
  1046   return function(t) {
       
  1047     var i = -1, o;
       
  1048     while (++i < n) s[(o = q[i]).i] = o.x(t);
       
  1049     return s.join("");
       
  1050   };
       
  1051 };
       
  1052 
       
  1053 d3.interpolateRgb = function(a, b) {
       
  1054   a = d3.rgb(a);
       
  1055   b = d3.rgb(b);
       
  1056   var ar = a.r,
       
  1057       ag = a.g,
       
  1058       ab = a.b,
       
  1059       br = b.r - ar,
       
  1060       bg = b.g - ag,
       
  1061       bb = b.b - ab;
       
  1062   return function(t) {
       
  1063     return "#"
       
  1064         + d3_rgb_hex(Math.round(ar + br * t))
       
  1065         + d3_rgb_hex(Math.round(ag + bg * t))
       
  1066         + d3_rgb_hex(Math.round(ab + bb * t));
       
  1067   };
       
  1068 };
       
  1069 
       
  1070 // interpolates HSL space, but outputs RGB string (for compatibility)
       
  1071 d3.interpolateHsl = function(a, b) {
       
  1072   a = d3.hsl(a);
       
  1073   b = d3.hsl(b);
       
  1074   var h0 = a.h,
       
  1075       s0 = a.s,
       
  1076       l0 = a.l,
       
  1077       h1 = b.h - h0,
       
  1078       s1 = b.s - s0,
       
  1079       l1 = b.l - l0;
       
  1080   return function(t) {
       
  1081     return d3_hsl_rgb(h0 + h1 * t, s0 + s1 * t, l0 + l1 * t).toString();
       
  1082   };
       
  1083 };
       
  1084 
       
  1085 d3.interpolateArray = function(a, b) {
       
  1086   var x = [],
       
  1087       c = [],
       
  1088       na = a.length,
       
  1089       nb = b.length,
       
  1090       n0 = Math.min(a.length, b.length),
       
  1091       i;
       
  1092   for (i = 0; i < n0; ++i) x.push(d3.interpolate(a[i], b[i]));
       
  1093   for (; i < na; ++i) c[i] = a[i];
       
  1094   for (; i < nb; ++i) c[i] = b[i];
       
  1095   return function(t) {
       
  1096     for (i = 0; i < n0; ++i) c[i] = x[i](t);
       
  1097     return c;
       
  1098   };
       
  1099 };
       
  1100 
       
  1101 d3.interpolateObject = function(a, b) {
       
  1102   var i = {},
       
  1103       c = {},
       
  1104       k;
       
  1105   for (k in a) {
       
  1106     if (k in b) {
       
  1107       i[k] = d3_interpolateByName(k)(a[k], b[k]);
       
  1108     } else {
       
  1109       c[k] = a[k];
       
  1110     }
       
  1111   }
       
  1112   for (k in b) {
       
  1113     if (!(k in a)) {
       
  1114       c[k] = b[k];
       
  1115     }
       
  1116   }
       
  1117   return function(t) {
       
  1118     for (k in i) c[k] = i[k](t);
       
  1119     return c;
       
  1120   };
       
  1121 }
       
  1122 
       
  1123 var d3_interpolate_number = /[-+]?(?:\d*\.?\d+)(?:[eE][-+]?\d+)?/g;
       
  1124 
       
  1125 function d3_interpolateByName(n) {
       
  1126   return n == "transform"
       
  1127       ? d3.interpolateTransform
       
  1128       : d3.interpolate;
       
  1129 }
       
  1130 
       
  1131 d3.interpolators = [
       
  1132   d3.interpolateObject,
       
  1133   function(a, b) { return (b instanceof Array) && d3.interpolateArray(a, b); },
       
  1134   function(a, b) { return (typeof a === "string" || typeof b === "string") && d3.interpolateString(a + "", b + ""); },
       
  1135   function(a, b) { return (typeof b === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) : b instanceof d3_Rgb || b instanceof d3_Hsl) && d3.interpolateRgb(a, b); },
       
  1136   function(a, b) { return !isNaN(a = +a) && !isNaN(b = +b) && d3.interpolateNumber(a, b); }
       
  1137 ];
       
  1138 function d3_uninterpolateNumber(a, b) {
       
  1139   b = b - (a = +a) ? 1 / (b - a) : 0;
       
  1140   return function(x) { return (x - a) * b; };
       
  1141 }
       
  1142 
       
  1143 function d3_uninterpolateClamp(a, b) {
       
  1144   b = b - (a = +a) ? 1 / (b - a) : 0;
       
  1145   return function(x) { return Math.max(0, Math.min(1, (x - a) * b)); };
       
  1146 }
       
  1147 d3.rgb = function(r, g, b) {
       
  1148   return arguments.length === 1
       
  1149       ? (r instanceof d3_Rgb ? d3_rgb(r.r, r.g, r.b)
       
  1150       : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb))
       
  1151       : d3_rgb(~~r, ~~g, ~~b);
       
  1152 };
       
  1153 
       
  1154 function d3_rgb(r, g, b) {
       
  1155   return new d3_Rgb(r, g, b);
       
  1156 }
       
  1157 
       
  1158 function d3_Rgb(r, g, b) {
       
  1159   this.r = r;
       
  1160   this.g = g;
       
  1161   this.b = b;
       
  1162 }
       
  1163 
       
  1164 d3_Rgb.prototype.brighter = function(k) {
       
  1165   k = Math.pow(0.7, arguments.length ? k : 1);
       
  1166   var r = this.r,
       
  1167       g = this.g,
       
  1168       b = this.b,
       
  1169       i = 30;
       
  1170   if (!r && !g && !b) return d3_rgb(i, i, i);
       
  1171   if (r && r < i) r = i;
       
  1172   if (g && g < i) g = i;
       
  1173   if (b && b < i) b = i;
       
  1174   return d3_rgb(
       
  1175       Math.min(255, Math.floor(r / k)),
       
  1176       Math.min(255, Math.floor(g / k)),
       
  1177       Math.min(255, Math.floor(b / k)));
       
  1178 };
       
  1179 
       
  1180 d3_Rgb.prototype.darker = function(k) {
       
  1181   k = Math.pow(0.7, arguments.length ? k : 1);
       
  1182   return d3_rgb(
       
  1183       Math.floor(k * this.r),
       
  1184       Math.floor(k * this.g),
       
  1185       Math.floor(k * this.b));
       
  1186 };
       
  1187 
       
  1188 d3_Rgb.prototype.hsl = function() {
       
  1189   return d3_rgb_hsl(this.r, this.g, this.b);
       
  1190 };
       
  1191 
       
  1192 d3_Rgb.prototype.toString = function() {
       
  1193   return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);
       
  1194 };
       
  1195 
       
  1196 function d3_rgb_hex(v) {
       
  1197   return v < 0x10
       
  1198       ? "0" + Math.max(0, v).toString(16)
       
  1199       : Math.min(255, v).toString(16);
       
  1200 }
       
  1201 
       
  1202 function d3_rgb_parse(format, rgb, hsl) {
       
  1203   var r = 0, // red channel; int in [0, 255]
       
  1204       g = 0, // green channel; int in [0, 255]
       
  1205       b = 0, // blue channel; int in [0, 255]
       
  1206       m1, // CSS color specification match
       
  1207       m2, // CSS color specification type (e.g., rgb)
       
  1208       name;
       
  1209 
       
  1210   /* Handle hsl, rgb. */
       
  1211   m1 = /([a-z]+)\((.*)\)/i.exec(format);
       
  1212   if (m1) {
       
  1213     m2 = m1[2].split(",");
       
  1214     switch (m1[1]) {
       
  1215       case "hsl": {
       
  1216         return hsl(
       
  1217           parseFloat(m2[0]), // degrees
       
  1218           parseFloat(m2[1]) / 100, // percentage
       
  1219           parseFloat(m2[2]) / 100 // percentage
       
  1220         );
       
  1221       }
       
  1222       case "rgb": {
       
  1223         return rgb(
       
  1224           d3_rgb_parseNumber(m2[0]),
       
  1225           d3_rgb_parseNumber(m2[1]),
       
  1226           d3_rgb_parseNumber(m2[2])
       
  1227         );
       
  1228       }
       
  1229     }
       
  1230   }
       
  1231 
       
  1232   /* Named colors. */
       
  1233   if (name = d3_rgb_names.get(format)) return rgb(name.r, name.g, name.b);
       
  1234 
       
  1235   /* Hexadecimal colors: #rgb and #rrggbb. */
       
  1236   if (format != null && format.charAt(0) === "#") {
       
  1237     if (format.length === 4) {
       
  1238       r = format.charAt(1); r += r;
       
  1239       g = format.charAt(2); g += g;
       
  1240       b = format.charAt(3); b += b;
       
  1241     } else if (format.length === 7) {
       
  1242       r = format.substring(1, 3);
       
  1243       g = format.substring(3, 5);
       
  1244       b = format.substring(5, 7);
       
  1245     }
       
  1246     r = parseInt(r, 16);
       
  1247     g = parseInt(g, 16);
       
  1248     b = parseInt(b, 16);
       
  1249   }
       
  1250 
       
  1251   return rgb(r, g, b);
       
  1252 }
       
  1253 
       
  1254 function d3_rgb_hsl(r, g, b) {
       
  1255   var min = Math.min(r /= 255, g /= 255, b /= 255),
       
  1256       max = Math.max(r, g, b),
       
  1257       d = max - min,
       
  1258       h,
       
  1259       s,
       
  1260       l = (max + min) / 2;
       
  1261   if (d) {
       
  1262     s = l < .5 ? d / (max + min) : d / (2 - max - min);
       
  1263     if (r == max) h = (g - b) / d + (g < b ? 6 : 0);
       
  1264     else if (g == max) h = (b - r) / d + 2;
       
  1265     else h = (r - g) / d + 4;
       
  1266     h *= 60;
       
  1267   } else {
       
  1268     s = h = 0;
       
  1269   }
       
  1270   return d3_hsl(h, s, l);
       
  1271 }
       
  1272 
       
  1273 function d3_rgb_parseNumber(c) { // either integer or percentage
       
  1274   var f = parseFloat(c);
       
  1275   return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
       
  1276 }
       
  1277 
       
  1278 var d3_rgb_names = d3.map({
       
  1279   aliceblue: "#f0f8ff",
       
  1280   antiquewhite: "#faebd7",
       
  1281   aqua: "#00ffff",
       
  1282   aquamarine: "#7fffd4",
       
  1283   azure: "#f0ffff",
       
  1284   beige: "#f5f5dc",
       
  1285   bisque: "#ffe4c4",
       
  1286   black: "#000000",
       
  1287   blanchedalmond: "#ffebcd",
       
  1288   blue: "#0000ff",
       
  1289   blueviolet: "#8a2be2",
       
  1290   brown: "#a52a2a",
       
  1291   burlywood: "#deb887",
       
  1292   cadetblue: "#5f9ea0",
       
  1293   chartreuse: "#7fff00",
       
  1294   chocolate: "#d2691e",
       
  1295   coral: "#ff7f50",
       
  1296   cornflowerblue: "#6495ed",
       
  1297   cornsilk: "#fff8dc",
       
  1298   crimson: "#dc143c",
       
  1299   cyan: "#00ffff",
       
  1300   darkblue: "#00008b",
       
  1301   darkcyan: "#008b8b",
       
  1302   darkgoldenrod: "#b8860b",
       
  1303   darkgray: "#a9a9a9",
       
  1304   darkgreen: "#006400",
       
  1305   darkgrey: "#a9a9a9",
       
  1306   darkkhaki: "#bdb76b",
       
  1307   darkmagenta: "#8b008b",
       
  1308   darkolivegreen: "#556b2f",
       
  1309   darkorange: "#ff8c00",
       
  1310   darkorchid: "#9932cc",
       
  1311   darkred: "#8b0000",
       
  1312   darksalmon: "#e9967a",
       
  1313   darkseagreen: "#8fbc8f",
       
  1314   darkslateblue: "#483d8b",
       
  1315   darkslategray: "#2f4f4f",
       
  1316   darkslategrey: "#2f4f4f",
       
  1317   darkturquoise: "#00ced1",
       
  1318   darkviolet: "#9400d3",
       
  1319   deeppink: "#ff1493",
       
  1320   deepskyblue: "#00bfff",
       
  1321   dimgray: "#696969",
       
  1322   dimgrey: "#696969",
       
  1323   dodgerblue: "#1e90ff",
       
  1324   firebrick: "#b22222",
       
  1325   floralwhite: "#fffaf0",
       
  1326   forestgreen: "#228b22",
       
  1327   fuchsia: "#ff00ff",
       
  1328   gainsboro: "#dcdcdc",
       
  1329   ghostwhite: "#f8f8ff",
       
  1330   gold: "#ffd700",
       
  1331   goldenrod: "#daa520",
       
  1332   gray: "#808080",
       
  1333   green: "#008000",
       
  1334   greenyellow: "#adff2f",
       
  1335   grey: "#808080",
       
  1336   honeydew: "#f0fff0",
       
  1337   hotpink: "#ff69b4",
       
  1338   indianred: "#cd5c5c",
       
  1339   indigo: "#4b0082",
       
  1340   ivory: "#fffff0",
       
  1341   khaki: "#f0e68c",
       
  1342   lavender: "#e6e6fa",
       
  1343   lavenderblush: "#fff0f5",
       
  1344   lawngreen: "#7cfc00",
       
  1345   lemonchiffon: "#fffacd",
       
  1346   lightblue: "#add8e6",
       
  1347   lightcoral: "#f08080",
       
  1348   lightcyan: "#e0ffff",
       
  1349   lightgoldenrodyellow: "#fafad2",
       
  1350   lightgray: "#d3d3d3",
       
  1351   lightgreen: "#90ee90",
       
  1352   lightgrey: "#d3d3d3",
       
  1353   lightpink: "#ffb6c1",
       
  1354   lightsalmon: "#ffa07a",
       
  1355   lightseagreen: "#20b2aa",
       
  1356   lightskyblue: "#87cefa",
       
  1357   lightslategray: "#778899",
       
  1358   lightslategrey: "#778899",
       
  1359   lightsteelblue: "#b0c4de",
       
  1360   lightyellow: "#ffffe0",
       
  1361   lime: "#00ff00",
       
  1362   limegreen: "#32cd32",
       
  1363   linen: "#faf0e6",
       
  1364   magenta: "#ff00ff",
       
  1365   maroon: "#800000",
       
  1366   mediumaquamarine: "#66cdaa",
       
  1367   mediumblue: "#0000cd",
       
  1368   mediumorchid: "#ba55d3",
       
  1369   mediumpurple: "#9370db",
       
  1370   mediumseagreen: "#3cb371",
       
  1371   mediumslateblue: "#7b68ee",
       
  1372   mediumspringgreen: "#00fa9a",
       
  1373   mediumturquoise: "#48d1cc",
       
  1374   mediumvioletred: "#c71585",
       
  1375   midnightblue: "#191970",
       
  1376   mintcream: "#f5fffa",
       
  1377   mistyrose: "#ffe4e1",
       
  1378   moccasin: "#ffe4b5",
       
  1379   navajowhite: "#ffdead",
       
  1380   navy: "#000080",
       
  1381   oldlace: "#fdf5e6",
       
  1382   olive: "#808000",
       
  1383   olivedrab: "#6b8e23",
       
  1384   orange: "#ffa500",
       
  1385   orangered: "#ff4500",
       
  1386   orchid: "#da70d6",
       
  1387   palegoldenrod: "#eee8aa",
       
  1388   palegreen: "#98fb98",
       
  1389   paleturquoise: "#afeeee",
       
  1390   palevioletred: "#db7093",
       
  1391   papayawhip: "#ffefd5",
       
  1392   peachpuff: "#ffdab9",
       
  1393   peru: "#cd853f",
       
  1394   pink: "#ffc0cb",
       
  1395   plum: "#dda0dd",
       
  1396   powderblue: "#b0e0e6",
       
  1397   purple: "#800080",
       
  1398   red: "#ff0000",
       
  1399   rosybrown: "#bc8f8f",
       
  1400   royalblue: "#4169e1",
       
  1401   saddlebrown: "#8b4513",
       
  1402   salmon: "#fa8072",
       
  1403   sandybrown: "#f4a460",
       
  1404   seagreen: "#2e8b57",
       
  1405   seashell: "#fff5ee",
       
  1406   sienna: "#a0522d",
       
  1407   silver: "#c0c0c0",
       
  1408   skyblue: "#87ceeb",
       
  1409   slateblue: "#6a5acd",
       
  1410   slategray: "#708090",
       
  1411   slategrey: "#708090",
       
  1412   snow: "#fffafa",
       
  1413   springgreen: "#00ff7f",
       
  1414   steelblue: "#4682b4",
       
  1415   tan: "#d2b48c",
       
  1416   teal: "#008080",
       
  1417   thistle: "#d8bfd8",
       
  1418   tomato: "#ff6347",
       
  1419   turquoise: "#40e0d0",
       
  1420   violet: "#ee82ee",
       
  1421   wheat: "#f5deb3",
       
  1422   white: "#ffffff",
       
  1423   whitesmoke: "#f5f5f5",
       
  1424   yellow: "#ffff00",
       
  1425   yellowgreen: "#9acd32"
       
  1426 });
       
  1427 
       
  1428 d3_rgb_names.forEach(function(key, value) {
       
  1429   d3_rgb_names.set(key, d3_rgb_parse(value, d3_rgb, d3_hsl_rgb));
       
  1430 });
       
  1431 d3.hsl = function(h, s, l) {
       
  1432   return arguments.length === 1
       
  1433       ? (h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l)
       
  1434       : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl))
       
  1435       : d3_hsl(+h, +s, +l);
       
  1436 };
       
  1437 
       
  1438 function d3_hsl(h, s, l) {
       
  1439   return new d3_Hsl(h, s, l);
       
  1440 }
       
  1441 
       
  1442 function d3_Hsl(h, s, l) {
       
  1443   this.h = h;
       
  1444   this.s = s;
       
  1445   this.l = l;
       
  1446 }
       
  1447 
       
  1448 d3_Hsl.prototype.brighter = function(k) {
       
  1449   k = Math.pow(0.7, arguments.length ? k : 1);
       
  1450   return d3_hsl(this.h, this.s, this.l / k);
       
  1451 };
       
  1452 
       
  1453 d3_Hsl.prototype.darker = function(k) {
       
  1454   k = Math.pow(0.7, arguments.length ? k : 1);
       
  1455   return d3_hsl(this.h, this.s, k * this.l);
       
  1456 };
       
  1457 
       
  1458 d3_Hsl.prototype.rgb = function() {
       
  1459   return d3_hsl_rgb(this.h, this.s, this.l);
       
  1460 };
       
  1461 
       
  1462 d3_Hsl.prototype.toString = function() {
       
  1463   return this.rgb().toString();
       
  1464 };
       
  1465 
       
  1466 function d3_hsl_rgb(h, s, l) {
       
  1467   var m1,
       
  1468       m2;
       
  1469 
       
  1470   /* Some simple corrections for h, s and l. */
       
  1471   h = h % 360; if (h < 0) h += 360;
       
  1472   s = s < 0 ? 0 : s > 1 ? 1 : s;
       
  1473   l = l < 0 ? 0 : l > 1 ? 1 : l;
       
  1474 
       
  1475   /* From FvD 13.37, CSS Color Module Level 3 */
       
  1476   m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
       
  1477   m1 = 2 * l - m2;
       
  1478 
       
  1479   function v(h) {
       
  1480     if (h > 360) h -= 360;
       
  1481     else if (h < 0) h += 360;
       
  1482     if (h < 60) return m1 + (m2 - m1) * h / 60;
       
  1483     if (h < 180) return m2;
       
  1484     if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
       
  1485     return m1;
       
  1486   }
       
  1487 
       
  1488   function vv(h) {
       
  1489     return Math.round(v(h) * 255);
       
  1490   }
       
  1491 
       
  1492   return d3_rgb(vv(h + 120), vv(h), vv(h - 120));
       
  1493 }
       
  1494 function d3_selection(groups) {
       
  1495   d3_arraySubclass(groups, d3_selectionPrototype);
       
  1496   return groups;
       
  1497 }
       
  1498 
       
  1499 var d3_select = function(s, n) { return n.querySelector(s); },
       
  1500     d3_selectAll = function(s, n) { return n.querySelectorAll(s); },
       
  1501     d3_selectRoot = document.documentElement,
       
  1502     d3_selectMatcher = d3_selectRoot.matchesSelector || d3_selectRoot.webkitMatchesSelector || d3_selectRoot.mozMatchesSelector || d3_selectRoot.msMatchesSelector || d3_selectRoot.oMatchesSelector,
       
  1503     d3_selectMatches = function(n, s) { return d3_selectMatcher.call(n, s); };
       
  1504 
       
  1505 // Prefer Sizzle, if available.
       
  1506 if (typeof Sizzle === "function") {
       
  1507   d3_select = function(s, n) { return Sizzle(s, n)[0]; };
       
  1508   d3_selectAll = function(s, n) { return Sizzle.uniqueSort(Sizzle(s, n)); };
       
  1509   d3_selectMatches = Sizzle.matchesSelector;
       
  1510 }
       
  1511 
       
  1512 var d3_selectionPrototype = [];
       
  1513 
       
  1514 d3.selection = function() {
       
  1515   return d3_selectionRoot;
       
  1516 };
       
  1517 
       
  1518 d3.selection.prototype = d3_selectionPrototype;
       
  1519 d3_selectionPrototype.select = function(selector) {
       
  1520   var subgroups = [],
       
  1521       subgroup,
       
  1522       subnode,
       
  1523       group,
       
  1524       node;
       
  1525 
       
  1526   if (typeof selector !== "function") selector = d3_selection_selector(selector);
       
  1527 
       
  1528   for (var j = -1, m = this.length; ++j < m;) {
       
  1529     subgroups.push(subgroup = []);
       
  1530     subgroup.parentNode = (group = this[j]).parentNode;
       
  1531     for (var i = -1, n = group.length; ++i < n;) {
       
  1532       if (node = group[i]) {
       
  1533         subgroup.push(subnode = selector.call(node, node.__data__, i));
       
  1534         if (subnode && "__data__" in node) subnode.__data__ = node.__data__;
       
  1535       } else {
       
  1536         subgroup.push(null);
       
  1537       }
       
  1538     }
       
  1539   }
       
  1540 
       
  1541   return d3_selection(subgroups);
       
  1542 };
       
  1543 
       
  1544 function d3_selection_selector(selector) {
       
  1545   return function() {
       
  1546     return d3_select(selector, this);
       
  1547   };
       
  1548 }
       
  1549 d3_selectionPrototype.selectAll = function(selector) {
       
  1550   var subgroups = [],
       
  1551       subgroup,
       
  1552       node;
       
  1553 
       
  1554   if (typeof selector !== "function") selector = d3_selection_selectorAll(selector);
       
  1555 
       
  1556   for (var j = -1, m = this.length; ++j < m;) {
       
  1557     for (var group = this[j], i = -1, n = group.length; ++i < n;) {
       
  1558       if (node = group[i]) {
       
  1559         subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i)));
       
  1560         subgroup.parentNode = node;
       
  1561       }
       
  1562     }
       
  1563   }
       
  1564 
       
  1565   return d3_selection(subgroups);
       
  1566 };
       
  1567 
       
  1568 function d3_selection_selectorAll(selector) {
       
  1569   return function() {
       
  1570     return d3_selectAll(selector, this);
       
  1571   };
       
  1572 }
       
  1573 d3_selectionPrototype.attr = function(name, value) {
       
  1574   name = d3.ns.qualify(name);
       
  1575 
       
  1576   // If no value is specified, return the first value.
       
  1577   if (arguments.length < 2) {
       
  1578     var node = this.node();
       
  1579     return name.local
       
  1580         ? node.getAttributeNS(name.space, name.local)
       
  1581         : node.getAttribute(name);
       
  1582   }
       
  1583 
       
  1584   function attrNull() {
       
  1585     this.removeAttribute(name);
       
  1586   }
       
  1587 
       
  1588   function attrNullNS() {
       
  1589     this.removeAttributeNS(name.space, name.local);
       
  1590   }
       
  1591 
       
  1592   function attrConstant() {
       
  1593     this.setAttribute(name, value);
       
  1594   }
       
  1595 
       
  1596   function attrConstantNS() {
       
  1597     this.setAttributeNS(name.space, name.local, value);
       
  1598   }
       
  1599 
       
  1600   function attrFunction() {
       
  1601     var x = value.apply(this, arguments);
       
  1602     if (x == null) this.removeAttribute(name);
       
  1603     else this.setAttribute(name, x);
       
  1604   }
       
  1605 
       
  1606   function attrFunctionNS() {
       
  1607     var x = value.apply(this, arguments);
       
  1608     if (x == null) this.removeAttributeNS(name.space, name.local);
       
  1609     else this.setAttributeNS(name.space, name.local, x);
       
  1610   }
       
  1611 
       
  1612   return this.each(value == null
       
  1613       ? (name.local ? attrNullNS : attrNull) : (typeof value === "function"
       
  1614       ? (name.local ? attrFunctionNS : attrFunction)
       
  1615       : (name.local ? attrConstantNS : attrConstant)));
       
  1616 };
       
  1617 d3_selectionPrototype.classed = function(name, value) {
       
  1618   var names = name.split(d3_selection_classedWhitespace),
       
  1619       n = names.length,
       
  1620       i = -1;
       
  1621   if (arguments.length > 1) {
       
  1622     while (++i < n) d3_selection_classed.call(this, names[i], value);
       
  1623     return this;
       
  1624   } else {
       
  1625     while (++i < n) if (!d3_selection_classed.call(this, names[i])) return false;
       
  1626     return true;
       
  1627   }
       
  1628 };
       
  1629 
       
  1630 var d3_selection_classedWhitespace = /\s+/g;
       
  1631 
       
  1632 function d3_selection_classed(name, value) {
       
  1633   var re = new RegExp("(^|\\s+)" + d3.requote(name) + "(\\s+|$)", "g");
       
  1634 
       
  1635   // If no value is specified, return the first value.
       
  1636   if (arguments.length < 2) {
       
  1637     var node = this.node();
       
  1638     if (c = node.classList) return c.contains(name);
       
  1639     var c = node.className;
       
  1640     re.lastIndex = 0;
       
  1641     return re.test(c.baseVal != null ? c.baseVal : c);
       
  1642   }
       
  1643 
       
  1644   function classedAdd() {
       
  1645     if (c = this.classList) return c.add(name);
       
  1646     var c = this.className,
       
  1647         cb = c.baseVal != null,
       
  1648         cv = cb ? c.baseVal : c;
       
  1649     re.lastIndex = 0;
       
  1650     if (!re.test(cv)) {
       
  1651       cv = d3_collapse(cv + " " + name);
       
  1652       if (cb) c.baseVal = cv;
       
  1653       else this.className = cv;
       
  1654     }
       
  1655   }
       
  1656 
       
  1657   function classedRemove() {
       
  1658     if (c = this.classList) return c.remove(name);
       
  1659     var c = this.className,
       
  1660         cb = c.baseVal != null,
       
  1661         cv = cb ? c.baseVal : c;
       
  1662     cv = d3_collapse(cv.replace(re, " "));
       
  1663     if (cb) c.baseVal = cv;
       
  1664     else this.className = cv;
       
  1665   }
       
  1666 
       
  1667   function classedFunction() {
       
  1668     (value.apply(this, arguments)
       
  1669         ? classedAdd
       
  1670         : classedRemove).call(this);
       
  1671   }
       
  1672 
       
  1673   return this.each(typeof value === "function"
       
  1674       ? classedFunction : value
       
  1675       ? classedAdd
       
  1676       : classedRemove);
       
  1677 }
       
  1678 d3_selectionPrototype.style = function(name, value, priority) {
       
  1679   if (arguments.length < 3) priority = "";
       
  1680 
       
  1681   // If no value is specified, return the first value.
       
  1682   if (arguments.length < 2) return window
       
  1683       .getComputedStyle(this.node(), null)
       
  1684       .getPropertyValue(name);
       
  1685 
       
  1686   function styleNull() {
       
  1687     this.style.removeProperty(name);
       
  1688   }
       
  1689 
       
  1690   function styleConstant() {
       
  1691     this.style.setProperty(name, value, priority);
       
  1692   }
       
  1693 
       
  1694   function styleFunction() {
       
  1695     var x = value.apply(this, arguments);
       
  1696     if (x == null) this.style.removeProperty(name);
       
  1697     else this.style.setProperty(name, x, priority);
       
  1698   }
       
  1699 
       
  1700   return this.each(value == null
       
  1701       ? styleNull : (typeof value === "function"
       
  1702       ? styleFunction : styleConstant));
       
  1703 };
       
  1704 d3_selectionPrototype.property = function(name, value) {
       
  1705 
       
  1706   // If no value is specified, return the first value.
       
  1707   if (arguments.length < 2) return this.node()[name];
       
  1708 
       
  1709   function propertyNull() {
       
  1710     delete this[name];
       
  1711   }
       
  1712 
       
  1713   function propertyConstant() {
       
  1714     this[name] = value;
       
  1715   }
       
  1716 
       
  1717   function propertyFunction() {
       
  1718     var x = value.apply(this, arguments);
       
  1719     if (x == null) delete this[name];
       
  1720     else this[name] = x;
       
  1721   }
       
  1722 
       
  1723   return this.each(value == null
       
  1724       ? propertyNull : (typeof value === "function"
       
  1725       ? propertyFunction : propertyConstant));
       
  1726 };
       
  1727 d3_selectionPrototype.text = function(value) {
       
  1728   return arguments.length < 1
       
  1729       ? this.node().textContent : this.each(typeof value === "function"
       
  1730       ? function() { var v = value.apply(this, arguments); this.textContent = v == null ? "" : v; } : value == null
       
  1731       ? function() { this.textContent = ""; }
       
  1732       : function() { this.textContent = value; });
       
  1733 };
       
  1734 d3_selectionPrototype.html = function(value) {
       
  1735   return arguments.length < 1
       
  1736       ? this.node().innerHTML : this.each(typeof value === "function"
       
  1737       ? function() { var v = value.apply(this, arguments); this.innerHTML = v == null ? "" : v; } : value == null
       
  1738       ? function() { this.innerHTML = ""; }
       
  1739       : function() { this.innerHTML = value; });
       
  1740 };
       
  1741 // TODO append(node)?
       
  1742 // TODO append(function)?
       
  1743 d3_selectionPrototype.append = function(name) {
       
  1744   name = d3.ns.qualify(name);
       
  1745 
       
  1746   function append() {
       
  1747     return this.appendChild(document.createElementNS(this.namespaceURI, name));
       
  1748   }
       
  1749 
       
  1750   function appendNS() {
       
  1751     return this.appendChild(document.createElementNS(name.space, name.local));
       
  1752   }
       
  1753 
       
  1754   return this.select(name.local ? appendNS : append);
       
  1755 };
       
  1756 // TODO insert(node, function)?
       
  1757 // TODO insert(function, string)?
       
  1758 // TODO insert(function, function)?
       
  1759 d3_selectionPrototype.insert = function(name, before) {
       
  1760   name = d3.ns.qualify(name);
       
  1761 
       
  1762   function insert() {
       
  1763     return this.insertBefore(
       
  1764         document.createElementNS(this.namespaceURI, name),
       
  1765         d3_select(before, this));
       
  1766   }
       
  1767 
       
  1768   function insertNS() {
       
  1769     return this.insertBefore(
       
  1770         document.createElementNS(name.space, name.local),
       
  1771         d3_select(before, this));
       
  1772   }
       
  1773 
       
  1774   return this.select(name.local ? insertNS : insert);
       
  1775 };
       
  1776 // TODO remove(selector)?
       
  1777 // TODO remove(node)?
       
  1778 // TODO remove(function)?
       
  1779 d3_selectionPrototype.remove = function() {
       
  1780   return this.each(function() {
       
  1781     var parent = this.parentNode;
       
  1782     if (parent) parent.removeChild(this);
       
  1783   });
       
  1784 };
       
  1785 d3_selectionPrototype.data = function(value, key) {
       
  1786   var i = -1,
       
  1787       n = this.length,
       
  1788       group,
       
  1789       node;
       
  1790 
       
  1791   // If no value is specified, return the first value.
       
  1792   if (!arguments.length) {
       
  1793     value = new Array(n = (group = this[0]).length);
       
  1794     while (++i < n) {
       
  1795       if (node = group[i]) {
       
  1796         value[i] = node.__data__;
       
  1797       }
       
  1798     }
       
  1799     return value;
       
  1800   }
       
  1801 
       
  1802   function bind(group, groupData) {
       
  1803     var i,
       
  1804         n = group.length,
       
  1805         m = groupData.length,
       
  1806         n0 = Math.min(n, m),
       
  1807         n1 = Math.max(n, m),
       
  1808         updateNodes = [],
       
  1809         enterNodes = [],
       
  1810         exitNodes = [],
       
  1811         node,
       
  1812         nodeData;
       
  1813 
       
  1814     if (key) {
       
  1815       var nodeByKeyValue = new d3_Map,
       
  1816           keyValues = [],
       
  1817           keyValue,
       
  1818           j = groupData.length;
       
  1819 
       
  1820       for (i = -1; ++i < n;) {
       
  1821         keyValue = key.call(node = group[i], node.__data__, i);
       
  1822         if (nodeByKeyValue.has(keyValue)) {
       
  1823           exitNodes[j++] = node; // duplicate key
       
  1824         } else {
       
  1825           nodeByKeyValue.set(keyValue, node);
       
  1826         }
       
  1827         keyValues.push(keyValue);
       
  1828       }
       
  1829 
       
  1830       for (i = -1; ++i < m;) {
       
  1831         keyValue = key.call(groupData, nodeData = groupData[i], i)
       
  1832         if (nodeByKeyValue.has(keyValue)) {
       
  1833           updateNodes[i] = node = nodeByKeyValue.get(keyValue);
       
  1834           node.__data__ = nodeData;
       
  1835           enterNodes[i] = exitNodes[i] = null;
       
  1836         } else {
       
  1837           enterNodes[i] = d3_selection_dataNode(nodeData);
       
  1838           updateNodes[i] = exitNodes[i] = null;
       
  1839         }
       
  1840         nodeByKeyValue.remove(keyValue);
       
  1841       }
       
  1842 
       
  1843       for (i = -1; ++i < n;) {
       
  1844         if (nodeByKeyValue.has(keyValues[i])) {
       
  1845           exitNodes[i] = group[i];
       
  1846         }
       
  1847       }
       
  1848     } else {
       
  1849       for (i = -1; ++i < n0;) {
       
  1850         node = group[i];
       
  1851         nodeData = groupData[i];
       
  1852         if (node) {
       
  1853           node.__data__ = nodeData;
       
  1854           updateNodes[i] = node;
       
  1855           enterNodes[i] = exitNodes[i] = null;
       
  1856         } else {
       
  1857           enterNodes[i] = d3_selection_dataNode(nodeData);
       
  1858           updateNodes[i] = exitNodes[i] = null;
       
  1859         }
       
  1860       }
       
  1861       for (; i < m; ++i) {
       
  1862         enterNodes[i] = d3_selection_dataNode(groupData[i]);
       
  1863         updateNodes[i] = exitNodes[i] = null;
       
  1864       }
       
  1865       for (; i < n1; ++i) {
       
  1866         exitNodes[i] = group[i];
       
  1867         enterNodes[i] = updateNodes[i] = null;
       
  1868       }
       
  1869     }
       
  1870 
       
  1871     enterNodes.update
       
  1872         = updateNodes;
       
  1873 
       
  1874     enterNodes.parentNode
       
  1875         = updateNodes.parentNode
       
  1876         = exitNodes.parentNode
       
  1877         = group.parentNode;
       
  1878 
       
  1879     enter.push(enterNodes);
       
  1880     update.push(updateNodes);
       
  1881     exit.push(exitNodes);
       
  1882   }
       
  1883 
       
  1884   var enter = d3_selection_enter([]),
       
  1885       update = d3_selection([]),
       
  1886       exit = d3_selection([]);
       
  1887 
       
  1888   if (typeof value === "function") {
       
  1889     while (++i < n) {
       
  1890       bind(group = this[i], value.call(group, group.parentNode.__data__, i));
       
  1891     }
       
  1892   } else {
       
  1893     while (++i < n) {
       
  1894       bind(group = this[i], value);
       
  1895     }
       
  1896   }
       
  1897 
       
  1898   update.enter = function() { return enter; };
       
  1899   update.exit = function() { return exit; };
       
  1900   return update;
       
  1901 };
       
  1902 
       
  1903 function d3_selection_dataNode(data) {
       
  1904   return {__data__: data};
       
  1905 }
       
  1906 d3_selectionPrototype.datum =
       
  1907 d3_selectionPrototype.map = function(value) {
       
  1908   return arguments.length < 1
       
  1909       ? this.property("__data__")
       
  1910       : this.property("__data__", value);
       
  1911 };
       
  1912 d3_selectionPrototype.filter = function(filter) {
       
  1913   var subgroups = [],
       
  1914       subgroup,
       
  1915       group,
       
  1916       node;
       
  1917 
       
  1918   if (typeof filter !== "function") filter = d3_selection_filter(filter);
       
  1919 
       
  1920   for (var j = 0, m = this.length; j < m; j++) {
       
  1921     subgroups.push(subgroup = []);
       
  1922     subgroup.parentNode = (group = this[j]).parentNode;
       
  1923     for (var i = 0, n = group.length; i < n; i++) {
       
  1924       if ((node = group[i]) && filter.call(node, node.__data__, i)) {
       
  1925         subgroup.push(node);
       
  1926       }
       
  1927     }
       
  1928   }
       
  1929 
       
  1930   return d3_selection(subgroups);
       
  1931 };
       
  1932 
       
  1933 function d3_selection_filter(selector) {
       
  1934   return function() {
       
  1935     return d3_selectMatches(this, selector);
       
  1936   };
       
  1937 }
       
  1938 d3_selectionPrototype.order = function() {
       
  1939   for (var j = -1, m = this.length; ++j < m;) {
       
  1940     for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
       
  1941       if (node = group[i]) {
       
  1942         if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
       
  1943         next = node;
       
  1944       }
       
  1945     }
       
  1946   }
       
  1947   return this;
       
  1948 };
       
  1949 d3_selectionPrototype.sort = function(comparator) {
       
  1950   comparator = d3_selection_sortComparator.apply(this, arguments);
       
  1951   for (var j = -1, m = this.length; ++j < m;) this[j].sort(comparator);
       
  1952   return this.order();
       
  1953 };
       
  1954 
       
  1955 function d3_selection_sortComparator(comparator) {
       
  1956   if (!arguments.length) comparator = d3.ascending;
       
  1957   return function(a, b) {
       
  1958     return comparator(a && a.__data__, b && b.__data__);
       
  1959   };
       
  1960 }
       
  1961 // type can be namespaced, e.g., "click.foo"
       
  1962 // listener can be null for removal
       
  1963 d3_selectionPrototype.on = function(type, listener, capture) {
       
  1964   if (arguments.length < 3) capture = false;
       
  1965 
       
  1966   // parse the type specifier
       
  1967   var name = "__on" + type, i = type.indexOf(".");
       
  1968   if (i > 0) type = type.substring(0, i);
       
  1969 
       
  1970   // if called with only one argument, return the current listener
       
  1971   if (arguments.length < 2) return (i = this.node()[name]) && i._;
       
  1972 
       
  1973   // remove the old event listener, and add the new event listener
       
  1974   return this.each(function(d, i) {
       
  1975     var node = this,
       
  1976         o = node[name];
       
  1977 
       
  1978     // remove the old listener, if any (using the previously-set capture)
       
  1979     if (o) {
       
  1980       node.removeEventListener(type, o, o.$);
       
  1981       delete node[name];
       
  1982     }
       
  1983 
       
  1984     // add the new listener, if any (remembering the capture flag)
       
  1985     if (listener) {
       
  1986       node.addEventListener(type, node[name] = l, l.$ = capture);
       
  1987       l._ = listener; // stash the unwrapped listener for get
       
  1988     }
       
  1989 
       
  1990     // wrapped event listener that preserves i
       
  1991     function l(e) {
       
  1992       var o = d3.event; // Events can be reentrant (e.g., focus).
       
  1993       d3.event = e;
       
  1994       try {
       
  1995         listener.call(node, node.__data__, i);
       
  1996       } finally {
       
  1997         d3.event = o;
       
  1998       }
       
  1999     }
       
  2000   });
       
  2001 };
       
  2002 d3_selectionPrototype.each = function(callback) {
       
  2003   for (var j = -1, m = this.length; ++j < m;) {
       
  2004     for (var group = this[j], i = -1, n = group.length; ++i < n;) {
       
  2005       var node = group[i];
       
  2006       if (node) callback.call(node, node.__data__, i, j);
       
  2007     }
       
  2008   }
       
  2009   return this;
       
  2010 };
       
  2011 //
       
  2012 // Note: assigning to the arguments array simultaneously changes the value of
       
  2013 // the corresponding argument!
       
  2014 //
       
  2015 // TODO The `this` argument probably shouldn't be the first argument to the
       
  2016 // callback, anyway, since it's redundant. However, that will require a major
       
  2017 // version bump due to backwards compatibility, so I'm not changing it right
       
  2018 // away.
       
  2019 //
       
  2020 d3_selectionPrototype.call = function(callback) {
       
  2021   callback.apply(this, (arguments[0] = this, arguments));
       
  2022   return this;
       
  2023 };
       
  2024 d3_selectionPrototype.empty = function() {
       
  2025   return !this.node();
       
  2026 };
       
  2027 d3_selectionPrototype.node = function(callback) {
       
  2028   for (var j = 0, m = this.length; j < m; j++) {
       
  2029     for (var group = this[j], i = 0, n = group.length; i < n; i++) {
       
  2030       var node = group[i];
       
  2031       if (node) return node;
       
  2032     }
       
  2033   }
       
  2034   return null;
       
  2035 };
       
  2036 d3_selectionPrototype.transition = function() {
       
  2037   var subgroups = [],
       
  2038       subgroup,
       
  2039       node;
       
  2040 
       
  2041   for (var j = -1, m = this.length; ++j < m;) {
       
  2042     subgroups.push(subgroup = []);
       
  2043     for (var group = this[j], i = -1, n = group.length; ++i < n;) {
       
  2044       subgroup.push((node = group[i]) ? {node: node, delay: d3_transitionDelay, duration: d3_transitionDuration} : null);
       
  2045     }
       
  2046   }
       
  2047 
       
  2048   return d3_transition(subgroups, d3_transitionId || ++d3_transitionNextId, Date.now());
       
  2049 };
       
  2050 var d3_selectionRoot = d3_selection([[document]]);
       
  2051 
       
  2052 d3_selectionRoot[0].parentNode = d3_selectRoot;
       
  2053 
       
  2054 // TODO fast singleton implementation!
       
  2055 // TODO select(function)
       
  2056 d3.select = function(selector) {
       
  2057   return typeof selector === "string"
       
  2058       ? d3_selectionRoot.select(selector)
       
  2059       : d3_selection([[selector]]); // assume node
       
  2060 };
       
  2061 
       
  2062 // TODO selectAll(function)
       
  2063 d3.selectAll = function(selector) {
       
  2064   return typeof selector === "string"
       
  2065       ? d3_selectionRoot.selectAll(selector)
       
  2066       : d3_selection([d3_array(selector)]); // assume node[]
       
  2067 };
       
  2068 function d3_selection_enter(selection) {
       
  2069   d3_arraySubclass(selection, d3_selection_enterPrototype);
       
  2070   return selection;
       
  2071 }
       
  2072 
       
  2073 var d3_selection_enterPrototype = [];
       
  2074 
       
  2075 d3.selection.enter = d3_selection_enter;
       
  2076 d3.selection.enter.prototype = d3_selection_enterPrototype;
       
  2077 
       
  2078 d3_selection_enterPrototype.append = d3_selectionPrototype.append;
       
  2079 d3_selection_enterPrototype.insert = d3_selectionPrototype.insert;
       
  2080 d3_selection_enterPrototype.empty = d3_selectionPrototype.empty;
       
  2081 d3_selection_enterPrototype.node = d3_selectionPrototype.node;
       
  2082 d3_selection_enterPrototype.select = function(selector) {
       
  2083   var subgroups = [],
       
  2084       subgroup,
       
  2085       subnode,
       
  2086       upgroup,
       
  2087       group,
       
  2088       node;
       
  2089 
       
  2090   for (var j = -1, m = this.length; ++j < m;) {
       
  2091     upgroup = (group = this[j]).update;
       
  2092     subgroups.push(subgroup = []);
       
  2093     subgroup.parentNode = group.parentNode;
       
  2094     for (var i = -1, n = group.length; ++i < n;) {
       
  2095       if (node = group[i]) {
       
  2096         subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i));
       
  2097         subnode.__data__ = node.__data__;
       
  2098       } else {
       
  2099         subgroup.push(null);
       
  2100       }
       
  2101     }
       
  2102   }
       
  2103 
       
  2104   return d3_selection(subgroups);
       
  2105 };
       
  2106 function d3_transition(groups, id, time) {
       
  2107   d3_arraySubclass(groups, d3_transitionPrototype);
       
  2108 
       
  2109   var tweens = new d3_Map,
       
  2110       event = d3.dispatch("start", "end"),
       
  2111       ease = d3_transitionEase;
       
  2112 
       
  2113   groups.id = id;
       
  2114 
       
  2115   groups.time = time;
       
  2116 
       
  2117   groups.tween = function(name, tween) {
       
  2118     if (arguments.length < 2) return tweens.get(name);
       
  2119     if (tween == null) tweens.remove(name);
       
  2120     else tweens.set(name, tween);
       
  2121     return groups;
       
  2122   };
       
  2123 
       
  2124   groups.ease = function(value) {
       
  2125     if (!arguments.length) return ease;
       
  2126     ease = typeof value === "function" ? value : d3.ease.apply(d3, arguments);
       
  2127     return groups;
       
  2128   };
       
  2129 
       
  2130   groups.each = function(type, listener) {
       
  2131     if (arguments.length < 2) return d3_transition_each.call(groups, type);
       
  2132     event.on(type, listener);
       
  2133     return groups;
       
  2134   };
       
  2135 
       
  2136   d3.timer(function(elapsed) {
       
  2137     groups.each(function(d, i, j) {
       
  2138       var tweened = [],
       
  2139           node = this,
       
  2140           delay = groups[j][i].delay,
       
  2141           duration = groups[j][i].duration,
       
  2142           lock = node.__transition__ || (node.__transition__ = {active: 0, count: 0});
       
  2143 
       
  2144       ++lock.count;
       
  2145 
       
  2146       delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time);
       
  2147 
       
  2148       function start(elapsed) {
       
  2149         if (lock.active > id) return stop();
       
  2150         lock.active = id;
       
  2151 
       
  2152         tweens.forEach(function(key, value) {
       
  2153           if (tween = value.call(node, d, i)) {
       
  2154             tweened.push(tween);
       
  2155           }
       
  2156         });
       
  2157 
       
  2158         event.start.call(node, d, i);
       
  2159         if (!tick(elapsed)) d3.timer(tick, 0, time);
       
  2160         return 1;
       
  2161       }
       
  2162 
       
  2163       function tick(elapsed) {
       
  2164         if (lock.active !== id) return stop();
       
  2165 
       
  2166         var t = (elapsed - delay) / duration,
       
  2167             e = ease(t),
       
  2168             n = tweened.length;
       
  2169 
       
  2170         while (n > 0) {
       
  2171           tweened[--n].call(node, e);
       
  2172         }
       
  2173 
       
  2174         if (t >= 1) {
       
  2175           stop();
       
  2176           d3_transitionId = id;
       
  2177           event.end.call(node, d, i);
       
  2178           d3_transitionId = 0;
       
  2179           return 1;
       
  2180         }
       
  2181       }
       
  2182 
       
  2183       function stop() {
       
  2184         if (!--lock.count) delete node.__transition__;
       
  2185         return 1;
       
  2186       }
       
  2187     });
       
  2188     return 1;
       
  2189   }, 0, time);
       
  2190 
       
  2191   return groups;
       
  2192 }
       
  2193 
       
  2194 var d3_transitionRemove = {};
       
  2195 
       
  2196 function d3_transitionNull(d, i, a) {
       
  2197   return a != "" && d3_transitionRemove;
       
  2198 }
       
  2199 
       
  2200 function d3_transitionTween(name, b) {
       
  2201   var interpolate = d3_interpolateByName(name);
       
  2202 
       
  2203   function transitionFunction(d, i, a) {
       
  2204     var v = b.call(this, d, i);
       
  2205     return v == null
       
  2206         ? a != "" && d3_transitionRemove
       
  2207         : a != v && interpolate(a, v);
       
  2208   }
       
  2209 
       
  2210   function transitionString(d, i, a) {
       
  2211     return a != b && interpolate(a, b);
       
  2212   }
       
  2213 
       
  2214   return typeof b === "function" ? transitionFunction
       
  2215       : b == null ? d3_transitionNull
       
  2216       : (b += "", transitionString);
       
  2217 }
       
  2218 
       
  2219 var d3_transitionPrototype = [],
       
  2220     d3_transitionNextId = 0,
       
  2221     d3_transitionId = 0,
       
  2222     d3_transitionDefaultDelay = 0,
       
  2223     d3_transitionDefaultDuration = 250,
       
  2224     d3_transitionDefaultEase = d3.ease("cubic-in-out"),
       
  2225     d3_transitionDelay = d3_transitionDefaultDelay,
       
  2226     d3_transitionDuration = d3_transitionDefaultDuration,
       
  2227     d3_transitionEase = d3_transitionDefaultEase;
       
  2228 
       
  2229 d3_transitionPrototype.call = d3_selectionPrototype.call;
       
  2230 
       
  2231 d3.transition = function(selection) {
       
  2232   return arguments.length
       
  2233       ? (d3_transitionId ? selection.transition() : selection)
       
  2234       : d3_selectionRoot.transition();
       
  2235 };
       
  2236 
       
  2237 d3.transition.prototype = d3_transitionPrototype;
       
  2238 d3_transitionPrototype.select = function(selector) {
       
  2239   var subgroups = [],
       
  2240       subgroup,
       
  2241       subnode,
       
  2242       node;
       
  2243 
       
  2244   if (typeof selector !== "function") selector = d3_selection_selector(selector);
       
  2245 
       
  2246   for (var j = -1, m = this.length; ++j < m;) {
       
  2247     subgroups.push(subgroup = []);
       
  2248     for (var group = this[j], i = -1, n = group.length; ++i < n;) {
       
  2249       if ((node = group[i]) && (subnode = selector.call(node.node, node.node.__data__, i))) {
       
  2250         if ("__data__" in node.node) subnode.__data__ = node.node.__data__;
       
  2251         subgroup.push({node: subnode, delay: node.delay, duration: node.duration});
       
  2252       } else {
       
  2253         subgroup.push(null);
       
  2254       }
       
  2255     }
       
  2256   }
       
  2257 
       
  2258   return d3_transition(subgroups, this.id, this.time).ease(this.ease());
       
  2259 };
       
  2260 d3_transitionPrototype.selectAll = function(selector) {
       
  2261   var subgroups = [],
       
  2262       subgroup,
       
  2263       subnodes,
       
  2264       node;
       
  2265 
       
  2266   if (typeof selector !== "function") selector = d3_selection_selectorAll(selector);
       
  2267 
       
  2268   for (var j = -1, m = this.length; ++j < m;) {
       
  2269     for (var group = this[j], i = -1, n = group.length; ++i < n;) {
       
  2270       if (node = group[i]) {
       
  2271         subnodes = selector.call(node.node, node.node.__data__, i);
       
  2272         subgroups.push(subgroup = []);
       
  2273         for (var k = -1, o = subnodes.length; ++k < o;) {
       
  2274           subgroup.push({node: subnodes[k], delay: node.delay, duration: node.duration});
       
  2275         }
       
  2276       }
       
  2277     }
       
  2278   }
       
  2279 
       
  2280   return d3_transition(subgroups, this.id, this.time).ease(this.ease());
       
  2281 };
       
  2282 d3_transitionPrototype.attr = function(name, value) {
       
  2283   return this.attrTween(name, d3_transitionTween(name, value));
       
  2284 };
       
  2285 
       
  2286 d3_transitionPrototype.attrTween = function(nameNS, tween) {
       
  2287   var name = d3.ns.qualify(nameNS);
       
  2288 
       
  2289   function attrTween(d, i) {
       
  2290     var f = tween.call(this, d, i, this.getAttribute(name));
       
  2291     return f === d3_transitionRemove
       
  2292         ? (this.removeAttribute(name), null)
       
  2293         : f && function(t) { this.setAttribute(name, f(t)); };
       
  2294   }
       
  2295 
       
  2296   function attrTweenNS(d, i) {
       
  2297     var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local));
       
  2298     return f === d3_transitionRemove
       
  2299         ? (this.removeAttributeNS(name.space, name.local), null)
       
  2300         : f && function(t) { this.setAttributeNS(name.space, name.local, f(t)); };
       
  2301   }
       
  2302 
       
  2303   return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween);
       
  2304 };
       
  2305 d3_transitionPrototype.style = function(name, value, priority) {
       
  2306   if (arguments.length < 3) priority = "";
       
  2307   return this.styleTween(name, d3_transitionTween(name, value), priority);
       
  2308 };
       
  2309 
       
  2310 d3_transitionPrototype.styleTween = function(name, tween, priority) {
       
  2311   if (arguments.length < 3) priority = "";
       
  2312   return this.tween("style." + name, function(d, i) {
       
  2313     var f = tween.call(this, d, i, window.getComputedStyle(this, null).getPropertyValue(name));
       
  2314     return f === d3_transitionRemove
       
  2315         ? (this.style.removeProperty(name), null)
       
  2316         : f && function(t) { this.style.setProperty(name, f(t), priority); };
       
  2317   });
       
  2318 };
       
  2319 d3_transitionPrototype.text = function(value) {
       
  2320   return this.tween("text", function(d, i) {
       
  2321     this.textContent = typeof value === "function"
       
  2322         ? value.call(this, d, i)
       
  2323         : value;
       
  2324   });
       
  2325 };
       
  2326 d3_transitionPrototype.remove = function() {
       
  2327   return this.each("end.transition", function() {
       
  2328     var p;
       
  2329     if (!this.__transition__ && (p = this.parentNode)) p.removeChild(this);
       
  2330   });
       
  2331 };
       
  2332 d3_transitionPrototype.delay = function(value) {
       
  2333   var groups = this;
       
  2334   return groups.each(typeof value === "function"
       
  2335       ? function(d, i, j) { groups[j][i].delay = value.apply(this, arguments) | 0; }
       
  2336       : (value = value | 0, function(d, i, j) { groups[j][i].delay = value; }));
       
  2337 };
       
  2338 d3_transitionPrototype.duration = function(value) {
       
  2339   var groups = this;
       
  2340   return groups.each(typeof value === "function"
       
  2341       ? function(d, i, j) { groups[j][i].duration = Math.max(1, value.apply(this, arguments) | 0); }
       
  2342       : (value = Math.max(1, value | 0), function(d, i, j) { groups[j][i].duration = value; }));
       
  2343 };
       
  2344 function d3_transition_each(callback) {
       
  2345   var id = d3_transitionId,
       
  2346       ease = d3_transitionEase,
       
  2347       delay = d3_transitionDelay,
       
  2348       duration = d3_transitionDuration;
       
  2349 
       
  2350   d3_transitionId = this.id;
       
  2351   d3_transitionEase = this.ease();
       
  2352   for (var j = 0, m = this.length; j < m; j++) {
       
  2353     for (var group = this[j], i = 0, n = group.length; i < n; i++) {
       
  2354       var node = group[i];
       
  2355       if (node) {
       
  2356         d3_transitionDelay = this[j][i].delay;
       
  2357         d3_transitionDuration = this[j][i].duration;
       
  2358         callback.call(node = node.node, node.__data__, i, j);
       
  2359       }
       
  2360     }
       
  2361   }
       
  2362 
       
  2363   d3_transitionId = id;
       
  2364   d3_transitionEase = ease;
       
  2365   d3_transitionDelay = delay;
       
  2366   d3_transitionDuration = duration;
       
  2367   return this;
       
  2368 }
       
  2369 d3_transitionPrototype.transition = function() {
       
  2370   return this.select(d3_this);
       
  2371 };
       
  2372 var d3_timer_queue = null,
       
  2373     d3_timer_interval, // is an interval (or frame) active?
       
  2374     d3_timer_timeout; // is a timeout active?
       
  2375 
       
  2376 // The timer will continue to fire until callback returns true.
       
  2377 d3.timer = function(callback, delay, then) {
       
  2378   var found = false,
       
  2379       t0,
       
  2380       t1 = d3_timer_queue;
       
  2381 
       
  2382   if (arguments.length < 3) {
       
  2383     if (arguments.length < 2) delay = 0;
       
  2384     else if (!isFinite(delay)) return;
       
  2385     then = Date.now();
       
  2386   }
       
  2387 
       
  2388   // See if the callback's already in the queue.
       
  2389   while (t1) {
       
  2390     if (t1.callback === callback) {
       
  2391       t1.then = then;
       
  2392       t1.delay = delay;
       
  2393       found = true;
       
  2394       break;
       
  2395     }
       
  2396     t0 = t1;
       
  2397     t1 = t1.next;
       
  2398   }
       
  2399 
       
  2400   // Otherwise, add the callback to the queue.
       
  2401   if (!found) d3_timer_queue = {
       
  2402     callback: callback,
       
  2403     then: then,
       
  2404     delay: delay,
       
  2405     next: d3_timer_queue
       
  2406   };
       
  2407 
       
  2408   // Start animatin'!
       
  2409   if (!d3_timer_interval) {
       
  2410     d3_timer_timeout = clearTimeout(d3_timer_timeout);
       
  2411     d3_timer_interval = 1;
       
  2412     d3_timer_frame(d3_timer_step);
       
  2413   }
       
  2414 }
       
  2415 
       
  2416 function d3_timer_step() {
       
  2417   var elapsed,
       
  2418       now = Date.now(),
       
  2419       t1 = d3_timer_queue;
       
  2420 
       
  2421   while (t1) {
       
  2422     elapsed = now - t1.then;
       
  2423     if (elapsed >= t1.delay) t1.flush = t1.callback(elapsed);
       
  2424     t1 = t1.next;
       
  2425   }
       
  2426 
       
  2427   var delay = d3_timer_flush() - now;
       
  2428   if (delay > 24) {
       
  2429     if (isFinite(delay)) {
       
  2430       clearTimeout(d3_timer_timeout);
       
  2431       d3_timer_timeout = setTimeout(d3_timer_step, delay);
       
  2432     }
       
  2433     d3_timer_interval = 0;
       
  2434   } else {
       
  2435     d3_timer_interval = 1;
       
  2436     d3_timer_frame(d3_timer_step);
       
  2437   }
       
  2438 }
       
  2439 
       
  2440 d3.timer.flush = function() {
       
  2441   var elapsed,
       
  2442       now = Date.now(),
       
  2443       t1 = d3_timer_queue;
       
  2444 
       
  2445   while (t1) {
       
  2446     elapsed = now - t1.then;
       
  2447     if (!t1.delay) t1.flush = t1.callback(elapsed);
       
  2448     t1 = t1.next;
       
  2449   }
       
  2450 
       
  2451   d3_timer_flush();
       
  2452 };
       
  2453 
       
  2454 // Flush after callbacks, to avoid concurrent queue modification.
       
  2455 function d3_timer_flush() {
       
  2456   var t0 = null,
       
  2457       t1 = d3_timer_queue,
       
  2458       then = Infinity;
       
  2459   while (t1) {
       
  2460     if (t1.flush) {
       
  2461       t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next;
       
  2462     } else {
       
  2463       then = Math.min(then, t1.then + t1.delay);
       
  2464       t1 = (t0 = t1).next;
       
  2465     }
       
  2466   }
       
  2467   return then;
       
  2468 }
       
  2469 
       
  2470 var d3_timer_frame = window.requestAnimationFrame
       
  2471     || window.webkitRequestAnimationFrame
       
  2472     || window.mozRequestAnimationFrame
       
  2473     || window.oRequestAnimationFrame
       
  2474     || window.msRequestAnimationFrame
       
  2475     || function(callback) { setTimeout(callback, 17); };
       
  2476 d3.transform = function(string) {
       
  2477   var g = document.createElementNS(d3.ns.prefix.svg, "g"),
       
  2478       identity = {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0};
       
  2479   return (d3.transform = function(string) {
       
  2480     g.setAttribute("transform", string);
       
  2481     var t = g.transform.baseVal.consolidate();
       
  2482     return new d3_transform(t ? t.matrix : identity);
       
  2483   })(string);
       
  2484 };
       
  2485 
       
  2486 // Compute x-scale and normalize the first row.
       
  2487 // Compute shear and make second row orthogonal to first.
       
  2488 // Compute y-scale and normalize the second row.
       
  2489 // Finally, compute the rotation.
       
  2490 function d3_transform(m) {
       
  2491   var r0 = [m.a, m.b],
       
  2492       r1 = [m.c, m.d],
       
  2493       kx = d3_transformNormalize(r0),
       
  2494       kz = d3_transformDot(r0, r1),
       
  2495       ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;
       
  2496   if (r0[0] * r1[1] < r1[0] * r0[1]) {
       
  2497     r0[0] *= -1;
       
  2498     r0[1] *= -1;
       
  2499     kx *= -1;
       
  2500     kz *= -1;
       
  2501   }
       
  2502   this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_transformDegrees;
       
  2503   this.translate = [m.e, m.f];
       
  2504   this.scale = [kx, ky];
       
  2505   this.skew = ky ? Math.atan2(kz, ky) * d3_transformDegrees : 0;
       
  2506 };
       
  2507 
       
  2508 d3_transform.prototype.toString = function() {
       
  2509   return "translate(" + this.translate
       
  2510       + ")rotate(" + this.rotate
       
  2511       + ")skewX(" + this.skew
       
  2512       + ")scale(" + this.scale
       
  2513       + ")";
       
  2514 };
       
  2515 
       
  2516 function d3_transformDot(a, b) {
       
  2517   return a[0] * b[0] + a[1] * b[1];
       
  2518 }
       
  2519 
       
  2520 function d3_transformNormalize(a) {
       
  2521   var k = Math.sqrt(d3_transformDot(a, a));
       
  2522   if (k) {
       
  2523     a[0] /= k;
       
  2524     a[1] /= k;
       
  2525   }
       
  2526   return k;
       
  2527 }
       
  2528 
       
  2529 function d3_transformCombine(a, b, k) {
       
  2530   a[0] += k * b[0];
       
  2531   a[1] += k * b[1];
       
  2532   return a;
       
  2533 }
       
  2534 
       
  2535 var d3_transformDegrees = 180 / Math.PI;
       
  2536 d3.mouse = function(container) {
       
  2537   return d3_mousePoint(container, d3_eventSource());
       
  2538 };
       
  2539 
       
  2540 // https://bugs.webkit.org/show_bug.cgi?id=44083
       
  2541 var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0;
       
  2542 
       
  2543 function d3_mousePoint(container, e) {
       
  2544   var svg = container.ownerSVGElement || container;
       
  2545   if (svg.createSVGPoint) {
       
  2546     var point = svg.createSVGPoint();
       
  2547     if ((d3_mouse_bug44083 < 0) && (window.scrollX || window.scrollY)) {
       
  2548       svg = d3.select(document.body)
       
  2549         .append("svg")
       
  2550           .style("position", "absolute")
       
  2551           .style("top", 0)
       
  2552           .style("left", 0);
       
  2553       var ctm = svg[0][0].getScreenCTM();
       
  2554       d3_mouse_bug44083 = !(ctm.f || ctm.e);
       
  2555       svg.remove();
       
  2556     }
       
  2557     if (d3_mouse_bug44083) {
       
  2558       point.x = e.pageX;
       
  2559       point.y = e.pageY;
       
  2560     } else {
       
  2561       point.x = e.clientX;
       
  2562       point.y = e.clientY;
       
  2563     }
       
  2564     point = point.matrixTransform(container.getScreenCTM().inverse());
       
  2565     return [point.x, point.y];
       
  2566   }
       
  2567   var rect = container.getBoundingClientRect();
       
  2568   return [e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop];
       
  2569 };
       
  2570 d3.touches = function(container, touches) {
       
  2571   if (arguments.length < 2) touches = d3_eventSource().touches;
       
  2572   return touches ? d3_array(touches).map(function(touch) {
       
  2573     var point = d3_mousePoint(container, touch);
       
  2574     point.identifier = touch.identifier;
       
  2575     return point;
       
  2576   }) : [];
       
  2577 };
       
  2578 function d3_noop() {}
       
  2579 d3.scale = {};
       
  2580 
       
  2581 function d3_scaleExtent(domain) {
       
  2582   var start = domain[0], stop = domain[domain.length - 1];
       
  2583   return start < stop ? [start, stop] : [stop, start];
       
  2584 }
       
  2585 
       
  2586 function d3_scaleRange(scale) {
       
  2587   return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range());
       
  2588 }
       
  2589 function d3_scale_nice(domain, nice) {
       
  2590   var i0 = 0,
       
  2591       i1 = domain.length - 1,
       
  2592       x0 = domain[i0],
       
  2593       x1 = domain[i1],
       
  2594       dx;
       
  2595 
       
  2596   if (x1 < x0) {
       
  2597     dx = i0; i0 = i1; i1 = dx;
       
  2598     dx = x0; x0 = x1; x1 = dx;
       
  2599   }
       
  2600 
       
  2601   if (dx = x1 - x0) {
       
  2602     nice = nice(dx);
       
  2603     domain[i0] = nice.floor(x0);
       
  2604     domain[i1] = nice.ceil(x1);
       
  2605   }
       
  2606 
       
  2607   return domain;
       
  2608 }
       
  2609 
       
  2610 function d3_scale_niceDefault() {
       
  2611   return Math;
       
  2612 }
       
  2613 d3.scale.linear = function() {
       
  2614   return d3_scale_linear([0, 1], [0, 1], d3.interpolate, false);
       
  2615 };
       
  2616 
       
  2617 function d3_scale_linear(domain, range, interpolate, clamp) {
       
  2618   var output,
       
  2619       input;
       
  2620 
       
  2621   function rescale() {
       
  2622     var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear,
       
  2623         uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
       
  2624     output = linear(domain, range, uninterpolate, interpolate);
       
  2625     input = linear(range, domain, uninterpolate, d3.interpolate);
       
  2626     return scale;
       
  2627   }
       
  2628 
       
  2629   function scale(x) {
       
  2630     return output(x);
       
  2631   }
       
  2632 
       
  2633   // Note: requires range is coercible to number!
       
  2634   scale.invert = function(y) {
       
  2635     return input(y);
       
  2636   };
       
  2637 
       
  2638   scale.domain = function(x) {
       
  2639     if (!arguments.length) return domain;
       
  2640     domain = x.map(Number);
       
  2641     return rescale();
       
  2642   };
       
  2643 
       
  2644   scale.range = function(x) {
       
  2645     if (!arguments.length) return range;
       
  2646     range = x;
       
  2647     return rescale();
       
  2648   };
       
  2649 
       
  2650   scale.rangeRound = function(x) {
       
  2651     return scale.range(x).interpolate(d3.interpolateRound);
       
  2652   };
       
  2653 
       
  2654   scale.clamp = function(x) {
       
  2655     if (!arguments.length) return clamp;
       
  2656     clamp = x;
       
  2657     return rescale();
       
  2658   };
       
  2659 
       
  2660   scale.interpolate = function(x) {
       
  2661     if (!arguments.length) return interpolate;
       
  2662     interpolate = x;
       
  2663     return rescale();
       
  2664   };
       
  2665 
       
  2666   scale.ticks = function(m) {
       
  2667     return d3_scale_linearTicks(domain, m);
       
  2668   };
       
  2669 
       
  2670   scale.tickFormat = function(m) {
       
  2671     return d3_scale_linearTickFormat(domain, m);
       
  2672   };
       
  2673 
       
  2674   scale.nice = function() {
       
  2675     d3_scale_nice(domain, d3_scale_linearNice);
       
  2676     return rescale();
       
  2677   };
       
  2678 
       
  2679   scale.copy = function() {
       
  2680     return d3_scale_linear(domain, range, interpolate, clamp);
       
  2681   };
       
  2682 
       
  2683   return rescale();
       
  2684 }
       
  2685 
       
  2686 function d3_scale_linearRebind(scale, linear) {
       
  2687   return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp");
       
  2688 }
       
  2689 
       
  2690 function d3_scale_linearNice(dx) {
       
  2691   dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1);
       
  2692   return {
       
  2693     floor: function(x) { return Math.floor(x / dx) * dx; },
       
  2694     ceil: function(x) { return Math.ceil(x / dx) * dx; }
       
  2695   };
       
  2696 }
       
  2697 
       
  2698 function d3_scale_linearTickRange(domain, m) {
       
  2699   var extent = d3_scaleExtent(domain),
       
  2700       span = extent[1] - extent[0],
       
  2701       step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)),
       
  2702       err = m / span * step;
       
  2703 
       
  2704   // Filter ticks to get closer to the desired count.
       
  2705   if (err <= .15) step *= 10;
       
  2706   else if (err <= .35) step *= 5;
       
  2707   else if (err <= .75) step *= 2;
       
  2708 
       
  2709   // Round start and stop values to step interval.
       
  2710   extent[0] = Math.ceil(extent[0] / step) * step;
       
  2711   extent[1] = Math.floor(extent[1] / step) * step + step * .5; // inclusive
       
  2712   extent[2] = step;
       
  2713   return extent;
       
  2714 }
       
  2715 
       
  2716 function d3_scale_linearTicks(domain, m) {
       
  2717   return d3.range.apply(d3, d3_scale_linearTickRange(domain, m));
       
  2718 }
       
  2719 
       
  2720 function d3_scale_linearTickFormat(domain, m) {
       
  2721   return d3.format(",." + Math.max(0, -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01)) + "f");
       
  2722 }
       
  2723 function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
       
  2724   var u = uninterpolate(domain[0], domain[1]),
       
  2725       i = interpolate(range[0], range[1]);
       
  2726   return function(x) {
       
  2727     return i(u(x));
       
  2728   };
       
  2729 }
       
  2730 function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
       
  2731   var u = [],
       
  2732       i = [],
       
  2733       j = 0,
       
  2734       k = Math.min(domain.length, range.length) - 1;
       
  2735 
       
  2736   // Handle descending domains.
       
  2737   if (domain[k] < domain[0]) {
       
  2738     domain = domain.slice().reverse();
       
  2739     range = range.slice().reverse();
       
  2740   }
       
  2741 
       
  2742   while (++j <= k) {
       
  2743     u.push(uninterpolate(domain[j - 1], domain[j]));
       
  2744     i.push(interpolate(range[j - 1], range[j]));
       
  2745   }
       
  2746 
       
  2747   return function(x) {
       
  2748     var j = d3.bisect(domain, x, 1, k) - 1;
       
  2749     return i[j](u[j](x));
       
  2750   };
       
  2751 }
       
  2752 d3.scale.log = function() {
       
  2753   return d3_scale_log(d3.scale.linear(), d3_scale_logp);
       
  2754 };
       
  2755 
       
  2756 function d3_scale_log(linear, log) {
       
  2757   var pow = log.pow;
       
  2758 
       
  2759   function scale(x) {
       
  2760     return linear(log(x));
       
  2761   }
       
  2762 
       
  2763   scale.invert = function(x) {
       
  2764     return pow(linear.invert(x));
       
  2765   };
       
  2766 
       
  2767   scale.domain = function(x) {
       
  2768     if (!arguments.length) return linear.domain().map(pow);
       
  2769     log = x[0] < 0 ? d3_scale_logn : d3_scale_logp;
       
  2770     pow = log.pow;
       
  2771     linear.domain(x.map(log));
       
  2772     return scale;
       
  2773   };
       
  2774 
       
  2775   scale.nice = function() {
       
  2776     linear.domain(d3_scale_nice(linear.domain(), d3_scale_niceDefault));
       
  2777     return scale;
       
  2778   };
       
  2779 
       
  2780   scale.ticks = function() {
       
  2781     var extent = d3_scaleExtent(linear.domain()),
       
  2782         ticks = [];
       
  2783     if (extent.every(isFinite)) {
       
  2784       var i = Math.floor(extent[0]),
       
  2785           j = Math.ceil(extent[1]),
       
  2786           u = pow(extent[0]),
       
  2787           v = pow(extent[1]);
       
  2788       if (log === d3_scale_logn) {
       
  2789         ticks.push(pow(i));
       
  2790         for (; i++ < j;) for (var k = 9; k > 0; k--) ticks.push(pow(i) * k);
       
  2791       } else {
       
  2792         for (; i < j; i++) for (var k = 1; k < 10; k++) ticks.push(pow(i) * k);
       
  2793         ticks.push(pow(i));
       
  2794       }
       
  2795       for (i = 0; ticks[i] < u; i++) {} // strip small values
       
  2796       for (j = ticks.length; ticks[j - 1] > v; j--) {} // strip big values
       
  2797       ticks = ticks.slice(i, j);
       
  2798     }
       
  2799     return ticks;
       
  2800   };
       
  2801 
       
  2802   scale.tickFormat = function(n, format) {
       
  2803     if (arguments.length < 2) format = d3_scale_logFormat;
       
  2804     if (arguments.length < 1) return format;
       
  2805     var k = n / scale.ticks().length,
       
  2806         f = log === d3_scale_logn ? (e = -1e-12, Math.floor) : (e = 1e-12, Math.ceil),
       
  2807         e;
       
  2808     return function(d) {
       
  2809       return d / pow(f(log(d) + e)) < k ? format(d) : "";
       
  2810     };
       
  2811   };
       
  2812 
       
  2813   scale.copy = function() {
       
  2814     return d3_scale_log(linear.copy(), log);
       
  2815   };
       
  2816 
       
  2817   return d3_scale_linearRebind(scale, linear);
       
  2818 }
       
  2819 
       
  2820 var d3_scale_logFormat = d3.format(".0e");
       
  2821 
       
  2822 function d3_scale_logp(x) {
       
  2823   return Math.log(x < 0 ? 0 : x) / Math.LN10;
       
  2824 }
       
  2825 
       
  2826 function d3_scale_logn(x) {
       
  2827   return -Math.log(x > 0 ? 0 : -x) / Math.LN10;
       
  2828 }
       
  2829 
       
  2830 d3_scale_logp.pow = function(x) {
       
  2831   return Math.pow(10, x);
       
  2832 };
       
  2833 
       
  2834 d3_scale_logn.pow = function(x) {
       
  2835   return -Math.pow(10, -x);
       
  2836 };
       
  2837 d3.scale.pow = function() {
       
  2838   return d3_scale_pow(d3.scale.linear(), 1);
       
  2839 };
       
  2840 
       
  2841 function d3_scale_pow(linear, exponent) {
       
  2842   var powp = d3_scale_powPow(exponent),
       
  2843       powb = d3_scale_powPow(1 / exponent);
       
  2844 
       
  2845   function scale(x) {
       
  2846     return linear(powp(x));
       
  2847   }
       
  2848 
       
  2849   scale.invert = function(x) {
       
  2850     return powb(linear.invert(x));
       
  2851   };
       
  2852 
       
  2853   scale.domain = function(x) {
       
  2854     if (!arguments.length) return linear.domain().map(powb);
       
  2855     linear.domain(x.map(powp));
       
  2856     return scale;
       
  2857   };
       
  2858 
       
  2859   scale.ticks = function(m) {
       
  2860     return d3_scale_linearTicks(scale.domain(), m);
       
  2861   };
       
  2862 
       
  2863   scale.tickFormat = function(m) {
       
  2864     return d3_scale_linearTickFormat(scale.domain(), m);
       
  2865   };
       
  2866 
       
  2867   scale.nice = function() {
       
  2868     return scale.domain(d3_scale_nice(scale.domain(), d3_scale_linearNice));
       
  2869   };
       
  2870 
       
  2871   scale.exponent = function(x) {
       
  2872     if (!arguments.length) return exponent;
       
  2873     var domain = scale.domain();
       
  2874     powp = d3_scale_powPow(exponent = x);
       
  2875     powb = d3_scale_powPow(1 / exponent);
       
  2876     return scale.domain(domain);
       
  2877   };
       
  2878 
       
  2879   scale.copy = function() {
       
  2880     return d3_scale_pow(linear.copy(), exponent);
       
  2881   };
       
  2882 
       
  2883   return d3_scale_linearRebind(scale, linear);
       
  2884 }
       
  2885 
       
  2886 function d3_scale_powPow(e) {
       
  2887   return function(x) {
       
  2888     return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e);
       
  2889   };
       
  2890 }
       
  2891 d3.scale.sqrt = function() {
       
  2892   return d3.scale.pow().exponent(.5);
       
  2893 };
       
  2894 d3.scale.ordinal = function() {
       
  2895   return d3_scale_ordinal([], {t: "range", x: []});
       
  2896 };
       
  2897 
       
  2898 function d3_scale_ordinal(domain, ranger) {
       
  2899   var index,
       
  2900       range,
       
  2901       rangeBand;
       
  2902 
       
  2903   function scale(x) {
       
  2904     return range[((index.get(x) || index.set(x, domain.push(x))) - 1) % range.length];
       
  2905   }
       
  2906 
       
  2907   function steps(start, step) {
       
  2908     return d3.range(domain.length).map(function(i) { return start + step * i; });
       
  2909   }
       
  2910 
       
  2911   scale.domain = function(x) {
       
  2912     if (!arguments.length) return domain;
       
  2913     domain = [];
       
  2914     index = new d3_Map;
       
  2915     var i = -1, n = x.length, xi;
       
  2916     while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi));
       
  2917     return scale[ranger.t](ranger.x, ranger.p);
       
  2918   };
       
  2919 
       
  2920   scale.range = function(x) {
       
  2921     if (!arguments.length) return range;
       
  2922     range = x;
       
  2923     rangeBand = 0;
       
  2924     ranger = {t: "range", x: x};
       
  2925     return scale;
       
  2926   };
       
  2927 
       
  2928   scale.rangePoints = function(x, padding) {
       
  2929     if (arguments.length < 2) padding = 0;
       
  2930     var start = x[0],
       
  2931         stop = x[1],
       
  2932         step = (stop - start) / (domain.length - 1 + padding);
       
  2933     range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step);
       
  2934     rangeBand = 0;
       
  2935     ranger = {t: "rangePoints", x: x, p: padding};
       
  2936     return scale;
       
  2937   };
       
  2938 
       
  2939   scale.rangeBands = function(x, padding) {
       
  2940     if (arguments.length < 2) padding = 0;
       
  2941     var reverse = x[1] < x[0],
       
  2942         start = x[reverse - 0],
       
  2943         stop = x[1 - reverse],
       
  2944         step = (stop - start) / (domain.length + padding);
       
  2945     range = steps(start + step * padding, step);
       
  2946     if (reverse) range.reverse();
       
  2947     rangeBand = step * (1 - padding);
       
  2948     ranger = {t: "rangeBands", x: x, p: padding};
       
  2949     return scale;
       
  2950   };
       
  2951 
       
  2952   scale.rangeRoundBands = function(x, padding) {
       
  2953     if (arguments.length < 2) padding = 0;
       
  2954     var reverse = x[1] < x[0],
       
  2955         start = x[reverse - 0],
       
  2956         stop = x[1 - reverse],
       
  2957         step = Math.floor((stop - start) / (domain.length + padding)),
       
  2958         error = stop - start - (domain.length - padding) * step;
       
  2959     range = steps(start + Math.round(error / 2), step);
       
  2960     if (reverse) range.reverse();
       
  2961     rangeBand = Math.round(step * (1 - padding));
       
  2962     ranger = {t: "rangeRoundBands", x: x, p: padding};
       
  2963     return scale;
       
  2964   };
       
  2965 
       
  2966   scale.rangeBand = function() {
       
  2967     return rangeBand;
       
  2968   };
       
  2969 
       
  2970   scale.rangeExtent = function() {
       
  2971     return d3_scaleExtent(ranger.x);
       
  2972   };
       
  2973 
       
  2974   scale.copy = function() {
       
  2975     return d3_scale_ordinal(domain, ranger);
       
  2976   };
       
  2977 
       
  2978   return scale.domain(domain);
       
  2979 }
       
  2980 /*
       
  2981  * This product includes color specifications and designs developed by Cynthia
       
  2982  * Brewer (http://colorbrewer.org/). See lib/colorbrewer for more information.
       
  2983  */
       
  2984 
       
  2985 d3.scale.category10 = function() {
       
  2986   return d3.scale.ordinal().range(d3_category10);
       
  2987 };
       
  2988 
       
  2989 d3.scale.category20 = function() {
       
  2990   return d3.scale.ordinal().range(d3_category20);
       
  2991 };
       
  2992 
       
  2993 d3.scale.category20b = function() {
       
  2994   return d3.scale.ordinal().range(d3_category20b);
       
  2995 };
       
  2996 
       
  2997 d3.scale.category20c = function() {
       
  2998   return d3.scale.ordinal().range(d3_category20c);
       
  2999 };
       
  3000 
       
  3001 var d3_category10 = [
       
  3002   "#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd",
       
  3003   "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf"
       
  3004 ];
       
  3005 
       
  3006 var d3_category20 = [
       
  3007   "#1f77b4", "#aec7e8",
       
  3008   "#ff7f0e", "#ffbb78",
       
  3009   "#2ca02c", "#98df8a",
       
  3010   "#d62728", "#ff9896",
       
  3011   "#9467bd", "#c5b0d5",
       
  3012   "#8c564b", "#c49c94",
       
  3013   "#e377c2", "#f7b6d2",
       
  3014   "#7f7f7f", "#c7c7c7",
       
  3015   "#bcbd22", "#dbdb8d",
       
  3016   "#17becf", "#9edae5"
       
  3017 ];
       
  3018 
       
  3019 var d3_category20b = [
       
  3020   "#393b79", "#5254a3", "#6b6ecf", "#9c9ede",
       
  3021   "#637939", "#8ca252", "#b5cf6b", "#cedb9c",
       
  3022   "#8c6d31", "#bd9e39", "#e7ba52", "#e7cb94",
       
  3023   "#843c39", "#ad494a", "#d6616b", "#e7969c",
       
  3024   "#7b4173", "#a55194", "#ce6dbd", "#de9ed6"
       
  3025 ];
       
  3026 
       
  3027 var d3_category20c = [
       
  3028   "#3182bd", "#6baed6", "#9ecae1", "#c6dbef",
       
  3029   "#e6550d", "#fd8d3c", "#fdae6b", "#fdd0a2",
       
  3030   "#31a354", "#74c476", "#a1d99b", "#c7e9c0",
       
  3031   "#756bb1", "#9e9ac8", "#bcbddc", "#dadaeb",
       
  3032   "#636363", "#969696", "#bdbdbd", "#d9d9d9"
       
  3033 ];
       
  3034 d3.scale.quantile = function() {
       
  3035   return d3_scale_quantile([], []);
       
  3036 };
       
  3037 
       
  3038 function d3_scale_quantile(domain, range) {
       
  3039   var thresholds;
       
  3040 
       
  3041   function rescale() {
       
  3042     var k = 0,
       
  3043         n = domain.length,
       
  3044         q = range.length;
       
  3045     thresholds = [];
       
  3046     while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q);
       
  3047     return scale;
       
  3048   }
       
  3049 
       
  3050   function scale(x) {
       
  3051     if (isNaN(x = +x)) return NaN;
       
  3052     return range[d3.bisect(thresholds, x)];
       
  3053   }
       
  3054 
       
  3055   scale.domain = function(x) {
       
  3056     if (!arguments.length) return domain;
       
  3057     domain = x.filter(function(d) { return !isNaN(d); }).sort(d3.ascending);
       
  3058     return rescale();
       
  3059   };
       
  3060 
       
  3061   scale.range = function(x) {
       
  3062     if (!arguments.length) return range;
       
  3063     range = x;
       
  3064     return rescale();
       
  3065   };
       
  3066 
       
  3067   scale.quantiles = function() {
       
  3068     return thresholds;
       
  3069   };
       
  3070 
       
  3071   scale.copy = function() {
       
  3072     return d3_scale_quantile(domain, range); // copy on write!
       
  3073   };
       
  3074 
       
  3075   return rescale();
       
  3076 }
       
  3077 d3.scale.quantize = function() {
       
  3078   return d3_scale_quantize(0, 1, [0, 1]);
       
  3079 };
       
  3080 
       
  3081 function d3_scale_quantize(x0, x1, range) {
       
  3082   var kx, i;
       
  3083 
       
  3084   function scale(x) {
       
  3085     return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))];
       
  3086   }
       
  3087 
       
  3088   function rescale() {
       
  3089     kx = range.length / (x1 - x0);
       
  3090     i = range.length - 1;
       
  3091     return scale;
       
  3092   }
       
  3093 
       
  3094   scale.domain = function(x) {
       
  3095     if (!arguments.length) return [x0, x1];
       
  3096     x0 = +x[0];
       
  3097     x1 = +x[x.length - 1];
       
  3098     return rescale();
       
  3099   };
       
  3100 
       
  3101   scale.range = function(x) {
       
  3102     if (!arguments.length) return range;
       
  3103     range = x;
       
  3104     return rescale();
       
  3105   };
       
  3106 
       
  3107   scale.copy = function() {
       
  3108     return d3_scale_quantize(x0, x1, range); // copy on write
       
  3109   };
       
  3110 
       
  3111   return rescale();
       
  3112 }
       
  3113 d3.scale.identity = function() {
       
  3114   return d3_scale_identity([0, 1]);
       
  3115 };
       
  3116 
       
  3117 function d3_scale_identity(domain) {
       
  3118 
       
  3119   function identity(x) { return +x; }
       
  3120 
       
  3121   identity.invert = identity;
       
  3122 
       
  3123   identity.domain = identity.range = function(x) {
       
  3124     if (!arguments.length) return domain;
       
  3125     domain = x.map(identity);
       
  3126     return identity;
       
  3127   };
       
  3128 
       
  3129   identity.ticks = function(m) {
       
  3130     return d3_scale_linearTicks(domain, m);
       
  3131   };
       
  3132 
       
  3133   identity.tickFormat = function(m) {
       
  3134     return d3_scale_linearTickFormat(domain, m);
       
  3135   };
       
  3136 
       
  3137   identity.copy = function() {
       
  3138     return d3_scale_identity(domain);
       
  3139   };
       
  3140 
       
  3141   return identity;
       
  3142 }
       
  3143 d3.svg = {};
       
  3144 d3.svg.arc = function() {
       
  3145   var innerRadius = d3_svg_arcInnerRadius,
       
  3146       outerRadius = d3_svg_arcOuterRadius,
       
  3147       startAngle = d3_svg_arcStartAngle,
       
  3148       endAngle = d3_svg_arcEndAngle;
       
  3149 
       
  3150   function arc() {
       
  3151     var r0 = innerRadius.apply(this, arguments),
       
  3152         r1 = outerRadius.apply(this, arguments),
       
  3153         a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset,
       
  3154         a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset,
       
  3155         da = (a1 < a0 && (da = a0, a0 = a1, a1 = da), a1 - a0),
       
  3156         df = da < Math.PI ? "0" : "1",
       
  3157         c0 = Math.cos(a0),
       
  3158         s0 = Math.sin(a0),
       
  3159         c1 = Math.cos(a1),
       
  3160         s1 = Math.sin(a1);
       
  3161     return da >= d3_svg_arcMax
       
  3162       ? (r0
       
  3163       ? "M0," + r1
       
  3164       + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1)
       
  3165       + "A" + r1 + "," + r1 + " 0 1,1 0," + r1
       
  3166       + "M0," + r0
       
  3167       + "A" + r0 + "," + r0 + " 0 1,0 0," + (-r0)
       
  3168       + "A" + r0 + "," + r0 + " 0 1,0 0," + r0
       
  3169       + "Z"
       
  3170       : "M0," + r1
       
  3171       + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1)
       
  3172       + "A" + r1 + "," + r1 + " 0 1,1 0," + r1
       
  3173       + "Z")
       
  3174       : (r0
       
  3175       ? "M" + r1 * c0 + "," + r1 * s0
       
  3176       + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1
       
  3177       + "L" + r0 * c1 + "," + r0 * s1
       
  3178       + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0
       
  3179       + "Z"
       
  3180       : "M" + r1 * c0 + "," + r1 * s0
       
  3181       + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1
       
  3182       + "L0,0"
       
  3183       + "Z");
       
  3184   }
       
  3185 
       
  3186   arc.innerRadius = function(v) {
       
  3187     if (!arguments.length) return innerRadius;
       
  3188     innerRadius = d3.functor(v);
       
  3189     return arc;
       
  3190   };
       
  3191 
       
  3192   arc.outerRadius = function(v) {
       
  3193     if (!arguments.length) return outerRadius;
       
  3194     outerRadius = d3.functor(v);
       
  3195     return arc;
       
  3196   };
       
  3197 
       
  3198   arc.startAngle = function(v) {
       
  3199     if (!arguments.length) return startAngle;
       
  3200     startAngle = d3.functor(v);
       
  3201     return arc;
       
  3202   };
       
  3203 
       
  3204   arc.endAngle = function(v) {
       
  3205     if (!arguments.length) return endAngle;
       
  3206     endAngle = d3.functor(v);
       
  3207     return arc;
       
  3208   };
       
  3209 
       
  3210   arc.centroid = function() {
       
  3211     var r = (innerRadius.apply(this, arguments)
       
  3212         + outerRadius.apply(this, arguments)) / 2,
       
  3213         a = (startAngle.apply(this, arguments)
       
  3214         + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset;
       
  3215     return [Math.cos(a) * r, Math.sin(a) * r];
       
  3216   };
       
  3217 
       
  3218   return arc;
       
  3219 };
       
  3220 
       
  3221 var d3_svg_arcOffset = -Math.PI / 2,
       
  3222     d3_svg_arcMax = 2 * Math.PI - 1e-6;
       
  3223 
       
  3224 function d3_svg_arcInnerRadius(d) {
       
  3225   return d.innerRadius;
       
  3226 }
       
  3227 
       
  3228 function d3_svg_arcOuterRadius(d) {
       
  3229   return d.outerRadius;
       
  3230 }
       
  3231 
       
  3232 function d3_svg_arcStartAngle(d) {
       
  3233   return d.startAngle;
       
  3234 }
       
  3235 
       
  3236 function d3_svg_arcEndAngle(d) {
       
  3237   return d.endAngle;
       
  3238 }
       
  3239 function d3_svg_line(projection) {
       
  3240   var x = d3_svg_lineX,
       
  3241       y = d3_svg_lineY,
       
  3242       interpolate = d3_svg_lineInterpolatorDefault,
       
  3243       interpolator = d3_svg_lineInterpolators.get(interpolate),
       
  3244       tension = .7;
       
  3245 
       
  3246   function line(d) {
       
  3247     return d.length < 1 ? null : "M" + interpolator(projection(d3_svg_linePoints(this, d, x, y)), tension);
       
  3248   }
       
  3249 
       
  3250   line.x = function(v) {
       
  3251     if (!arguments.length) return x;
       
  3252     x = v;
       
  3253     return line;
       
  3254   };
       
  3255 
       
  3256   line.y = function(v) {
       
  3257     if (!arguments.length) return y;
       
  3258     y = v;
       
  3259     return line;
       
  3260   };
       
  3261 
       
  3262   line.interpolate = function(v) {
       
  3263     if (!arguments.length) return interpolate;
       
  3264     if (!d3_svg_lineInterpolators.has(v += "")) v = d3_svg_lineInterpolatorDefault;
       
  3265     interpolator = d3_svg_lineInterpolators.get(interpolate = v);
       
  3266     return line;
       
  3267   };
       
  3268 
       
  3269   line.tension = function(v) {
       
  3270     if (!arguments.length) return tension;
       
  3271     tension = v;
       
  3272     return line;
       
  3273   };
       
  3274 
       
  3275   return line;
       
  3276 }
       
  3277 
       
  3278 d3.svg.line = function() {
       
  3279   return d3_svg_line(Object);
       
  3280 };
       
  3281 
       
  3282 // Converts the specified array of data into an array of points
       
  3283 // (x-y tuples), by evaluating the specified `x` and `y` functions on each
       
  3284 // data point. The `this` context of the evaluated functions is the specified
       
  3285 // "self" object; each function is passed the current datum and index.
       
  3286 function d3_svg_linePoints(self, d, x, y) {
       
  3287   var points = [],
       
  3288       i = -1,
       
  3289       n = d.length,
       
  3290       fx = typeof x === "function",
       
  3291       fy = typeof y === "function",
       
  3292       value;
       
  3293   if (fx && fy) {
       
  3294     while (++i < n) points.push([
       
  3295       x.call(self, value = d[i], i),
       
  3296       y.call(self, value, i)
       
  3297     ]);
       
  3298   } else if (fx) {
       
  3299     while (++i < n) points.push([x.call(self, d[i], i), y]);
       
  3300   } else if (fy) {
       
  3301     while (++i < n) points.push([x, y.call(self, d[i], i)]);
       
  3302   } else {
       
  3303     while (++i < n) points.push([x, y]);
       
  3304   }
       
  3305   return points;
       
  3306 }
       
  3307 
       
  3308 // The default `x` property, which references d[0].
       
  3309 function d3_svg_lineX(d) {
       
  3310   return d[0];
       
  3311 }
       
  3312 
       
  3313 // The default `y` property, which references d[1].
       
  3314 function d3_svg_lineY(d) {
       
  3315   return d[1];
       
  3316 }
       
  3317 
       
  3318 var d3_svg_lineInterpolatorDefault = "linear";
       
  3319 
       
  3320 // The various interpolators supported by the `line` class.
       
  3321 var d3_svg_lineInterpolators = d3.map({
       
  3322   "linear": d3_svg_lineLinear,
       
  3323   "step-before": d3_svg_lineStepBefore,
       
  3324   "step-after": d3_svg_lineStepAfter,
       
  3325   "basis": d3_svg_lineBasis,
       
  3326   "basis-open": d3_svg_lineBasisOpen,
       
  3327   "basis-closed": d3_svg_lineBasisClosed,
       
  3328   "bundle": d3_svg_lineBundle,
       
  3329   "cardinal": d3_svg_lineCardinal,
       
  3330   "cardinal-open": d3_svg_lineCardinalOpen,
       
  3331   "cardinal-closed": d3_svg_lineCardinalClosed,
       
  3332   "monotone": d3_svg_lineMonotone
       
  3333 });
       
  3334 
       
  3335 // Linear interpolation; generates "L" commands.
       
  3336 function d3_svg_lineLinear(points) {
       
  3337   var i = 0,
       
  3338       n = points.length,
       
  3339       p = points[0],
       
  3340       path = [p[0], ",", p[1]];
       
  3341   while (++i < n) path.push("L", (p = points[i])[0], ",", p[1]);
       
  3342   return path.join("");
       
  3343 }
       
  3344 
       
  3345 // Step interpolation; generates "H" and "V" commands.
       
  3346 function d3_svg_lineStepBefore(points) {
       
  3347   var i = 0,
       
  3348       n = points.length,
       
  3349       p = points[0],
       
  3350       path = [p[0], ",", p[1]];
       
  3351   while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]);
       
  3352   return path.join("");
       
  3353 }
       
  3354 
       
  3355 // Step interpolation; generates "H" and "V" commands.
       
  3356 function d3_svg_lineStepAfter(points) {
       
  3357   var i = 0,
       
  3358       n = points.length,
       
  3359       p = points[0],
       
  3360       path = [p[0], ",", p[1]];
       
  3361   while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]);
       
  3362   return path.join("");
       
  3363 }
       
  3364 
       
  3365 // Open cardinal spline interpolation; generates "C" commands.
       
  3366 function d3_svg_lineCardinalOpen(points, tension) {
       
  3367   return points.length < 4
       
  3368       ? d3_svg_lineLinear(points)
       
  3369       : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1),
       
  3370         d3_svg_lineCardinalTangents(points, tension));
       
  3371 }
       
  3372 
       
  3373 // Closed cardinal spline interpolation; generates "C" commands.
       
  3374 function d3_svg_lineCardinalClosed(points, tension) {
       
  3375   return points.length < 3
       
  3376       ? d3_svg_lineLinear(points)
       
  3377       : points[0] + d3_svg_lineHermite((points.push(points[0]), points),
       
  3378         d3_svg_lineCardinalTangents([points[points.length - 2]]
       
  3379         .concat(points, [points[1]]), tension));
       
  3380 }
       
  3381 
       
  3382 // Cardinal spline interpolation; generates "C" commands.
       
  3383 function d3_svg_lineCardinal(points, tension, closed) {
       
  3384   return points.length < 3
       
  3385       ? d3_svg_lineLinear(points)
       
  3386       : points[0] + d3_svg_lineHermite(points,
       
  3387         d3_svg_lineCardinalTangents(points, tension));
       
  3388 }
       
  3389 
       
  3390 // Hermite spline construction; generates "C" commands.
       
  3391 function d3_svg_lineHermite(points, tangents) {
       
  3392   if (tangents.length < 1
       
  3393       || (points.length != tangents.length
       
  3394       && points.length != tangents.length + 2)) {
       
  3395     return d3_svg_lineLinear(points);
       
  3396   }
       
  3397 
       
  3398   var quad = points.length != tangents.length,
       
  3399       path = "",
       
  3400       p0 = points[0],
       
  3401       p = points[1],
       
  3402       t0 = tangents[0],
       
  3403       t = t0,
       
  3404       pi = 1;
       
  3405 
       
  3406   if (quad) {
       
  3407     path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3)
       
  3408         + "," + p[0] + "," + p[1];
       
  3409     p0 = points[1];
       
  3410     pi = 2;
       
  3411   }
       
  3412 
       
  3413   if (tangents.length > 1) {
       
  3414     t = tangents[1];
       
  3415     p = points[pi];
       
  3416     pi++;
       
  3417     path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1])
       
  3418         + "," + (p[0] - t[0]) + "," + (p[1] - t[1])
       
  3419         + "," + p[0] + "," + p[1];
       
  3420     for (var i = 2; i < tangents.length; i++, pi++) {
       
  3421       p = points[pi];
       
  3422       t = tangents[i];
       
  3423       path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1])
       
  3424           + "," + p[0] + "," + p[1];
       
  3425     }
       
  3426   }
       
  3427 
       
  3428   if (quad) {
       
  3429     var lp = points[pi];
       
  3430     path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3)
       
  3431         + "," + lp[0] + "," + lp[1];
       
  3432   }
       
  3433 
       
  3434   return path;
       
  3435 }
       
  3436 
       
  3437 // Generates tangents for a cardinal spline.
       
  3438 function d3_svg_lineCardinalTangents(points, tension) {
       
  3439   var tangents = [],
       
  3440       a = (1 - tension) / 2,
       
  3441       p0,
       
  3442       p1 = points[0],
       
  3443       p2 = points[1],
       
  3444       i = 1,
       
  3445       n = points.length;
       
  3446   while (++i < n) {
       
  3447     p0 = p1;
       
  3448     p1 = p2;
       
  3449     p2 = points[i];
       
  3450     tangents.push([a * (p2[0] - p0[0]), a * (p2[1] - p0[1])]);
       
  3451   }
       
  3452   return tangents;
       
  3453 }
       
  3454 
       
  3455 // B-spline interpolation; generates "C" commands.
       
  3456 function d3_svg_lineBasis(points) {
       
  3457   if (points.length < 3) return d3_svg_lineLinear(points);
       
  3458   var i = 1,
       
  3459       n = points.length,
       
  3460       pi = points[0],
       
  3461       x0 = pi[0],
       
  3462       y0 = pi[1],
       
  3463       px = [x0, x0, x0, (pi = points[1])[0]],
       
  3464       py = [y0, y0, y0, pi[1]],
       
  3465       path = [x0, ",", y0];
       
  3466   d3_svg_lineBasisBezier(path, px, py);
       
  3467   while (++i < n) {
       
  3468     pi = points[i];
       
  3469     px.shift(); px.push(pi[0]);
       
  3470     py.shift(); py.push(pi[1]);
       
  3471     d3_svg_lineBasisBezier(path, px, py);
       
  3472   }
       
  3473   i = -1;
       
  3474   while (++i < 2) {
       
  3475     px.shift(); px.push(pi[0]);
       
  3476     py.shift(); py.push(pi[1]);
       
  3477     d3_svg_lineBasisBezier(path, px, py);
       
  3478   }
       
  3479   return path.join("");
       
  3480 }
       
  3481 
       
  3482 // Open B-spline interpolation; generates "C" commands.
       
  3483 function d3_svg_lineBasisOpen(points) {
       
  3484   if (points.length < 4) return d3_svg_lineLinear(points);
       
  3485   var path = [],
       
  3486       i = -1,
       
  3487       n = points.length,
       
  3488       pi,
       
  3489       px = [0],
       
  3490       py = [0];
       
  3491   while (++i < 3) {
       
  3492     pi = points[i];
       
  3493     px.push(pi[0]);
       
  3494     py.push(pi[1]);
       
  3495   }
       
  3496   path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px)
       
  3497     + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py));
       
  3498   --i; while (++i < n) {
       
  3499     pi = points[i];
       
  3500     px.shift(); px.push(pi[0]);
       
  3501     py.shift(); py.push(pi[1]);
       
  3502     d3_svg_lineBasisBezier(path, px, py);
       
  3503   }
       
  3504   return path.join("");
       
  3505 }
       
  3506 
       
  3507 // Closed B-spline interpolation; generates "C" commands.
       
  3508 function d3_svg_lineBasisClosed(points) {
       
  3509   var path,
       
  3510       i = -1,
       
  3511       n = points.length,
       
  3512       m = n + 4,
       
  3513       pi,
       
  3514       px = [],
       
  3515       py = [];
       
  3516   while (++i < 4) {
       
  3517     pi = points[i % n];
       
  3518     px.push(pi[0]);
       
  3519     py.push(pi[1]);
       
  3520   }
       
  3521   path = [
       
  3522     d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",",
       
  3523     d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)
       
  3524   ];
       
  3525   --i; while (++i < m) {
       
  3526     pi = points[i % n];
       
  3527     px.shift(); px.push(pi[0]);
       
  3528     py.shift(); py.push(pi[1]);
       
  3529     d3_svg_lineBasisBezier(path, px, py);
       
  3530   }
       
  3531   return path.join("");
       
  3532 }
       
  3533 
       
  3534 function d3_svg_lineBundle(points, tension) {
       
  3535   var n = points.length - 1,
       
  3536       x0 = points[0][0],
       
  3537       y0 = points[0][1],
       
  3538       dx = points[n][0] - x0,
       
  3539       dy = points[n][1] - y0,
       
  3540       i = -1,
       
  3541       p,
       
  3542       t;
       
  3543   while (++i <= n) {
       
  3544     p = points[i];
       
  3545     t = i / n;
       
  3546     p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx);
       
  3547     p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy);
       
  3548   }
       
  3549   return d3_svg_lineBasis(points);
       
  3550 }
       
  3551 
       
  3552 // Returns the dot product of the given four-element vectors.
       
  3553 function d3_svg_lineDot4(a, b) {
       
  3554   return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
       
  3555 }
       
  3556 
       
  3557 // Matrix to transform basis (b-spline) control points to bezier
       
  3558 // control points. Derived from FvD 11.2.8.
       
  3559 var d3_svg_lineBasisBezier1 = [0, 2/3, 1/3, 0],
       
  3560     d3_svg_lineBasisBezier2 = [0, 1/3, 2/3, 0],
       
  3561     d3_svg_lineBasisBezier3 = [0, 1/6, 2/3, 1/6];
       
  3562 
       
  3563 // Pushes a "C" Bézier curve onto the specified path array, given the
       
  3564 // two specified four-element arrays which define the control points.
       
  3565 function d3_svg_lineBasisBezier(path, x, y) {
       
  3566   path.push(
       
  3567       "C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x),
       
  3568       ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y),
       
  3569       ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x),
       
  3570       ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y),
       
  3571       ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x),
       
  3572       ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y));
       
  3573 }
       
  3574 
       
  3575 // Computes the slope from points p0 to p1.
       
  3576 function d3_svg_lineSlope(p0, p1) {
       
  3577   return (p1[1] - p0[1]) / (p1[0] - p0[0]);
       
  3578 }
       
  3579 
       
  3580 // Compute three-point differences for the given points.
       
  3581 // http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Finite_difference
       
  3582 function d3_svg_lineFiniteDifferences(points) {
       
  3583   var i = 0,
       
  3584       j = points.length - 1,
       
  3585       m = [],
       
  3586       p0 = points[0],
       
  3587       p1 = points[1],
       
  3588       d = m[0] = d3_svg_lineSlope(p0, p1);
       
  3589   while (++i < j) {
       
  3590     m[i] = d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]));
       
  3591   }
       
  3592   m[i] = d;
       
  3593   return m;
       
  3594 }
       
  3595 
       
  3596 // Interpolates the given points using Fritsch-Carlson Monotone cubic Hermite
       
  3597 // interpolation. Returns an array of tangent vectors. For details, see
       
  3598 // http://en.wikipedia.org/wiki/Monotone_cubic_interpolation
       
  3599 function d3_svg_lineMonotoneTangents(points) {
       
  3600   var tangents = [],
       
  3601       d,
       
  3602       a,
       
  3603       b,
       
  3604       s,
       
  3605       m = d3_svg_lineFiniteDifferences(points),
       
  3606       i = -1,
       
  3607       j = points.length - 1;
       
  3608 
       
  3609   // The first two steps are done by computing finite-differences:
       
  3610   // 1. Compute the slopes of the secant lines between successive points.
       
  3611   // 2. Initialize the tangents at every point as the average of the secants.
       
  3612 
       
  3613   // Then, for each segment…
       
  3614   while (++i < j) {
       
  3615     d = d3_svg_lineSlope(points[i], points[i + 1]);
       
  3616 
       
  3617     // 3. If two successive yk = y{k + 1} are equal (i.e., d is zero), then set
       
  3618     // mk = m{k + 1} = 0 as the spline connecting these points must be flat to
       
  3619     // preserve monotonicity. Ignore step 4 and 5 for those k.
       
  3620 
       
  3621     if (Math.abs(d) < 1e-6) {
       
  3622       m[i] = m[i + 1] = 0;
       
  3623     } else {
       
  3624       // 4. Let ak = mk / dk and bk = m{k + 1} / dk.
       
  3625       a = m[i] / d;
       
  3626       b = m[i + 1] / d;
       
  3627 
       
  3628       // 5. Prevent overshoot and ensure monotonicity by restricting the
       
  3629       // magnitude of vector <ak, bk> to a circle of radius 3.
       
  3630       s = a * a + b * b;
       
  3631       if (s > 9) {
       
  3632         s = d * 3 / Math.sqrt(s);
       
  3633         m[i] = s * a;
       
  3634         m[i + 1] = s * b;
       
  3635       }
       
  3636     }
       
  3637   }
       
  3638 
       
  3639   // Compute the normalized tangent vector from the slopes. Note that if x is
       
  3640   // not monotonic, it's possible that the slope will be infinite, so we protect
       
  3641   // against NaN by setting the coordinate to zero.
       
  3642   i = -1; while (++i <= j) {
       
  3643     s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0])
       
  3644       / (6 * (1 + m[i] * m[i]));
       
  3645     tangents.push([s || 0, m[i] * s || 0]);
       
  3646   }
       
  3647 
       
  3648   return tangents;
       
  3649 }
       
  3650 
       
  3651 function d3_svg_lineMonotone(points) {
       
  3652   return points.length < 3
       
  3653       ? d3_svg_lineLinear(points)
       
  3654       : points[0] +
       
  3655         d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points));
       
  3656 }
       
  3657 d3.svg.line.radial = function() {
       
  3658   var line = d3_svg_line(d3_svg_lineRadial);
       
  3659   line.radius = line.x, delete line.x;
       
  3660   line.angle = line.y, delete line.y;
       
  3661   return line;
       
  3662 };
       
  3663 
       
  3664 function d3_svg_lineRadial(points) {
       
  3665   var point,
       
  3666       i = -1,
       
  3667       n = points.length,
       
  3668       r,
       
  3669       a;
       
  3670   while (++i < n) {
       
  3671     point = points[i];
       
  3672     r = point[0];
       
  3673     a = point[1] + d3_svg_arcOffset;
       
  3674     point[0] = r * Math.cos(a);
       
  3675     point[1] = r * Math.sin(a);
       
  3676   }
       
  3677   return points;
       
  3678 }
       
  3679 function d3_svg_area(projection) {
       
  3680   var x0 = d3_svg_lineX,
       
  3681       x1 = d3_svg_lineX,
       
  3682       y0 = 0,
       
  3683       y1 = d3_svg_lineY,
       
  3684       interpolate,
       
  3685       i0,
       
  3686       i1,
       
  3687       tension = .7;
       
  3688 
       
  3689   function area(d) {
       
  3690     if (d.length < 1) return null;
       
  3691     var points0 = d3_svg_linePoints(this, d, x0, y0),
       
  3692         points1 = d3_svg_linePoints(this, d, x0 === x1 ? d3_svg_areaX(points0) : x1, y0 === y1 ? d3_svg_areaY(points0) : y1);
       
  3693     return "M" + i0(projection(points1), tension)
       
  3694          + "L" + i1(projection(points0.reverse()), tension)
       
  3695          + "Z";
       
  3696   }
       
  3697 
       
  3698   area.x = function(x) {
       
  3699     if (!arguments.length) return x1;
       
  3700     x0 = x1 = x;
       
  3701     return area;
       
  3702   };
       
  3703 
       
  3704   area.x0 = function(x) {
       
  3705     if (!arguments.length) return x0;
       
  3706     x0 = x;
       
  3707     return area;
       
  3708   };
       
  3709 
       
  3710   area.x1 = function(x) {
       
  3711     if (!arguments.length) return x1;
       
  3712     x1 = x;
       
  3713     return area;
       
  3714   };
       
  3715 
       
  3716   area.y = function(y) {
       
  3717     if (!arguments.length) return y1;
       
  3718     y0 = y1 = y;
       
  3719     return area;
       
  3720   };
       
  3721 
       
  3722   area.y0 = function(y) {
       
  3723     if (!arguments.length) return y0;
       
  3724     y0 = y;
       
  3725     return area;
       
  3726   };
       
  3727 
       
  3728   area.y1 = function(y) {
       
  3729     if (!arguments.length) return y1;
       
  3730     y1 = y;
       
  3731     return area;
       
  3732   };
       
  3733 
       
  3734   area.interpolate = function(x) {
       
  3735     if (!arguments.length) return interpolate;
       
  3736     if (!d3_svg_lineInterpolators.has(x += "")) x = d3_svg_lineInterpolatorDefault;
       
  3737     i0 = d3_svg_lineInterpolators.get(interpolate = x);
       
  3738     i1 = i0.reverse || i0;
       
  3739     return area;
       
  3740   };
       
  3741 
       
  3742   area.tension = function(x) {
       
  3743     if (!arguments.length) return tension;
       
  3744     tension = x;
       
  3745     return area;
       
  3746   };
       
  3747 
       
  3748   return area.interpolate("linear");
       
  3749 }
       
  3750 
       
  3751 d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter;
       
  3752 d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore;
       
  3753 
       
  3754 d3.svg.area = function() {
       
  3755   return d3_svg_area(Object);
       
  3756 };
       
  3757 
       
  3758 function d3_svg_areaX(points) {
       
  3759   return function(d, i) {
       
  3760     return points[i][0];
       
  3761   };
       
  3762 }
       
  3763 
       
  3764 function d3_svg_areaY(points) {
       
  3765   return function(d, i) {
       
  3766     return points[i][1];
       
  3767   };
       
  3768 }
       
  3769 d3.svg.area.radial = function() {
       
  3770   var area = d3_svg_area(d3_svg_lineRadial);
       
  3771   area.radius = area.x, delete area.x;
       
  3772   area.innerRadius = area.x0, delete area.x0;
       
  3773   area.outerRadius = area.x1, delete area.x1;
       
  3774   area.angle = area.y, delete area.y;
       
  3775   area.startAngle = area.y0, delete area.y0;
       
  3776   area.endAngle = area.y1, delete area.y1;
       
  3777   return area;
       
  3778 };
       
  3779 d3.svg.chord = function() {
       
  3780   var source = d3_svg_chordSource,
       
  3781       target = d3_svg_chordTarget,
       
  3782       radius = d3_svg_chordRadius,
       
  3783       startAngle = d3_svg_arcStartAngle,
       
  3784       endAngle = d3_svg_arcEndAngle;
       
  3785 
       
  3786   // TODO Allow control point to be customized.
       
  3787 
       
  3788   function chord(d, i) {
       
  3789     var s = subgroup(this, source, d, i),
       
  3790         t = subgroup(this, target, d, i);
       
  3791     return "M" + s.p0
       
  3792       + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t)
       
  3793       ? curve(s.r, s.p1, s.r, s.p0)
       
  3794       : curve(s.r, s.p1, t.r, t.p0)
       
  3795       + arc(t.r, t.p1, t.a1 - t.a0)
       
  3796       + curve(t.r, t.p1, s.r, s.p0))
       
  3797       + "Z";
       
  3798   }
       
  3799 
       
  3800   function subgroup(self, f, d, i) {
       
  3801     var subgroup = f.call(self, d, i),
       
  3802         r = radius.call(self, subgroup, i),
       
  3803         a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset,
       
  3804         a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset;
       
  3805     return {
       
  3806       r: r,
       
  3807       a0: a0,
       
  3808       a1: a1,
       
  3809       p0: [r * Math.cos(a0), r * Math.sin(a0)],
       
  3810       p1: [r * Math.cos(a1), r * Math.sin(a1)]
       
  3811     };
       
  3812   }
       
  3813 
       
  3814   function equals(a, b) {
       
  3815     return a.a0 == b.a0 && a.a1 == b.a1;
       
  3816   }
       
  3817 
       
  3818   function arc(r, p, a) {
       
  3819     return "A" + r + "," + r + " 0 " + +(a > Math.PI) + ",1 " + p;
       
  3820   }
       
  3821 
       
  3822   function curve(r0, p0, r1, p1) {
       
  3823     return "Q 0,0 " + p1;
       
  3824   }
       
  3825 
       
  3826   chord.radius = function(v) {
       
  3827     if (!arguments.length) return radius;
       
  3828     radius = d3.functor(v);
       
  3829     return chord;
       
  3830   };
       
  3831 
       
  3832   chord.source = function(v) {
       
  3833     if (!arguments.length) return source;
       
  3834     source = d3.functor(v);
       
  3835     return chord;
       
  3836   };
       
  3837 
       
  3838   chord.target = function(v) {
       
  3839     if (!arguments.length) return target;
       
  3840     target = d3.functor(v);
       
  3841     return chord;
       
  3842   };
       
  3843 
       
  3844   chord.startAngle = function(v) {
       
  3845     if (!arguments.length) return startAngle;
       
  3846     startAngle = d3.functor(v);
       
  3847     return chord;
       
  3848   };
       
  3849 
       
  3850   chord.endAngle = function(v) {
       
  3851     if (!arguments.length) return endAngle;
       
  3852     endAngle = d3.functor(v);
       
  3853     return chord;
       
  3854   };
       
  3855 
       
  3856   return chord;
       
  3857 };
       
  3858 
       
  3859 function d3_svg_chordSource(d) {
       
  3860   return d.source;
       
  3861 }
       
  3862 
       
  3863 function d3_svg_chordTarget(d) {
       
  3864   return d.target;
       
  3865 }
       
  3866 
       
  3867 function d3_svg_chordRadius(d) {
       
  3868   return d.radius;
       
  3869 }
       
  3870 
       
  3871 function d3_svg_chordStartAngle(d) {
       
  3872   return d.startAngle;
       
  3873 }
       
  3874 
       
  3875 function d3_svg_chordEndAngle(d) {
       
  3876   return d.endAngle;
       
  3877 }
       
  3878 d3.svg.diagonal = function() {
       
  3879   var source = d3_svg_chordSource,
       
  3880       target = d3_svg_chordTarget,
       
  3881       projection = d3_svg_diagonalProjection;
       
  3882 
       
  3883   function diagonal(d, i) {
       
  3884     var p0 = source.call(this, d, i),
       
  3885         p3 = target.call(this, d, i),
       
  3886         m = (p0.y + p3.y) / 2,
       
  3887         p = [p0, {x: p0.x, y: m}, {x: p3.x, y: m}, p3];
       
  3888     p = p.map(projection);
       
  3889     return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
       
  3890   }
       
  3891 
       
  3892   diagonal.source = function(x) {
       
  3893     if (!arguments.length) return source;
       
  3894     source = d3.functor(x);
       
  3895     return diagonal;
       
  3896   };
       
  3897 
       
  3898   diagonal.target = function(x) {
       
  3899     if (!arguments.length) return target;
       
  3900     target = d3.functor(x);
       
  3901     return diagonal;
       
  3902   };
       
  3903 
       
  3904   diagonal.projection = function(x) {
       
  3905     if (!arguments.length) return projection;
       
  3906     projection = x;
       
  3907     return diagonal;
       
  3908   };
       
  3909 
       
  3910   return diagonal;
       
  3911 };
       
  3912 
       
  3913 function d3_svg_diagonalProjection(d) {
       
  3914   return [d.x, d.y];
       
  3915 }
       
  3916 d3.svg.diagonal.radial = function() {
       
  3917   var diagonal = d3.svg.diagonal(),
       
  3918       projection = d3_svg_diagonalProjection,
       
  3919       projection_ = diagonal.projection;
       
  3920 
       
  3921   diagonal.projection = function(x) {
       
  3922     return arguments.length
       
  3923         ? projection_(d3_svg_diagonalRadialProjection(projection = x))
       
  3924         : projection;
       
  3925   };
       
  3926 
       
  3927   return diagonal;
       
  3928 };
       
  3929 
       
  3930 function d3_svg_diagonalRadialProjection(projection) {
       
  3931   return function() {
       
  3932     var d = projection.apply(this, arguments),
       
  3933         r = d[0],
       
  3934         a = d[1] + d3_svg_arcOffset;
       
  3935     return [r * Math.cos(a), r * Math.sin(a)];
       
  3936   };
       
  3937 }
       
  3938 d3.svg.mouse = d3.mouse;
       
  3939 d3.svg.touches = d3.touches;
       
  3940 d3.svg.symbol = function() {
       
  3941   var type = d3_svg_symbolType,
       
  3942       size = d3_svg_symbolSize;
       
  3943 
       
  3944   function symbol(d, i) {
       
  3945     return (d3_svg_symbols.get(type.call(this, d, i))
       
  3946         || d3_svg_symbolCircle)
       
  3947         (size.call(this, d, i));
       
  3948   }
       
  3949 
       
  3950   symbol.type = function(x) {
       
  3951     if (!arguments.length) return type;
       
  3952     type = d3.functor(x);
       
  3953     return symbol;
       
  3954   };
       
  3955 
       
  3956   // size of symbol in square pixels
       
  3957   symbol.size = function(x) {
       
  3958     if (!arguments.length) return size;
       
  3959     size = d3.functor(x);
       
  3960     return symbol;
       
  3961   };
       
  3962 
       
  3963   return symbol;
       
  3964 };
       
  3965 
       
  3966 function d3_svg_symbolSize() {
       
  3967   return 64;
       
  3968 }
       
  3969 
       
  3970 function d3_svg_symbolType() {
       
  3971   return "circle";
       
  3972 }
       
  3973 
       
  3974 function d3_svg_symbolCircle(size) {
       
  3975   var r = Math.sqrt(size / Math.PI);
       
  3976   return "M0," + r
       
  3977       + "A" + r + "," + r + " 0 1,1 0," + (-r)
       
  3978       + "A" + r + "," + r + " 0 1,1 0," + r
       
  3979       + "Z";
       
  3980 }
       
  3981 
       
  3982 // TODO cross-diagonal?
       
  3983 var d3_svg_symbols = d3.map({
       
  3984   "circle": d3_svg_symbolCircle,
       
  3985   "cross": function(size) {
       
  3986     var r = Math.sqrt(size / 5) / 2;
       
  3987     return "M" + -3 * r + "," + -r
       
  3988         + "H" + -r
       
  3989         + "V" + -3 * r
       
  3990         + "H" + r
       
  3991         + "V" + -r
       
  3992         + "H" + 3 * r
       
  3993         + "V" + r
       
  3994         + "H" + r
       
  3995         + "V" + 3 * r
       
  3996         + "H" + -r
       
  3997         + "V" + r
       
  3998         + "H" + -3 * r
       
  3999         + "Z";
       
  4000   },
       
  4001   "diamond": function(size) {
       
  4002     var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)),
       
  4003         rx = ry * d3_svg_symbolTan30;
       
  4004     return "M0," + -ry
       
  4005         + "L" + rx + ",0"
       
  4006         + " 0," + ry
       
  4007         + " " + -rx + ",0"
       
  4008         + "Z";
       
  4009   },
       
  4010   "square": function(size) {
       
  4011     var r = Math.sqrt(size) / 2;
       
  4012     return "M" + -r + "," + -r
       
  4013         + "L" + r + "," + -r
       
  4014         + " " + r + "," + r
       
  4015         + " " + -r + "," + r
       
  4016         + "Z";
       
  4017   },
       
  4018   "triangle-down": function(size) {
       
  4019     var rx = Math.sqrt(size / d3_svg_symbolSqrt3),
       
  4020         ry = rx * d3_svg_symbolSqrt3 / 2;
       
  4021     return "M0," + ry
       
  4022         + "L" + rx +"," + -ry
       
  4023         + " " + -rx + "," + -ry
       
  4024         + "Z";
       
  4025   },
       
  4026   "triangle-up": function(size) {
       
  4027     var rx = Math.sqrt(size / d3_svg_symbolSqrt3),
       
  4028         ry = rx * d3_svg_symbolSqrt3 / 2;
       
  4029     return "M0," + -ry
       
  4030         + "L" + rx +"," + ry
       
  4031         + " " + -rx + "," + ry
       
  4032         + "Z";
       
  4033   }
       
  4034 });
       
  4035 
       
  4036 d3.svg.symbolTypes = d3_svg_symbols.keys();
       
  4037 
       
  4038 var d3_svg_symbolSqrt3 = Math.sqrt(3),
       
  4039     d3_svg_symbolTan30 = Math.tan(30 * Math.PI / 180);
       
  4040 d3.svg.axis = function() {
       
  4041   var scale = d3.scale.linear(),
       
  4042       orient = "bottom",
       
  4043       tickMajorSize = 6,
       
  4044       tickMinorSize = 6,
       
  4045       tickEndSize = 6,
       
  4046       tickPadding = 3,
       
  4047       tickArguments_ = [10],
       
  4048       tickValues = null,
       
  4049       tickFormat_,
       
  4050       tickSubdivide = 0;
       
  4051 
       
  4052   function axis(g) {
       
  4053     g.each(function() {
       
  4054       var g = d3.select(this);
       
  4055 
       
  4056       // Ticks, or domain values for ordinal scales.
       
  4057       var ticks = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments_) : scale.domain()) : tickValues,
       
  4058           tickFormat = tickFormat_ == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments_) : String) : tickFormat_;
       
  4059 
       
  4060       // Minor ticks.
       
  4061       var subticks = d3_svg_axisSubdivide(scale, ticks, tickSubdivide),
       
  4062           subtick = g.selectAll(".minor").data(subticks, String),
       
  4063           subtickEnter = subtick.enter().insert("line", "g").attr("class", "tick minor").style("opacity", 1e-6),
       
  4064           subtickExit = d3.transition(subtick.exit()).style("opacity", 1e-6).remove(),
       
  4065           subtickUpdate = d3.transition(subtick).style("opacity", 1);
       
  4066 
       
  4067       // Major ticks.
       
  4068       var tick = g.selectAll("g").data(ticks, String),
       
  4069           tickEnter = tick.enter().insert("g", "path").style("opacity", 1e-6),
       
  4070           tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).remove(),
       
  4071           tickUpdate = d3.transition(tick).style("opacity", 1),
       
  4072           tickTransform;
       
  4073 
       
  4074       // Domain.
       
  4075       var range = d3_scaleRange(scale),
       
  4076           path = g.selectAll(".domain").data([0]),
       
  4077           pathEnter = path.enter().append("path").attr("class", "domain"),
       
  4078           pathUpdate = d3.transition(path);
       
  4079 
       
  4080       // Stash a snapshot of the new scale, and retrieve the old snapshot.
       
  4081       var scale1 = scale.copy(),
       
  4082           scale0 = this.__chart__ || scale1;
       
  4083       this.__chart__ = scale1;
       
  4084 
       
  4085       tickEnter.append("line").attr("class", "tick");
       
  4086       tickEnter.append("text");
       
  4087       tickUpdate.select("text").text(tickFormat);
       
  4088 
       
  4089       switch (orient) {
       
  4090         case "bottom": {
       
  4091           tickTransform = d3_svg_axisX;
       
  4092           subtickEnter.attr("y2", tickMinorSize);
       
  4093           subtickUpdate.attr("x2", 0).attr("y2", tickMinorSize);
       
  4094           tickEnter.select("line").attr("y2", tickMajorSize);
       
  4095           tickEnter.select("text").attr("y", Math.max(tickMajorSize, 0) + tickPadding);
       
  4096           tickUpdate.select("line").attr("x2", 0).attr("y2", tickMajorSize);
       
  4097           tickUpdate.select("text").attr("x", 0).attr("y", Math.max(tickMajorSize, 0) + tickPadding).attr("dy", ".71em").attr("text-anchor", "middle");
       
  4098           pathUpdate.attr("d", "M" + range[0] + "," + tickEndSize + "V0H" + range[1] + "V" + tickEndSize);
       
  4099           break;
       
  4100         }
       
  4101         case "top": {
       
  4102           tickTransform = d3_svg_axisX;
       
  4103           subtickEnter.attr("y2", -tickMinorSize);
       
  4104           subtickUpdate.attr("x2", 0).attr("y2", -tickMinorSize);
       
  4105           tickEnter.select("line").attr("y2", -tickMajorSize);
       
  4106           tickEnter.select("text").attr("y", -(Math.max(tickMajorSize, 0) + tickPadding));
       
  4107           tickUpdate.select("line").attr("x2", 0).attr("y2", -tickMajorSize);
       
  4108           tickUpdate.select("text").attr("x", 0).attr("y", -(Math.max(tickMajorSize, 0) + tickPadding)).attr("dy", "0em").attr("text-anchor", "middle");
       
  4109           pathUpdate.attr("d", "M" + range[0] + "," + -tickEndSize + "V0H" + range[1] + "V" + -tickEndSize);
       
  4110           break;
       
  4111         }
       
  4112         case "left": {
       
  4113           tickTransform = d3_svg_axisY;
       
  4114           subtickEnter.attr("x2", -tickMinorSize);
       
  4115           subtickUpdate.attr("x2", -tickMinorSize).attr("y2", 0);
       
  4116           tickEnter.select("line").attr("x2", -tickMajorSize);
       
  4117           tickEnter.select("text").attr("x", -(Math.max(tickMajorSize, 0) + tickPadding));
       
  4118           tickUpdate.select("line").attr("x2", -tickMajorSize).attr("y2", 0);
       
  4119           tickUpdate.select("text").attr("x", -(Math.max(tickMajorSize, 0) + tickPadding)).attr("y", 0).attr("dy", ".32em").attr("text-anchor", "end");
       
  4120           pathUpdate.attr("d", "M" + -tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + -tickEndSize);
       
  4121           break;
       
  4122         }
       
  4123         case "right": {
       
  4124           tickTransform = d3_svg_axisY;
       
  4125           subtickEnter.attr("x2", tickMinorSize);
       
  4126           subtickUpdate.attr("x2", tickMinorSize).attr("y2", 0);
       
  4127           tickEnter.select("line").attr("x2", tickMajorSize);
       
  4128           tickEnter.select("text").attr("x", Math.max(tickMajorSize, 0) + tickPadding);
       
  4129           tickUpdate.select("line").attr("x2", tickMajorSize).attr("y2", 0);
       
  4130           tickUpdate.select("text").attr("x", Math.max(tickMajorSize, 0) + tickPadding).attr("y", 0).attr("dy", ".32em").attr("text-anchor", "start");
       
  4131           pathUpdate.attr("d", "M" + tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + tickEndSize);
       
  4132           break;
       
  4133         }
       
  4134       }
       
  4135 
       
  4136       // For quantitative scales:
       
  4137       // - enter new ticks from the old scale
       
  4138       // - exit old ticks to the new scale
       
  4139       if (scale.ticks) {
       
  4140         tickEnter.call(tickTransform, scale0);
       
  4141         tickUpdate.call(tickTransform, scale1);
       
  4142         tickExit.call(tickTransform, scale1);
       
  4143         subtickEnter.call(tickTransform, scale0);
       
  4144         subtickUpdate.call(tickTransform, scale1);
       
  4145         subtickExit.call(tickTransform, scale1);
       
  4146       }
       
  4147 
       
  4148       // For ordinal scales:
       
  4149       // - any entering ticks are undefined in the old scale
       
  4150       // - any exiting ticks are undefined in the new scale
       
  4151       // Therefore, we only need to transition updating ticks.
       
  4152       else {
       
  4153         var dx = scale1.rangeBand() / 2, x = function(d) { return scale1(d) + dx; };
       
  4154         tickEnter.call(tickTransform, x);
       
  4155         tickUpdate.call(tickTransform, x);
       
  4156       }
       
  4157     });
       
  4158   }
       
  4159 
       
  4160   axis.scale = function(x) {
       
  4161     if (!arguments.length) return scale;
       
  4162     scale = x;
       
  4163     return axis;
       
  4164   };
       
  4165 
       
  4166   axis.orient = function(x) {
       
  4167     if (!arguments.length) return orient;
       
  4168     orient = x;
       
  4169     return axis;
       
  4170   };
       
  4171 
       
  4172   axis.ticks = function() {
       
  4173     if (!arguments.length) return tickArguments_;
       
  4174     tickArguments_ = arguments;
       
  4175     return axis;
       
  4176   };
       
  4177 
       
  4178   axis.tickValues = function(x) {
       
  4179     if (!arguments.length) return tickValues;
       
  4180     tickValues = x;
       
  4181     return axis;
       
  4182   };
       
  4183 
       
  4184   axis.tickFormat = function(x) {
       
  4185     if (!arguments.length) return tickFormat_;
       
  4186     tickFormat_ = x;
       
  4187     return axis;
       
  4188   };
       
  4189 
       
  4190   axis.tickSize = function(x, y, z) {
       
  4191     if (!arguments.length) return tickMajorSize;
       
  4192     var n = arguments.length - 1;
       
  4193     tickMajorSize = +x;
       
  4194     tickMinorSize = n > 1 ? +y : tickMajorSize;
       
  4195     tickEndSize = n > 0 ? +arguments[n] : tickMajorSize;
       
  4196     return axis;
       
  4197   };
       
  4198 
       
  4199   axis.tickPadding = function(x) {
       
  4200     if (!arguments.length) return tickPadding;
       
  4201     tickPadding = +x;
       
  4202     return axis;
       
  4203   };
       
  4204 
       
  4205   axis.tickSubdivide = function(x) {
       
  4206     if (!arguments.length) return tickSubdivide;
       
  4207     tickSubdivide = +x;
       
  4208     return axis;
       
  4209   };
       
  4210 
       
  4211   return axis;
       
  4212 };
       
  4213 
       
  4214 function d3_svg_axisX(selection, x) {
       
  4215   selection.attr("transform", function(d) { return "translate(" + x(d) + ",0)"; });
       
  4216 }
       
  4217 
       
  4218 function d3_svg_axisY(selection, y) {
       
  4219   selection.attr("transform", function(d) { return "translate(0," + y(d) + ")"; });
       
  4220 }
       
  4221 
       
  4222 function d3_svg_axisSubdivide(scale, ticks, m) {
       
  4223   subticks = [];
       
  4224   if (m && ticks.length > 1) {
       
  4225     var extent = d3_scaleExtent(scale.domain()),
       
  4226         subticks,
       
  4227         i = -1,
       
  4228         n = ticks.length,
       
  4229         d = (ticks[1] - ticks[0]) / ++m,
       
  4230         j,
       
  4231         v;
       
  4232     while (++i < n) {
       
  4233       for (j = m; --j > 0;) {
       
  4234         if ((v = +ticks[i] - j * d) >= extent[0]) {
       
  4235           subticks.push(v);
       
  4236         }
       
  4237       }
       
  4238     }
       
  4239     for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1];) {
       
  4240       subticks.push(v);
       
  4241     }
       
  4242   }
       
  4243   return subticks;
       
  4244 }
       
  4245 d3.svg.brush = function() {
       
  4246   var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"),
       
  4247       x = null, // x-scale, optional
       
  4248       y = null, // y-scale, optional
       
  4249       resizes = d3_svg_brushResizes[0],
       
  4250       extent = [[0, 0], [0, 0]], // [x0, y0], [x1, y1], in pixels (integers)
       
  4251       extentDomain; // the extent in data space, lazily created
       
  4252 
       
  4253   function brush(g) {
       
  4254     g.each(function() {
       
  4255       var g = d3.select(this),
       
  4256           bg = g.selectAll(".background").data([0]),
       
  4257           fg = g.selectAll(".extent").data([0]),
       
  4258           tz = g.selectAll(".resize").data(resizes, String),
       
  4259           e;
       
  4260 
       
  4261       // Prepare the brush container for events.
       
  4262       g
       
  4263           .style("pointer-events", "all")
       
  4264           .on("mousedown.brush", brushstart)
       
  4265           .on("touchstart.brush", brushstart);
       
  4266 
       
  4267       // An invisible, mouseable area for starting a new brush.
       
  4268       bg.enter().append("rect")
       
  4269           .attr("class", "background")
       
  4270           .style("visibility", "hidden")
       
  4271           .style("cursor", "crosshair");
       
  4272 
       
  4273       // The visible brush extent; style this as you like!
       
  4274       fg.enter().append("rect")
       
  4275           .attr("class", "extent")
       
  4276           .style("cursor", "move");
       
  4277 
       
  4278       // More invisible rects for resizing the extent.
       
  4279       tz.enter().append("g")
       
  4280           .attr("class", function(d) { return "resize " + d; })
       
  4281           .style("cursor", function(d) { return d3_svg_brushCursor[d]; })
       
  4282         .append("rect")
       
  4283           .attr("x", function(d) { return /[ew]$/.test(d) ? -3 : null; })
       
  4284           .attr("y", function(d) { return /^[ns]/.test(d) ? -3 : null; })
       
  4285           .attr("width", 6)
       
  4286           .attr("height", 6)
       
  4287           .style("visibility", "hidden");
       
  4288 
       
  4289       // Show or hide the resizers.
       
  4290       tz.style("display", brush.empty() ? "none" : null);
       
  4291 
       
  4292       // Remove any superfluous resizers.
       
  4293       tz.exit().remove();
       
  4294 
       
  4295       // Initialize the background to fill the defined range.
       
  4296       // If the range isn't defined, you can post-process.
       
  4297       if (x) {
       
  4298         e = d3_scaleRange(x);
       
  4299         bg.attr("x", e[0]).attr("width", e[1] - e[0]);
       
  4300         redrawX(g);
       
  4301       }
       
  4302       if (y) {
       
  4303         e = d3_scaleRange(y);
       
  4304         bg.attr("y", e[0]).attr("height", e[1] - e[0]);
       
  4305         redrawY(g);
       
  4306       }
       
  4307       redraw(g);
       
  4308     });
       
  4309   }
       
  4310 
       
  4311   function redraw(g) {
       
  4312     g.selectAll(".resize").attr("transform", function(d) {
       
  4313       return "translate(" + extent[+/e$/.test(d)][0] + "," + extent[+/^s/.test(d)][1] + ")";
       
  4314     });
       
  4315   }
       
  4316 
       
  4317   function redrawX(g) {
       
  4318     g.select(".extent").attr("x", extent[0][0]);
       
  4319     g.selectAll(".extent,.n>rect,.s>rect").attr("width", extent[1][0] - extent[0][0]);
       
  4320   }
       
  4321 
       
  4322   function redrawY(g) {
       
  4323     g.select(".extent").attr("y", extent[0][1]);
       
  4324     g.selectAll(".extent,.e>rect,.w>rect").attr("height", extent[1][1] - extent[0][1]);
       
  4325   }
       
  4326 
       
  4327   function brushstart() {
       
  4328     var target = this,
       
  4329         eventTarget = d3.select(d3.event.target),
       
  4330         event_ = event.of(target, arguments),
       
  4331         g = d3.select(target),
       
  4332         resizing = eventTarget.datum(),
       
  4333         resizingX = !/^(n|s)$/.test(resizing) && x,
       
  4334         resizingY = !/^(e|w)$/.test(resizing) && y,
       
  4335         dragging = eventTarget.classed("extent"),
       
  4336         center,
       
  4337         origin = mouse(),
       
  4338         offset;
       
  4339 
       
  4340     var w = d3.select(window)
       
  4341         .on("mousemove.brush", brushmove)
       
  4342         .on("mouseup.brush", brushend)
       
  4343         .on("touchmove.brush", brushmove)
       
  4344         .on("touchend.brush", brushend)
       
  4345         .on("keydown.brush", keydown)
       
  4346         .on("keyup.brush", keyup);
       
  4347 
       
  4348     // If the extent was clicked on, drag rather than brush;
       
  4349     // store the point between the mouse and extent origin instead.
       
  4350     if (dragging) {
       
  4351       origin[0] = extent[0][0] - origin[0];
       
  4352       origin[1] = extent[0][1] - origin[1];
       
  4353     }
       
  4354 
       
  4355     // If a resizer was clicked on, record which side is to be resized.
       
  4356     // Also, set the origin to the opposite side.
       
  4357     else if (resizing) {
       
  4358       var ex = +/w$/.test(resizing),
       
  4359           ey = +/^n/.test(resizing);
       
  4360       offset = [extent[1 - ex][0] - origin[0], extent[1 - ey][1] - origin[1]];
       
  4361       origin[0] = extent[ex][0];
       
  4362       origin[1] = extent[ey][1];
       
  4363     }
       
  4364 
       
  4365     // If the ALT key is down when starting a brush, the center is at the mouse.
       
  4366     else if (d3.event.altKey) center = origin.slice();
       
  4367 
       
  4368     // Propagate the active cursor to the body for the drag duration.
       
  4369     g.style("pointer-events", "none").selectAll(".resize").style("display", null);
       
  4370     d3.select("body").style("cursor", eventTarget.style("cursor"));
       
  4371 
       
  4372     // Notify listeners.
       
  4373     event_({type: "brushstart"});
       
  4374     brushmove();
       
  4375     d3_eventCancel();
       
  4376 
       
  4377     function mouse() {
       
  4378       var touches = d3.event.changedTouches;
       
  4379       return touches ? d3.touches(target, touches)[0] : d3.mouse(target);
       
  4380     }
       
  4381 
       
  4382     function keydown() {
       
  4383       if (d3.event.keyCode == 32) {
       
  4384         if (!dragging) {
       
  4385           center = null;
       
  4386           origin[0] -= extent[1][0];
       
  4387           origin[1] -= extent[1][1];
       
  4388           dragging = 2;
       
  4389         }
       
  4390         d3_eventCancel();
       
  4391       }
       
  4392     }
       
  4393 
       
  4394     function keyup() {
       
  4395       if (d3.event.keyCode == 32 && dragging == 2) {
       
  4396         origin[0] += extent[1][0];
       
  4397         origin[1] += extent[1][1];
       
  4398         dragging = 0;
       
  4399         d3_eventCancel();
       
  4400       }
       
  4401     }
       
  4402 
       
  4403     function brushmove() {
       
  4404       var point = mouse(),
       
  4405           moved = false;
       
  4406 
       
  4407       // Preserve the offset for thick resizers.
       
  4408       if (offset) {
       
  4409         point[0] += offset[0];
       
  4410         point[1] += offset[1];
       
  4411       }
       
  4412 
       
  4413       if (!dragging) {
       
  4414 
       
  4415         // If needed, determine the center from the current extent.
       
  4416         if (d3.event.altKey) {
       
  4417           if (!center) center = [(extent[0][0] + extent[1][0]) / 2, (extent[0][1] + extent[1][1]) / 2];
       
  4418 
       
  4419           // Update the origin, for when the ALT key is released.
       
  4420           origin[0] = extent[+(point[0] < center[0])][0];
       
  4421           origin[1] = extent[+(point[1] < center[1])][1];
       
  4422         }
       
  4423 
       
  4424         // When the ALT key is released, we clear the center.
       
  4425         else center = null;
       
  4426       }
       
  4427 
       
  4428       // Update the brush extent for each dimension.
       
  4429       if (resizingX && move1(point, x, 0)) {
       
  4430         redrawX(g);
       
  4431         moved = true;
       
  4432       }
       
  4433       if (resizingY && move1(point, y, 1)) {
       
  4434         redrawY(g);
       
  4435         moved = true;
       
  4436       }
       
  4437 
       
  4438       // Final redraw and notify listeners.
       
  4439       if (moved) {
       
  4440         redraw(g);
       
  4441         event_({type: "brush", mode: dragging ? "move" : "resize"});
       
  4442       }
       
  4443     }
       
  4444 
       
  4445     function move1(point, scale, i) {
       
  4446       var range = d3_scaleRange(scale),
       
  4447           r0 = range[0],
       
  4448           r1 = range[1],
       
  4449           position = origin[i],
       
  4450           size = extent[1][i] - extent[0][i],
       
  4451           min,
       
  4452           max;
       
  4453 
       
  4454       // When dragging, reduce the range by the extent size and position.
       
  4455       if (dragging) {
       
  4456         r0 -= position;
       
  4457         r1 -= size + position;
       
  4458       }
       
  4459 
       
  4460       // Clamp the point so that the extent fits within the range extent.
       
  4461       min = Math.max(r0, Math.min(r1, point[i]));
       
  4462 
       
  4463       // Compute the new extent bounds.
       
  4464       if (dragging) {
       
  4465         max = (min += position) + size;
       
  4466       } else {
       
  4467 
       
  4468         // If the ALT key is pressed, then preserve the center of the extent.
       
  4469         if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min));
       
  4470 
       
  4471         // Compute the min and max of the position and point.
       
  4472         if (position < min) {
       
  4473           max = min;
       
  4474           min = position;
       
  4475         } else {
       
  4476           max = position;
       
  4477         }
       
  4478       }
       
  4479 
       
  4480       // Update the stored bounds.
       
  4481       if (extent[0][i] !== min || extent[1][i] !== max) {
       
  4482         extentDomain = null;
       
  4483         extent[0][i] = min;
       
  4484         extent[1][i] = max;
       
  4485         return true;
       
  4486       }
       
  4487     }
       
  4488 
       
  4489     function brushend() {
       
  4490       brushmove();
       
  4491 
       
  4492       // reset the cursor styles
       
  4493       g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null);
       
  4494       d3.select("body").style("cursor", null);
       
  4495 
       
  4496       w .on("mousemove.brush", null)
       
  4497         .on("mouseup.brush", null)
       
  4498         .on("touchmove.brush", null)
       
  4499         .on("touchend.brush", null)
       
  4500         .on("keydown.brush", null)
       
  4501         .on("keyup.brush", null);
       
  4502 
       
  4503       event_({type: "brushend"});
       
  4504       d3_eventCancel();
       
  4505     }
       
  4506   }
       
  4507 
       
  4508   brush.x = function(z) {
       
  4509     if (!arguments.length) return x;
       
  4510     x = z;
       
  4511     resizes = d3_svg_brushResizes[!x << 1 | !y]; // fore!
       
  4512     return brush;
       
  4513   };
       
  4514 
       
  4515   brush.y = function(z) {
       
  4516     if (!arguments.length) return y;
       
  4517     y = z;
       
  4518     resizes = d3_svg_brushResizes[!x << 1 | !y]; // fore!
       
  4519     return brush;
       
  4520   };
       
  4521 
       
  4522   brush.extent = function(z) {
       
  4523     var x0, x1, y0, y1, t;
       
  4524 
       
  4525     // Invert the pixel extent to data-space.
       
  4526     if (!arguments.length) {
       
  4527       z = extentDomain || extent;
       
  4528       if (x) {
       
  4529         x0 = z[0][0], x1 = z[1][0];
       
  4530         if (!extentDomain) {
       
  4531           x0 = extent[0][0], x1 = extent[1][0];
       
  4532           if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1);
       
  4533           if (x1 < x0) t = x0, x0 = x1, x1 = t;
       
  4534         }
       
  4535       }
       
  4536       if (y) {
       
  4537         y0 = z[0][1], y1 = z[1][1];
       
  4538         if (!extentDomain) {
       
  4539           y0 = extent[0][1], y1 = extent[1][1];
       
  4540           if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1);
       
  4541           if (y1 < y0) t = y0, y0 = y1, y1 = t;
       
  4542         }
       
  4543       }
       
  4544       return x && y ? [[x0, y0], [x1, y1]] : x ? [x0, x1] : y && [y0, y1];
       
  4545     }
       
  4546 
       
  4547     // Scale the data-space extent to pixels.
       
  4548     extentDomain = [[0, 0], [0, 0]];
       
  4549     if (x) {
       
  4550       x0 = z[0], x1 = z[1];
       
  4551       if (y) x0 = x0[0], x1 = x1[0];
       
  4552       extentDomain[0][0] = x0, extentDomain[1][0] = x1;
       
  4553       if (x.invert) x0 = x(x0), x1 = x(x1);
       
  4554       if (x1 < x0) t = x0, x0 = x1, x1 = t;
       
  4555       extent[0][0] = x0 | 0, extent[1][0] = x1 | 0;
       
  4556     }
       
  4557     if (y) {
       
  4558       y0 = z[0], y1 = z[1];
       
  4559       if (x) y0 = y0[1], y1 = y1[1];
       
  4560       extentDomain[0][1] = y0, extentDomain[1][1] = y1;
       
  4561       if (y.invert) y0 = y(y0), y1 = y(y1);
       
  4562       if (y1 < y0) t = y0, y0 = y1, y1 = t;
       
  4563       extent[0][1] = y0 | 0, extent[1][1] = y1 | 0;
       
  4564     }
       
  4565 
       
  4566     return brush;
       
  4567   };
       
  4568 
       
  4569   brush.clear = function() {
       
  4570     extentDomain = null;
       
  4571     extent[0][0] =
       
  4572     extent[0][1] =
       
  4573     extent[1][0] =
       
  4574     extent[1][1] = 0;
       
  4575     return brush;
       
  4576   };
       
  4577 
       
  4578   brush.empty = function() {
       
  4579     return (x && extent[0][0] === extent[1][0])
       
  4580         || (y && extent[0][1] === extent[1][1]);
       
  4581   };
       
  4582 
       
  4583   return d3.rebind(brush, event, "on");
       
  4584 };
       
  4585 
       
  4586 var d3_svg_brushCursor = {
       
  4587   n: "ns-resize",
       
  4588   e: "ew-resize",
       
  4589   s: "ns-resize",
       
  4590   w: "ew-resize",
       
  4591   nw: "nwse-resize",
       
  4592   ne: "nesw-resize",
       
  4593   se: "nwse-resize",
       
  4594   sw: "nesw-resize"
       
  4595 };
       
  4596 
       
  4597 var d3_svg_brushResizes = [
       
  4598   ["n", "e", "s", "w", "nw", "ne", "se", "sw"],
       
  4599   ["e", "w"],
       
  4600   ["n", "s"],
       
  4601   []
       
  4602 ];
       
  4603 d3.behavior = {};
       
  4604 // TODO Track touch points by identifier.
       
  4605 
       
  4606 d3.behavior.drag = function() {
       
  4607   var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"),
       
  4608       origin = null;
       
  4609 
       
  4610   function drag() {
       
  4611     this.on("mousedown.drag", mousedown)
       
  4612         .on("touchstart.drag", mousedown);
       
  4613   }
       
  4614 
       
  4615   function mousedown() {
       
  4616     var target = this,
       
  4617         event_ = event.of(target, arguments),
       
  4618         eventTarget = d3.event.target,
       
  4619         offset,
       
  4620         origin_ = point(),
       
  4621         moved = 0;
       
  4622 
       
  4623     var w = d3.select(window)
       
  4624         .on("mousemove.drag", dragmove)
       
  4625         .on("touchmove.drag", dragmove)
       
  4626         .on("mouseup.drag", dragend, true)
       
  4627         .on("touchend.drag", dragend, true);
       
  4628 
       
  4629     if (origin) {
       
  4630       offset = origin.apply(target, arguments);
       
  4631       offset = [offset.x - origin_[0], offset.y - origin_[1]];
       
  4632     } else {
       
  4633       offset = [0, 0];
       
  4634     }
       
  4635 
       
  4636     event_({type: "dragstart"});
       
  4637 
       
  4638     function point() {
       
  4639       var p = target.parentNode,
       
  4640           t = d3.event.changedTouches;
       
  4641       return t ? d3.touches(p, t)[0] : d3.mouse(p);
       
  4642     }
       
  4643 
       
  4644     function dragmove() {
       
  4645       if (!target.parentNode) return dragend(); // target removed from DOM
       
  4646 
       
  4647       var p = point(),
       
  4648           dx = p[0] - origin_[0],
       
  4649           dy = p[1] - origin_[1];
       
  4650 
       
  4651       moved |= dx | dy;
       
  4652       origin_ = p;
       
  4653       d3_eventCancel();
       
  4654 
       
  4655       event_({type: "drag", x: p[0] + offset[0], y: p[1] + offset[1], dx: dx, dy: dy});
       
  4656     }
       
  4657 
       
  4658     function dragend() {
       
  4659       event_({type: "dragend"});
       
  4660 
       
  4661       // if moved, prevent the mouseup (and possibly click) from propagating
       
  4662       if (moved) {
       
  4663         d3_eventCancel();
       
  4664         if (d3.event.target === eventTarget) w.on("click.drag", click, true);
       
  4665       }
       
  4666 
       
  4667       w .on("mousemove.drag", null)
       
  4668         .on("touchmove.drag", null)
       
  4669         .on("mouseup.drag", null)
       
  4670         .on("touchend.drag", null);
       
  4671     }
       
  4672 
       
  4673     // prevent the subsequent click from propagating (e.g., for anchors)
       
  4674     function click() {
       
  4675       d3_eventCancel();
       
  4676       w.on("click.drag", null);
       
  4677     }
       
  4678   }
       
  4679 
       
  4680   drag.origin = function(x) {
       
  4681     if (!arguments.length) return origin;
       
  4682     origin = x;
       
  4683     return drag;
       
  4684   };
       
  4685 
       
  4686   return d3.rebind(drag, event, "on");
       
  4687 };
       
  4688 d3.behavior.zoom = function() {
       
  4689   var translate = [0, 0],
       
  4690       translate0, // translate when we started zooming (to avoid drift)
       
  4691       scale = 1,
       
  4692       scale0, // scale when we started touching
       
  4693       scaleExtent = d3_behavior_zoomInfinity,
       
  4694       event = d3_eventDispatch(zoom, "zoom"),
       
  4695       x0,
       
  4696       x1,
       
  4697       y0,
       
  4698       y1,
       
  4699       touchtime; // time of last touchstart (to detect double-tap)
       
  4700 
       
  4701   function zoom() {
       
  4702     this
       
  4703         .on("mousedown.zoom", mousedown)
       
  4704         .on("mousewheel.zoom", mousewheel)
       
  4705         .on("mousemove.zoom", mousemove)
       
  4706         .on("DOMMouseScroll.zoom", mousewheel)
       
  4707         .on("dblclick.zoom", dblclick)
       
  4708         .on("touchstart.zoom", touchstart)
       
  4709         .on("touchmove.zoom", touchmove)
       
  4710         .on("touchend.zoom", touchstart);
       
  4711   }
       
  4712 
       
  4713   zoom.translate = function(x) {
       
  4714     if (!arguments.length) return translate;
       
  4715     translate = x.map(Number);
       
  4716     return zoom;
       
  4717   };
       
  4718 
       
  4719   zoom.scale = function(x) {
       
  4720     if (!arguments.length) return scale;
       
  4721     scale = +x;
       
  4722     return zoom;
       
  4723   };
       
  4724 
       
  4725   zoom.scaleExtent = function(x) {
       
  4726     if (!arguments.length) return scaleExtent;
       
  4727     scaleExtent = x == null ? d3_behavior_zoomInfinity : x.map(Number);
       
  4728     return zoom;
       
  4729   };
       
  4730 
       
  4731   zoom.x = function(z) {
       
  4732     if (!arguments.length) return x1;
       
  4733     x1 = z;
       
  4734     x0 = z.copy();
       
  4735     return zoom;
       
  4736   };
       
  4737 
       
  4738   zoom.y = function(z) {
       
  4739     if (!arguments.length) return y1;
       
  4740     y1 = z;
       
  4741     y0 = z.copy();
       
  4742     return zoom;
       
  4743   };
       
  4744 
       
  4745   function location(p) {
       
  4746     return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
       
  4747   }
       
  4748 
       
  4749   function point(l) {
       
  4750     return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
       
  4751   }
       
  4752 
       
  4753   function scaleTo(s) {
       
  4754     scale = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s));
       
  4755   }
       
  4756 
       
  4757   function translateTo(p, l) {
       
  4758     l = point(l);
       
  4759     translate[0] += p[0] - l[0];
       
  4760     translate[1] += p[1] - l[1];
       
  4761   }
       
  4762 
       
  4763   function dispatch(event) {
       
  4764     if (x1) x1.domain(x0.range().map(function(x) { return (x - translate[0]) / scale; }).map(x0.invert));
       
  4765     if (y1) y1.domain(y0.range().map(function(y) { return (y - translate[1]) / scale; }).map(y0.invert));
       
  4766     d3.event.preventDefault();
       
  4767     event({type: "zoom", scale: scale, translate: translate});
       
  4768   }
       
  4769 
       
  4770   function mousedown() {
       
  4771     var target = this,
       
  4772         event_ = event.of(target, arguments),
       
  4773         eventTarget = d3.event.target,
       
  4774         moved = 0,
       
  4775         w = d3.select(window).on("mousemove.zoom", mousemove).on("mouseup.zoom", mouseup),
       
  4776         l = location(d3.mouse(target));
       
  4777 
       
  4778     window.focus();
       
  4779     d3_eventCancel();
       
  4780 
       
  4781     function mousemove() {
       
  4782       moved = 1;
       
  4783       translateTo(d3.mouse(target), l);
       
  4784       dispatch(event_);
       
  4785     }
       
  4786 
       
  4787     function mouseup() {
       
  4788       if (moved) d3_eventCancel();
       
  4789       w.on("mousemove.zoom", null).on("mouseup.zoom", null);
       
  4790       if (moved && d3.event.target === eventTarget) w.on("click.zoom", click);
       
  4791     }
       
  4792 
       
  4793     function click() {
       
  4794       d3_eventCancel();
       
  4795       w.on("click.zoom", null);
       
  4796     }
       
  4797   }
       
  4798 
       
  4799   function mousewheel() {
       
  4800     if (!translate0) translate0 = location(d3.mouse(this));
       
  4801     scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * scale);
       
  4802     translateTo(d3.mouse(this), translate0);
       
  4803     dispatch(event.of(this, arguments));
       
  4804   }
       
  4805 
       
  4806   function mousemove() {
       
  4807     translate0 = null;
       
  4808   }
       
  4809 
       
  4810   function dblclick() {
       
  4811     var p = d3.mouse(this), l = location(p);
       
  4812     scaleTo(d3.event.shiftKey ? scale / 2 : scale * 2);
       
  4813     translateTo(p, l);
       
  4814     dispatch(event.of(this, arguments));
       
  4815   }
       
  4816 
       
  4817   function touchstart() {
       
  4818     var touches = d3.touches(this),
       
  4819         now = Date.now();
       
  4820 
       
  4821     scale0 = scale;
       
  4822     translate0 = {};
       
  4823     touches.forEach(function(t) { translate0[t.identifier] = location(t); });
       
  4824     d3_eventCancel();
       
  4825 
       
  4826     if ((touches.length === 1) && (now - touchtime < 500)) { // dbltap
       
  4827       var p = touches[0], l = location(touches[0]);
       
  4828       scaleTo(scale * 2);
       
  4829       translateTo(p, l);
       
  4830       dispatch(event.of(this, arguments));
       
  4831     }
       
  4832     touchtime = now;
       
  4833   }
       
  4834 
       
  4835   function touchmove() {
       
  4836     var touches = d3.touches(this),
       
  4837         p0 = touches[0],
       
  4838         l0 = translate0[p0.identifier];
       
  4839     if (p1 = touches[1]) {
       
  4840       var p1, l1 = translate0[p1.identifier];
       
  4841       p0 = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
       
  4842       l0 = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
       
  4843       scaleTo(d3.event.scale * scale0);
       
  4844     }
       
  4845     translateTo(p0, l0);
       
  4846     dispatch(event.of(this, arguments));
       
  4847   }
       
  4848 
       
  4849   return d3.rebind(zoom, event, "on");
       
  4850 };
       
  4851 
       
  4852 var d3_behavior_zoomDiv, // for interpreting mousewheel events
       
  4853     d3_behavior_zoomInfinity = [0, Infinity]; // default scale extent
       
  4854 
       
  4855 function d3_behavior_zoomDelta() {
       
  4856 
       
  4857   // mousewheel events are totally broken!
       
  4858   // https://bugs.webkit.org/show_bug.cgi?id=40441
       
  4859   // not only that, but Chrome and Safari differ in re. to acceleration!
       
  4860   if (!d3_behavior_zoomDiv) {
       
  4861     d3_behavior_zoomDiv = d3.select("body").append("div")
       
  4862         .style("visibility", "hidden")
       
  4863         .style("top", 0)
       
  4864         .style("height", 0)
       
  4865         .style("width", 0)
       
  4866         .style("overflow-y", "scroll")
       
  4867       .append("div")
       
  4868         .style("height", "2000px")
       
  4869       .node().parentNode;
       
  4870   }
       
  4871 
       
  4872   var e = d3.event, delta;
       
  4873   try {
       
  4874     d3_behavior_zoomDiv.scrollTop = 1000;
       
  4875     d3_behavior_zoomDiv.dispatchEvent(e);
       
  4876     delta = 1000 - d3_behavior_zoomDiv.scrollTop;
       
  4877   } catch (error) {
       
  4878     delta = e.wheelDelta || (-e.detail * 5);
       
  4879   }
       
  4880 
       
  4881   return delta;
       
  4882 }
       
  4883 d3.layout = {};
       
  4884 // Implements hierarchical edge bundling using Holten's algorithm. For each
       
  4885 // input link, a path is computed that travels through the tree, up the parent
       
  4886 // hierarchy to the least common ancestor, and then back down to the destination
       
  4887 // node. Each path is simply an array of nodes.
       
  4888 d3.layout.bundle = function() {
       
  4889   return function(links) {
       
  4890     var paths = [],
       
  4891         i = -1,
       
  4892         n = links.length;
       
  4893     while (++i < n) paths.push(d3_layout_bundlePath(links[i]));
       
  4894     return paths;
       
  4895   };
       
  4896 };
       
  4897 
       
  4898 function d3_layout_bundlePath(link) {
       
  4899   var start = link.source,
       
  4900       end = link.target,
       
  4901       lca = d3_layout_bundleLeastCommonAncestor(start, end),
       
  4902       points = [start];
       
  4903   while (start !== lca) {
       
  4904     start = start.parent;
       
  4905     points.push(start);
       
  4906   }
       
  4907   var k = points.length;
       
  4908   while (end !== lca) {
       
  4909     points.splice(k, 0, end);
       
  4910     end = end.parent;
       
  4911   }
       
  4912   return points;
       
  4913 }
       
  4914 
       
  4915 function d3_layout_bundleAncestors(node) {
       
  4916   var ancestors = [],
       
  4917       parent = node.parent;
       
  4918   while (parent != null) {
       
  4919     ancestors.push(node);
       
  4920     node = parent;
       
  4921     parent = parent.parent;
       
  4922   }
       
  4923   ancestors.push(node);
       
  4924   return ancestors;
       
  4925 }
       
  4926 
       
  4927 function d3_layout_bundleLeastCommonAncestor(a, b) {
       
  4928   if (a === b) return a;
       
  4929   var aNodes = d3_layout_bundleAncestors(a),
       
  4930       bNodes = d3_layout_bundleAncestors(b),
       
  4931       aNode = aNodes.pop(),
       
  4932       bNode = bNodes.pop(),
       
  4933       sharedNode = null;
       
  4934   while (aNode === bNode) {
       
  4935     sharedNode = aNode;
       
  4936     aNode = aNodes.pop();
       
  4937     bNode = bNodes.pop();
       
  4938   }
       
  4939   return sharedNode;
       
  4940 }
       
  4941 d3.layout.chord = function() {
       
  4942   var chord = {},
       
  4943       chords,
       
  4944       groups,
       
  4945       matrix,
       
  4946       n,
       
  4947       padding = 0,
       
  4948       sortGroups,
       
  4949       sortSubgroups,
       
  4950       sortChords;
       
  4951 
       
  4952   function relayout() {
       
  4953     var subgroups = {},
       
  4954         groupSums = [],
       
  4955         groupIndex = d3.range(n),
       
  4956         subgroupIndex = [],
       
  4957         k,
       
  4958         x,
       
  4959         x0,
       
  4960         i,
       
  4961         j;
       
  4962 
       
  4963     chords = [];
       
  4964     groups = [];
       
  4965 
       
  4966     // Compute the sum.
       
  4967     k = 0, i = -1; while (++i < n) {
       
  4968       x = 0, j = -1; while (++j < n) {
       
  4969         x += matrix[i][j];
       
  4970       }
       
  4971       groupSums.push(x);
       
  4972       subgroupIndex.push(d3.range(n));
       
  4973       k += x;
       
  4974     }
       
  4975 
       
  4976     // Sort groups…
       
  4977     if (sortGroups) {
       
  4978       groupIndex.sort(function(a, b) {
       
  4979         return sortGroups(groupSums[a], groupSums[b]);
       
  4980       });
       
  4981     }
       
  4982 
       
  4983     // Sort subgroups…
       
  4984     if (sortSubgroups) {
       
  4985       subgroupIndex.forEach(function(d, i) {
       
  4986         d.sort(function(a, b) {
       
  4987           return sortSubgroups(matrix[i][a], matrix[i][b]);
       
  4988         });
       
  4989       });
       
  4990     }
       
  4991 
       
  4992     // Convert the sum to scaling factor for [0, 2pi].
       
  4993     // TODO Allow start and end angle to be specified.
       
  4994     // TODO Allow padding to be specified as percentage?
       
  4995     k = (2 * Math.PI - padding * n) / k;
       
  4996 
       
  4997     // Compute the start and end angle for each group and subgroup.
       
  4998     // Note: Opera has a bug reordering object literal properties!
       
  4999     x = 0, i = -1; while (++i < n) {
       
  5000       x0 = x, j = -1; while (++j < n) {
       
  5001         var di = groupIndex[i],
       
  5002             dj = subgroupIndex[di][j],
       
  5003             v = matrix[di][dj],
       
  5004             a0 = x,
       
  5005             a1 = x += v * k;
       
  5006         subgroups[di + "-" + dj] = {
       
  5007           index: di,
       
  5008           subindex: dj,
       
  5009           startAngle: a0,
       
  5010           endAngle: a1,
       
  5011           value: v
       
  5012         };
       
  5013       }
       
  5014       groups.push({
       
  5015         index: di,
       
  5016         startAngle: x0,
       
  5017         endAngle: x,
       
  5018         value: (x - x0) / k
       
  5019       });
       
  5020       x += padding;
       
  5021     }
       
  5022 
       
  5023     // Generate chords for each (non-empty) subgroup-subgroup link.
       
  5024     i = -1; while (++i < n) {
       
  5025       j = i - 1; while (++j < n) {
       
  5026         var source = subgroups[i + "-" + j],
       
  5027             target = subgroups[j + "-" + i];
       
  5028         if (source.value || target.value) {
       
  5029           chords.push(source.value < target.value
       
  5030               ? {source: target, target: source}
       
  5031               : {source: source, target: target});
       
  5032         }
       
  5033       }
       
  5034     }
       
  5035 
       
  5036     if (sortChords) resort();
       
  5037   }
       
  5038 
       
  5039   function resort() {
       
  5040     chords.sort(function(a, b) {
       
  5041       return sortChords(
       
  5042           (a.source.value + a.target.value) / 2,
       
  5043           (b.source.value + b.target.value) / 2);
       
  5044     });
       
  5045   }
       
  5046 
       
  5047   chord.matrix = function(x) {
       
  5048     if (!arguments.length) return matrix;
       
  5049     n = (matrix = x) && matrix.length;
       
  5050     chords = groups = null;
       
  5051     return chord;
       
  5052   };
       
  5053 
       
  5054   chord.padding = function(x) {
       
  5055     if (!arguments.length) return padding;
       
  5056     padding = x;
       
  5057     chords = groups = null;
       
  5058     return chord;
       
  5059   };
       
  5060 
       
  5061   chord.sortGroups = function(x) {
       
  5062     if (!arguments.length) return sortGroups;
       
  5063     sortGroups = x;
       
  5064     chords = groups = null;
       
  5065     return chord;
       
  5066   };
       
  5067 
       
  5068   chord.sortSubgroups = function(x) {
       
  5069     if (!arguments.length) return sortSubgroups;
       
  5070     sortSubgroups = x;
       
  5071     chords = null;
       
  5072     return chord;
       
  5073   };
       
  5074 
       
  5075   chord.sortChords = function(x) {
       
  5076     if (!arguments.length) return sortChords;
       
  5077     sortChords = x;
       
  5078     if (chords) resort();
       
  5079     return chord;
       
  5080   };
       
  5081 
       
  5082   chord.chords = function() {
       
  5083     if (!chords) relayout();
       
  5084     return chords;
       
  5085   };
       
  5086 
       
  5087   chord.groups = function() {
       
  5088     if (!groups) relayout();
       
  5089     return groups;
       
  5090   };
       
  5091 
       
  5092   return chord;
       
  5093 };
       
  5094 // A rudimentary force layout using Gauss-Seidel.
       
  5095 d3.layout.force = function() {
       
  5096   var force = {},
       
  5097       event = d3.dispatch("start", "tick", "end"),
       
  5098       size = [1, 1],
       
  5099       drag,
       
  5100       alpha,
       
  5101       friction = .9,
       
  5102       linkDistance = d3_layout_forceLinkDistance,
       
  5103       linkStrength = d3_layout_forceLinkStrength,
       
  5104       charge = -30,
       
  5105       gravity = .1,
       
  5106       theta = .8,
       
  5107       interval,
       
  5108       nodes = [],
       
  5109       links = [],
       
  5110       distances,
       
  5111       strengths,
       
  5112       charges;
       
  5113 
       
  5114   function repulse(node) {
       
  5115     return function(quad, x1, y1, x2, y2) {
       
  5116       if (quad.point !== node) {
       
  5117         var dx = quad.cx - node.x,
       
  5118             dy = quad.cy - node.y,
       
  5119             dn = 1 / Math.sqrt(dx * dx + dy * dy);
       
  5120 
       
  5121         /* Barnes-Hut criterion. */
       
  5122         if ((x2 - x1) * dn < theta) {
       
  5123           var k = quad.charge * dn * dn;
       
  5124           node.px -= dx * k;
       
  5125           node.py -= dy * k;
       
  5126           return true;
       
  5127         }
       
  5128 
       
  5129         if (quad.point && isFinite(dn)) {
       
  5130           var k = quad.pointCharge * dn * dn;
       
  5131           node.px -= dx * k;
       
  5132           node.py -= dy * k;
       
  5133         }
       
  5134       }
       
  5135       return !quad.charge;
       
  5136     };
       
  5137   }
       
  5138 
       
  5139   force.tick = function() {
       
  5140     // simulated annealing, basically
       
  5141     if ((alpha *= .99) < .005) {
       
  5142       event.end({type: "end", alpha: alpha = 0});
       
  5143       return true;
       
  5144     }
       
  5145 
       
  5146     var n = nodes.length,
       
  5147         m = links.length,
       
  5148         q,
       
  5149         i, // current index
       
  5150         o, // current object
       
  5151         s, // current source
       
  5152         t, // current target
       
  5153         l, // current distance
       
  5154         k, // current force
       
  5155         x, // x-distance
       
  5156         y; // y-distance
       
  5157 
       
  5158     // gauss-seidel relaxation for links
       
  5159     for (i = 0; i < m; ++i) {
       
  5160       o = links[i];
       
  5161       s = o.source;
       
  5162       t = o.target;
       
  5163       x = t.x - s.x;
       
  5164       y = t.y - s.y;
       
  5165       if (l = (x * x + y * y)) {
       
  5166         l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;
       
  5167         x *= l;
       
  5168         y *= l;
       
  5169         t.x -= x * (k = s.weight / (t.weight + s.weight));
       
  5170         t.y -= y * k;
       
  5171         s.x += x * (k = 1 - k);
       
  5172         s.y += y * k;
       
  5173       }
       
  5174     }
       
  5175 
       
  5176     // apply gravity forces
       
  5177     if (k = alpha * gravity) {
       
  5178       x = size[0] / 2;
       
  5179       y = size[1] / 2;
       
  5180       i = -1; if (k) while (++i < n) {
       
  5181         o = nodes[i];
       
  5182         o.x += (x - o.x) * k;
       
  5183         o.y += (y - o.y) * k;
       
  5184       }
       
  5185     }
       
  5186 
       
  5187     // compute quadtree center of mass and apply charge forces
       
  5188     if (charge) {
       
  5189       d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges);
       
  5190       i = -1; while (++i < n) {
       
  5191         if (!(o = nodes[i]).fixed) {
       
  5192           q.visit(repulse(o));
       
  5193         }
       
  5194       }
       
  5195     }
       
  5196 
       
  5197     // position verlet integration
       
  5198     i = -1; while (++i < n) {
       
  5199       o = nodes[i];
       
  5200       if (o.fixed) {
       
  5201         o.x = o.px;
       
  5202         o.y = o.py;
       
  5203       } else {
       
  5204         o.x -= (o.px - (o.px = o.x)) * friction;
       
  5205         o.y -= (o.py - (o.py = o.y)) * friction;
       
  5206       }
       
  5207     }
       
  5208 
       
  5209     event.tick({type: "tick", alpha: alpha});
       
  5210   };
       
  5211 
       
  5212   force.nodes = function(x) {
       
  5213     if (!arguments.length) return nodes;
       
  5214     nodes = x;
       
  5215     return force;
       
  5216   };
       
  5217 
       
  5218   force.links = function(x) {
       
  5219     if (!arguments.length) return links;
       
  5220     links = x;
       
  5221     return force;
       
  5222   };
       
  5223 
       
  5224   force.size = function(x) {
       
  5225     if (!arguments.length) return size;
       
  5226     size = x;
       
  5227     return force;
       
  5228   };
       
  5229 
       
  5230   force.linkDistance = function(x) {
       
  5231     if (!arguments.length) return linkDistance;
       
  5232     linkDistance = d3.functor(x);
       
  5233     return force;
       
  5234   };
       
  5235 
       
  5236   // For backwards-compatibility.
       
  5237   force.distance = force.linkDistance;
       
  5238 
       
  5239   force.linkStrength = function(x) {
       
  5240     if (!arguments.length) return linkStrength;
       
  5241     linkStrength = d3.functor(x);
       
  5242     return force;
       
  5243   };
       
  5244 
       
  5245   force.friction = function(x) {
       
  5246     if (!arguments.length) return friction;
       
  5247     friction = x;
       
  5248     return force;
       
  5249   };
       
  5250 
       
  5251   force.charge = function(x) {
       
  5252     if (!arguments.length) return charge;
       
  5253     charge = typeof x === "function" ? x : +x;
       
  5254     return force;
       
  5255   };
       
  5256 
       
  5257   force.gravity = function(x) {
       
  5258     if (!arguments.length) return gravity;
       
  5259     gravity = x;
       
  5260     return force;
       
  5261   };
       
  5262 
       
  5263   force.theta = function(x) {
       
  5264     if (!arguments.length) return theta;
       
  5265     theta = x;
       
  5266     return force;
       
  5267   };
       
  5268 
       
  5269   force.alpha = function(x) {
       
  5270     if (!arguments.length) return alpha;
       
  5271 
       
  5272     if (alpha) { // if we're already running
       
  5273       if (x > 0) alpha = x; // we might keep it hot
       
  5274       else alpha = 0; // or, next tick will dispatch "end"
       
  5275     } else if (x > 0) { // otherwise, fire it up!
       
  5276       event.start({type: "start", alpha: alpha = x});
       
  5277       d3.timer(force.tick);
       
  5278     }
       
  5279 
       
  5280     return force;
       
  5281   };
       
  5282 
       
  5283   force.start = function() {
       
  5284     var i,
       
  5285         j,
       
  5286         n = nodes.length,
       
  5287         m = links.length,
       
  5288         w = size[0],
       
  5289         h = size[1],
       
  5290         neighbors,
       
  5291         o;
       
  5292 
       
  5293     for (i = 0; i < n; ++i) {
       
  5294       (o = nodes[i]).index = i;
       
  5295       o.weight = 0;
       
  5296     }
       
  5297 
       
  5298     distances = [];
       
  5299     strengths = [];
       
  5300     for (i = 0; i < m; ++i) {
       
  5301       o = links[i];
       
  5302       if (typeof o.source == "number") o.source = nodes[o.source];
       
  5303       if (typeof o.target == "number") o.target = nodes[o.target];
       
  5304       distances[i] = linkDistance.call(this, o, i);
       
  5305       strengths[i] = linkStrength.call(this, o, i);
       
  5306       ++o.source.weight;
       
  5307       ++o.target.weight;
       
  5308     }
       
  5309 
       
  5310     for (i = 0; i < n; ++i) {
       
  5311       o = nodes[i];
       
  5312       if (isNaN(o.x)) o.x = position("x", w);
       
  5313       if (isNaN(o.y)) o.y = position("y", h);
       
  5314       if (isNaN(o.px)) o.px = o.x;
       
  5315       if (isNaN(o.py)) o.py = o.y;
       
  5316     }
       
  5317 
       
  5318     charges = [];
       
  5319     if (typeof charge === "function") {
       
  5320       for (i = 0; i < n; ++i) {
       
  5321         charges[i] = +charge.call(this, nodes[i], i);
       
  5322       }
       
  5323     } else {
       
  5324       for (i = 0; i < n; ++i) {
       
  5325         charges[i] = charge;
       
  5326       }
       
  5327     }
       
  5328 
       
  5329     // initialize node position based on first neighbor
       
  5330     function position(dimension, size) {
       
  5331       var neighbors = neighbor(i),
       
  5332           j = -1,
       
  5333           m = neighbors.length,
       
  5334           x;
       
  5335       while (++j < m) if (!isNaN(x = neighbors[j][dimension])) return x;
       
  5336       return Math.random() * size;
       
  5337     }
       
  5338 
       
  5339     // initialize neighbors lazily
       
  5340     function neighbor() {
       
  5341       if (!neighbors) {
       
  5342         neighbors = [];
       
  5343         for (j = 0; j < n; ++j) {
       
  5344           neighbors[j] = [];
       
  5345         }
       
  5346         for (j = 0; j < m; ++j) {
       
  5347           var o = links[j];
       
  5348           neighbors[o.source.index].push(o.target);
       
  5349           neighbors[o.target.index].push(o.source);
       
  5350         }
       
  5351       }
       
  5352       return neighbors[i];
       
  5353     }
       
  5354 
       
  5355     return force.resume();
       
  5356   };
       
  5357 
       
  5358   force.resume = function() {
       
  5359     return force.alpha(.1);
       
  5360   };
       
  5361 
       
  5362   force.stop = function() {
       
  5363     return force.alpha(0);
       
  5364   };
       
  5365 
       
  5366   // use `node.call(force.drag)` to make nodes draggable
       
  5367   force.drag = function() {
       
  5368     if (!drag) drag = d3.behavior.drag()
       
  5369         .origin(Object)
       
  5370         .on("dragstart", dragstart)
       
  5371         .on("drag", d3_layout_forceDrag)
       
  5372         .on("dragend", d3_layout_forceDragEnd);
       
  5373 
       
  5374     this.on("mouseover.force", d3_layout_forceDragOver)
       
  5375         .on("mouseout.force", d3_layout_forceDragOut)
       
  5376         .call(drag);
       
  5377   };
       
  5378 
       
  5379   function dragstart(d) {
       
  5380     d3_layout_forceDragOver(d3_layout_forceDragNode = d);
       
  5381     d3_layout_forceDragForce = force;
       
  5382   }
       
  5383 
       
  5384   return d3.rebind(force, event, "on");
       
  5385 };
       
  5386 
       
  5387 var d3_layout_forceDragForce,
       
  5388     d3_layout_forceDragNode;
       
  5389 
       
  5390 function d3_layout_forceDragOver(d) {
       
  5391   d.fixed |= 2;
       
  5392 }
       
  5393 
       
  5394 function d3_layout_forceDragOut(d) {
       
  5395   if (d !== d3_layout_forceDragNode) d.fixed &= 1;
       
  5396 }
       
  5397 
       
  5398 function d3_layout_forceDragEnd() {
       
  5399   d3_layout_forceDragNode.fixed &= 1;
       
  5400   d3_layout_forceDragForce = d3_layout_forceDragNode = null;
       
  5401 }
       
  5402 
       
  5403 function d3_layout_forceDrag() {
       
  5404   d3_layout_forceDragNode.px = d3.event.x;
       
  5405   d3_layout_forceDragNode.py = d3.event.y;
       
  5406   d3_layout_forceDragForce.resume(); // restart annealing
       
  5407 }
       
  5408 
       
  5409 function d3_layout_forceAccumulate(quad, alpha, charges) {
       
  5410   var cx = 0,
       
  5411       cy = 0;
       
  5412   quad.charge = 0;
       
  5413   if (!quad.leaf) {
       
  5414     var nodes = quad.nodes,
       
  5415         n = nodes.length,
       
  5416         i = -1,
       
  5417         c;
       
  5418     while (++i < n) {
       
  5419       c = nodes[i];
       
  5420       if (c == null) continue;
       
  5421       d3_layout_forceAccumulate(c, alpha, charges);
       
  5422       quad.charge += c.charge;
       
  5423       cx += c.charge * c.cx;
       
  5424       cy += c.charge * c.cy;
       
  5425     }
       
  5426   }
       
  5427   if (quad.point) {
       
  5428     // jitter internal nodes that are coincident
       
  5429     if (!quad.leaf) {
       
  5430       quad.point.x += Math.random() - .5;
       
  5431       quad.point.y += Math.random() - .5;
       
  5432     }
       
  5433     var k = alpha * charges[quad.point.index];
       
  5434     quad.charge += quad.pointCharge = k;
       
  5435     cx += k * quad.point.x;
       
  5436     cy += k * quad.point.y;
       
  5437   }
       
  5438   quad.cx = cx / quad.charge;
       
  5439   quad.cy = cy / quad.charge;
       
  5440 }
       
  5441 
       
  5442 function d3_layout_forceLinkDistance(link) {
       
  5443   return 20;
       
  5444 }
       
  5445 
       
  5446 function d3_layout_forceLinkStrength(link) {
       
  5447   return 1;
       
  5448 }
       
  5449 d3.layout.partition = function() {
       
  5450   var hierarchy = d3.layout.hierarchy(),
       
  5451       size = [1, 1]; // width, height
       
  5452 
       
  5453   function position(node, x, dx, dy) {
       
  5454     var children = node.children;
       
  5455     node.x = x;
       
  5456     node.y = node.depth * dy;
       
  5457     node.dx = dx;
       
  5458     node.dy = dy;
       
  5459     if (children && (n = children.length)) {
       
  5460       var i = -1,
       
  5461           n,
       
  5462           c,
       
  5463           d;
       
  5464       dx = node.value ? dx / node.value : 0;
       
  5465       while (++i < n) {
       
  5466         position(c = children[i], x, d = c.value * dx, dy);
       
  5467         x += d;
       
  5468       }
       
  5469     }
       
  5470   }
       
  5471 
       
  5472   function depth(node) {
       
  5473     var children = node.children,
       
  5474         d = 0;
       
  5475     if (children && (n = children.length)) {
       
  5476       var i = -1,
       
  5477           n;
       
  5478       while (++i < n) d = Math.max(d, depth(children[i]));
       
  5479     }
       
  5480     return 1 + d;
       
  5481   }
       
  5482 
       
  5483   function partition(d, i) {
       
  5484     var nodes = hierarchy.call(this, d, i);
       
  5485     position(nodes[0], 0, size[0], size[1] / depth(nodes[0]));
       
  5486     return nodes;
       
  5487   }
       
  5488 
       
  5489   partition.size = function(x) {
       
  5490     if (!arguments.length) return size;
       
  5491     size = x;
       
  5492     return partition;
       
  5493   };
       
  5494 
       
  5495   return d3_layout_hierarchyRebind(partition, hierarchy);
       
  5496 };
       
  5497 d3.layout.pie = function() {
       
  5498   var value = Number,
       
  5499       sort = d3_layout_pieSortByValue,
       
  5500       startAngle = 0,
       
  5501       endAngle = 2 * Math.PI;
       
  5502 
       
  5503   function pie(data, i) {
       
  5504 
       
  5505     // Compute the numeric values for each data element.
       
  5506     var values = data.map(function(d, i) { return +value.call(pie, d, i); });
       
  5507 
       
  5508     // Compute the start angle.
       
  5509     var a = +(typeof startAngle === "function"
       
  5510         ? startAngle.apply(this, arguments)
       
  5511         : startAngle);
       
  5512 
       
  5513     // Compute the angular scale factor: from value to radians.
       
  5514     var k = ((typeof endAngle === "function"
       
  5515         ? endAngle.apply(this, arguments)
       
  5516         : endAngle) - startAngle)
       
  5517         / d3.sum(values);
       
  5518 
       
  5519     // Optionally sort the data.
       
  5520     var index = d3.range(data.length);
       
  5521     if (sort != null) index.sort(sort === d3_layout_pieSortByValue
       
  5522         ? function(i, j) { return values[j] - values[i]; }
       
  5523         : function(i, j) { return sort(data[i], data[j]); });
       
  5524 
       
  5525     // Compute the arcs!
       
  5526     // They are stored in the original data's order.
       
  5527     var arcs = [];
       
  5528     index.forEach(function(i) {
       
  5529       arcs[i] = {
       
  5530         data: data[i],
       
  5531         value: d = values[i],
       
  5532         startAngle: a,
       
  5533         endAngle: a += d * k
       
  5534       };
       
  5535     });
       
  5536     return arcs;
       
  5537   }
       
  5538 
       
  5539   /**
       
  5540    * Specifies the value function *x*, which returns a nonnegative numeric value
       
  5541    * for each datum. The default value function is `Number`. The value function
       
  5542    * is passed two arguments: the current datum and the current index.
       
  5543    */
       
  5544   pie.value = function(x) {
       
  5545     if (!arguments.length) return value;
       
  5546     value = x;
       
  5547     return pie;
       
  5548   };
       
  5549 
       
  5550   /**
       
  5551    * Specifies a sort comparison operator *x*. The comparator is passed two data
       
  5552    * elements from the data array, a and b; it returns a negative value if a is
       
  5553    * less than b, a positive value if a is greater than b, and zero if a equals
       
  5554    * b.
       
  5555    */
       
  5556   pie.sort = function(x) {
       
  5557     if (!arguments.length) return sort;
       
  5558     sort = x;
       
  5559     return pie;
       
  5560   };
       
  5561 
       
  5562   /**
       
  5563    * Specifies the overall start angle of the pie chart. Defaults to 0. The
       
  5564    * start angle can be specified either as a constant or as a function; in the
       
  5565    * case of a function, it is evaluated once per array (as opposed to per
       
  5566    * element).
       
  5567    */
       
  5568   pie.startAngle = function(x) {
       
  5569     if (!arguments.length) return startAngle;
       
  5570     startAngle = x;
       
  5571     return pie;
       
  5572   };
       
  5573 
       
  5574   /**
       
  5575    * Specifies the overall end angle of the pie chart. Defaults to 2Ï€. The
       
  5576    * end angle can be specified either as a constant or as a function; in the
       
  5577    * case of a function, it is evaluated once per array (as opposed to per
       
  5578    * element).
       
  5579    */
       
  5580   pie.endAngle = function(x) {
       
  5581     if (!arguments.length) return endAngle;
       
  5582     endAngle = x;
       
  5583     return pie;
       
  5584   };
       
  5585 
       
  5586   return pie;
       
  5587 };
       
  5588 
       
  5589 var d3_layout_pieSortByValue = {};
       
  5590 // data is two-dimensional array of x,y; we populate y0
       
  5591 d3.layout.stack = function() {
       
  5592   var values = Object,
       
  5593       order = d3_layout_stackOrderDefault,
       
  5594       offset = d3_layout_stackOffsetZero,
       
  5595       out = d3_layout_stackOut,
       
  5596       x = d3_layout_stackX,
       
  5597       y = d3_layout_stackY;
       
  5598 
       
  5599   function stack(data, index) {
       
  5600 
       
  5601     // Convert series to canonical two-dimensional representation.
       
  5602     var series = data.map(function(d, i) {
       
  5603       return values.call(stack, d, i);
       
  5604     });
       
  5605 
       
  5606     // Convert each series to canonical [[x,y]] representation.
       
  5607     var points = series.map(function(d, i) {
       
  5608       return d.map(function(v, i) {
       
  5609         return [x.call(stack, v, i), y.call(stack, v, i)];
       
  5610       });
       
  5611     });
       
  5612 
       
  5613     // Compute the order of series, and permute them.
       
  5614     var orders = order.call(stack, points, index);
       
  5615     series = d3.permute(series, orders);
       
  5616     points = d3.permute(points, orders);
       
  5617 
       
  5618     // Compute the baseline…
       
  5619     var offsets = offset.call(stack, points, index);
       
  5620 
       
  5621     // And propagate it to other series.
       
  5622     var n = series.length,
       
  5623         m = series[0].length,
       
  5624         i,
       
  5625         j,
       
  5626         o;
       
  5627     for (j = 0; j < m; ++j) {
       
  5628       out.call(stack, series[0][j], o = offsets[j], points[0][j][1]);
       
  5629       for (i = 1; i < n; ++i) {
       
  5630         out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]);
       
  5631       }
       
  5632     }
       
  5633 
       
  5634     return data;
       
  5635   }
       
  5636 
       
  5637   stack.values = function(x) {
       
  5638     if (!arguments.length) return values;
       
  5639     values = x;
       
  5640     return stack;
       
  5641   };
       
  5642 
       
  5643   stack.order = function(x) {
       
  5644     if (!arguments.length) return order;
       
  5645     order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault;
       
  5646     return stack;
       
  5647   };
       
  5648 
       
  5649   stack.offset = function(x) {
       
  5650     if (!arguments.length) return offset;
       
  5651     offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero;
       
  5652     return stack;
       
  5653   };
       
  5654 
       
  5655   stack.x = function(z) {
       
  5656     if (!arguments.length) return x;
       
  5657     x = z;
       
  5658     return stack;
       
  5659   };
       
  5660 
       
  5661   stack.y = function(z) {
       
  5662     if (!arguments.length) return y;
       
  5663     y = z;
       
  5664     return stack;
       
  5665   };
       
  5666 
       
  5667   stack.out = function(z) {
       
  5668     if (!arguments.length) return out;
       
  5669     out = z;
       
  5670     return stack;
       
  5671   };
       
  5672 
       
  5673   return stack;
       
  5674 }
       
  5675 
       
  5676 function d3_layout_stackX(d) {
       
  5677   return d.x;
       
  5678 }
       
  5679 
       
  5680 function d3_layout_stackY(d) {
       
  5681   return d.y;
       
  5682 }
       
  5683 
       
  5684 function d3_layout_stackOut(d, y0, y) {
       
  5685   d.y0 = y0;
       
  5686   d.y = y;
       
  5687 }
       
  5688 
       
  5689 var d3_layout_stackOrders = d3.map({
       
  5690 
       
  5691   "inside-out": function(data) {
       
  5692     var n = data.length,
       
  5693         i,
       
  5694         j,
       
  5695         max = data.map(d3_layout_stackMaxIndex),
       
  5696         sums = data.map(d3_layout_stackReduceSum),
       
  5697         index = d3.range(n).sort(function(a, b) { return max[a] - max[b]; }),
       
  5698         top = 0,
       
  5699         bottom = 0,
       
  5700         tops = [],
       
  5701         bottoms = [];
       
  5702     for (i = 0; i < n; ++i) {
       
  5703       j = index[i];
       
  5704       if (top < bottom) {
       
  5705         top += sums[j];
       
  5706         tops.push(j);
       
  5707       } else {
       
  5708         bottom += sums[j];
       
  5709         bottoms.push(j);
       
  5710       }
       
  5711     }
       
  5712     return bottoms.reverse().concat(tops);
       
  5713   },
       
  5714 
       
  5715   "reverse": function(data) {
       
  5716     return d3.range(data.length).reverse();
       
  5717   },
       
  5718 
       
  5719   "default": d3_layout_stackOrderDefault
       
  5720 
       
  5721 });
       
  5722 
       
  5723 var d3_layout_stackOffsets = d3.map({
       
  5724 
       
  5725   "silhouette": function(data) {
       
  5726     var n = data.length,
       
  5727         m = data[0].length,
       
  5728         sums = [],
       
  5729         max = 0,
       
  5730         i,
       
  5731         j,
       
  5732         o,
       
  5733         y0 = [];
       
  5734     for (j = 0; j < m; ++j) {
       
  5735       for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
       
  5736       if (o > max) max = o;
       
  5737       sums.push(o);
       
  5738     }
       
  5739     for (j = 0; j < m; ++j) {
       
  5740       y0[j] = (max - sums[j]) / 2;
       
  5741     }
       
  5742     return y0;
       
  5743   },
       
  5744 
       
  5745   "wiggle": function(data) {
       
  5746     var n = data.length,
       
  5747         x = data[0],
       
  5748         m = x.length,
       
  5749         max = 0,
       
  5750         i,
       
  5751         j,
       
  5752         k,
       
  5753         s1,
       
  5754         s2,
       
  5755         s3,
       
  5756         dx,
       
  5757         o,
       
  5758         o0,
       
  5759         y0 = [];
       
  5760     y0[0] = o = o0 = 0;
       
  5761     for (j = 1; j < m; ++j) {
       
  5762       for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1];
       
  5763       for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) {
       
  5764         for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) {
       
  5765           s3 += (data[k][j][1] - data[k][j - 1][1]) / dx;
       
  5766         }
       
  5767         s2 += s3 * data[i][j][1];
       
  5768       }
       
  5769       y0[j] = o -= s1 ? s2 / s1 * dx : 0;
       
  5770       if (o < o0) o0 = o;
       
  5771     }
       
  5772     for (j = 0; j < m; ++j) y0[j] -= o0;
       
  5773     return y0;
       
  5774   },
       
  5775 
       
  5776   "expand": function(data) {
       
  5777     var n = data.length,
       
  5778         m = data[0].length,
       
  5779         k = 1 / n,
       
  5780         i,
       
  5781         j,
       
  5782         o,
       
  5783         y0 = [];
       
  5784     for (j = 0; j < m; ++j) {
       
  5785       for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
       
  5786       if (o) for (i = 0; i < n; i++) data[i][j][1] /= o;
       
  5787       else for (i = 0; i < n; i++) data[i][j][1] = k;
       
  5788     }
       
  5789     for (j = 0; j < m; ++j) y0[j] = 0;
       
  5790     return y0;
       
  5791   },
       
  5792 
       
  5793   "zero": d3_layout_stackOffsetZero
       
  5794 
       
  5795 });
       
  5796 
       
  5797 function d3_layout_stackOrderDefault(data) {
       
  5798   return d3.range(data.length);
       
  5799 }
       
  5800 
       
  5801 function d3_layout_stackOffsetZero(data) {
       
  5802   var j = -1,
       
  5803       m = data[0].length,
       
  5804       y0 = [];
       
  5805   while (++j < m) y0[j] = 0;
       
  5806   return y0;
       
  5807 }
       
  5808 
       
  5809 function d3_layout_stackMaxIndex(array) {
       
  5810   var i = 1,
       
  5811       j = 0,
       
  5812       v = array[0][1],
       
  5813       k,
       
  5814       n = array.length;
       
  5815   for (; i < n; ++i) {
       
  5816     if ((k = array[i][1]) > v) {
       
  5817       j = i;
       
  5818       v = k;
       
  5819     }
       
  5820   }
       
  5821   return j;
       
  5822 }
       
  5823 
       
  5824 function d3_layout_stackReduceSum(d) {
       
  5825   return d.reduce(d3_layout_stackSum, 0);
       
  5826 }
       
  5827 
       
  5828 function d3_layout_stackSum(p, d) {
       
  5829   return p + d[1];
       
  5830 }
       
  5831 d3.layout.histogram = function() {
       
  5832   var frequency = true,
       
  5833       valuer = Number,
       
  5834       ranger = d3_layout_histogramRange,
       
  5835       binner = d3_layout_histogramBinSturges;
       
  5836 
       
  5837   function histogram(data, i) {
       
  5838     var bins = [],
       
  5839         values = data.map(valuer, this),
       
  5840         range = ranger.call(this, values, i),
       
  5841         thresholds = binner.call(this, range, values, i),
       
  5842         bin,
       
  5843         i = -1,
       
  5844         n = values.length,
       
  5845         m = thresholds.length - 1,
       
  5846         k = frequency ? 1 : 1 / n,
       
  5847         x;
       
  5848 
       
  5849     // Initialize the bins.
       
  5850     while (++i < m) {
       
  5851       bin = bins[i] = [];
       
  5852       bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]);
       
  5853       bin.y = 0;
       
  5854     }
       
  5855 
       
  5856     // Fill the bins, ignoring values outside the range.
       
  5857     i = -1; while(++i < n) {
       
  5858       x = values[i];
       
  5859       if ((x >= range[0]) && (x <= range[1])) {
       
  5860         bin = bins[d3.bisect(thresholds, x, 1, m) - 1];
       
  5861         bin.y += k;
       
  5862         bin.push(data[i]);
       
  5863       }
       
  5864     }
       
  5865 
       
  5866     return bins;
       
  5867   }
       
  5868 
       
  5869   // Specifies how to extract a value from the associated data. The default
       
  5870   // value function is `Number`, which is equivalent to the identity function.
       
  5871   histogram.value = function(x) {
       
  5872     if (!arguments.length) return valuer;
       
  5873     valuer = x;
       
  5874     return histogram;
       
  5875   };
       
  5876 
       
  5877   // Specifies the range of the histogram. Values outside the specified range
       
  5878   // will be ignored. The argument `x` may be specified either as a two-element
       
  5879   // array representing the minimum and maximum value of the range, or as a
       
  5880   // function that returns the range given the array of values and the current
       
  5881   // index `i`. The default range is the extent (minimum and maximum) of the
       
  5882   // values.
       
  5883   histogram.range = function(x) {
       
  5884     if (!arguments.length) return ranger;
       
  5885     ranger = d3.functor(x);
       
  5886     return histogram;
       
  5887   };
       
  5888 
       
  5889   // Specifies how to bin values in the histogram. The argument `x` may be
       
  5890   // specified as a number, in which case the range of values will be split
       
  5891   // uniformly into the given number of bins. Or, `x` may be an array of
       
  5892   // threshold values, defining the bins; the specified array must contain the
       
  5893   // rightmost (upper) value, thus specifying n + 1 values for n bins. Or, `x`
       
  5894   // may be a function which is evaluated, being passed the range, the array of
       
  5895   // values, and the current index `i`, returning an array of thresholds. The
       
  5896   // default bin function will divide the values into uniform bins using
       
  5897   // Sturges' formula.
       
  5898   histogram.bins = function(x) {
       
  5899     if (!arguments.length) return binner;
       
  5900     binner = typeof x === "number"
       
  5901         ? function(range) { return d3_layout_histogramBinFixed(range, x); }
       
  5902         : d3.functor(x);
       
  5903     return histogram;
       
  5904   };
       
  5905 
       
  5906   // Specifies whether the histogram's `y` value is a count (frequency) or a
       
  5907   // probability (density). The default value is true.
       
  5908   histogram.frequency = function(x) {
       
  5909     if (!arguments.length) return frequency;
       
  5910     frequency = !!x;
       
  5911     return histogram;
       
  5912   };
       
  5913 
       
  5914   return histogram;
       
  5915 };
       
  5916 
       
  5917 function d3_layout_histogramBinSturges(range, values) {
       
  5918   return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1));
       
  5919 }
       
  5920 
       
  5921 function d3_layout_histogramBinFixed(range, n) {
       
  5922   var x = -1,
       
  5923       b = +range[0],
       
  5924       m = (range[1] - b) / n,
       
  5925       f = [];
       
  5926   while (++x <= n) f[x] = m * x + b;
       
  5927   return f;
       
  5928 }
       
  5929 
       
  5930 function d3_layout_histogramRange(values) {
       
  5931   return [d3.min(values), d3.max(values)];
       
  5932 }
       
  5933 d3.layout.hierarchy = function() {
       
  5934   var sort = d3_layout_hierarchySort,
       
  5935       children = d3_layout_hierarchyChildren,
       
  5936       value = d3_layout_hierarchyValue;
       
  5937 
       
  5938   // Recursively compute the node depth and value.
       
  5939   // Also converts the data representation into a standard hierarchy structure.
       
  5940   function recurse(data, depth, nodes) {
       
  5941     var childs = children.call(hierarchy, data, depth),
       
  5942         node = d3_layout_hierarchyInline ? data : {data: data};
       
  5943     node.depth = depth;
       
  5944     nodes.push(node);
       
  5945     if (childs && (n = childs.length)) {
       
  5946       var i = -1,
       
  5947           n,
       
  5948           c = node.children = [],
       
  5949           v = 0,
       
  5950           j = depth + 1;
       
  5951       while (++i < n) {
       
  5952         d = recurse(childs[i], j, nodes);
       
  5953         d.parent = node;
       
  5954         c.push(d);
       
  5955         v += d.value;
       
  5956       }
       
  5957       if (sort) c.sort(sort);
       
  5958       if (value) node.value = v;
       
  5959     } else if (value) {
       
  5960       node.value = +value.call(hierarchy, data, depth) || 0;
       
  5961     }
       
  5962     return node;
       
  5963   }
       
  5964 
       
  5965   // Recursively re-evaluates the node value.
       
  5966   function revalue(node, depth) {
       
  5967     var children = node.children,
       
  5968         v = 0;
       
  5969     if (children && (n = children.length)) {
       
  5970       var i = -1,
       
  5971           n,
       
  5972           j = depth + 1;
       
  5973       while (++i < n) v += revalue(children[i], j);
       
  5974     } else if (value) {
       
  5975       v = +value.call(hierarchy, d3_layout_hierarchyInline ? node : node.data, depth) || 0;
       
  5976     }
       
  5977     if (value) node.value = v;
       
  5978     return v;
       
  5979   }
       
  5980 
       
  5981   function hierarchy(d) {
       
  5982     var nodes = [];
       
  5983     recurse(d, 0, nodes);
       
  5984     return nodes;
       
  5985   }
       
  5986 
       
  5987   hierarchy.sort = function(x) {
       
  5988     if (!arguments.length) return sort;
       
  5989     sort = x;
       
  5990     return hierarchy;
       
  5991   };
       
  5992 
       
  5993   hierarchy.children = function(x) {
       
  5994     if (!arguments.length) return children;
       
  5995     children = x;
       
  5996     return hierarchy;
       
  5997   };
       
  5998 
       
  5999   hierarchy.value = function(x) {
       
  6000     if (!arguments.length) return value;
       
  6001     value = x;
       
  6002     return hierarchy;
       
  6003   };
       
  6004 
       
  6005   // Re-evaluates the `value` property for the specified hierarchy.
       
  6006   hierarchy.revalue = function(root) {
       
  6007     revalue(root, 0);
       
  6008     return root;
       
  6009   };
       
  6010 
       
  6011   return hierarchy;
       
  6012 };
       
  6013 
       
  6014 // A method assignment helper for hierarchy subclasses.
       
  6015 function d3_layout_hierarchyRebind(object, hierarchy) {
       
  6016   d3.rebind(object, hierarchy, "sort", "children", "value");
       
  6017 
       
  6018   // Add an alias for links, for convenience.
       
  6019   object.links = d3_layout_hierarchyLinks;
       
  6020 
       
  6021   // If the new API is used, enabling inlining.
       
  6022   object.nodes = function(d) {
       
  6023     d3_layout_hierarchyInline = true;
       
  6024     return (object.nodes = object)(d);
       
  6025   };
       
  6026 
       
  6027   return object;
       
  6028 }
       
  6029 
       
  6030 function d3_layout_hierarchyChildren(d) {
       
  6031   return d.children;
       
  6032 }
       
  6033 
       
  6034 function d3_layout_hierarchyValue(d) {
       
  6035   return d.value;
       
  6036 }
       
  6037 
       
  6038 function d3_layout_hierarchySort(a, b) {
       
  6039   return b.value - a.value;
       
  6040 }
       
  6041 
       
  6042 // Returns an array source+target objects for the specified nodes.
       
  6043 function d3_layout_hierarchyLinks(nodes) {
       
  6044   return d3.merge(nodes.map(function(parent) {
       
  6045     return (parent.children || []).map(function(child) {
       
  6046       return {source: parent, target: child};
       
  6047     });
       
  6048   }));
       
  6049 }
       
  6050 
       
  6051 // For backwards-compatibility, don't enable inlining by default.
       
  6052 var d3_layout_hierarchyInline = false;
       
  6053 d3.layout.pack = function() {
       
  6054   var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort),
       
  6055       size = [1, 1];
       
  6056 
       
  6057   function pack(d, i) {
       
  6058     var nodes = hierarchy.call(this, d, i),
       
  6059         root = nodes[0];
       
  6060 
       
  6061     // Recursively compute the layout.
       
  6062     root.x = 0;
       
  6063     root.y = 0;
       
  6064     d3_layout_packTree(root);
       
  6065 
       
  6066     // Scale the layout to fit the requested size.
       
  6067     var w = size[0],
       
  6068         h = size[1],
       
  6069         k = 1 / Math.max(2 * root.r / w, 2 * root.r / h);
       
  6070     d3_layout_packTransform(root, w / 2, h / 2, k);
       
  6071 
       
  6072     return nodes;
       
  6073   }
       
  6074 
       
  6075   pack.size = function(x) {
       
  6076     if (!arguments.length) return size;
       
  6077     size = x;
       
  6078     return pack;
       
  6079   };
       
  6080 
       
  6081   return d3_layout_hierarchyRebind(pack, hierarchy);
       
  6082 };
       
  6083 
       
  6084 function d3_layout_packSort(a, b) {
       
  6085   return a.value - b.value;
       
  6086 }
       
  6087 
       
  6088 function d3_layout_packInsert(a, b) {
       
  6089   var c = a._pack_next;
       
  6090   a._pack_next = b;
       
  6091   b._pack_prev = a;
       
  6092   b._pack_next = c;
       
  6093   c._pack_prev = b;
       
  6094 }
       
  6095 
       
  6096 function d3_layout_packSplice(a, b) {
       
  6097   a._pack_next = b;
       
  6098   b._pack_prev = a;
       
  6099 }
       
  6100 
       
  6101 function d3_layout_packIntersects(a, b) {
       
  6102   var dx = b.x - a.x,
       
  6103       dy = b.y - a.y,
       
  6104       dr = a.r + b.r;
       
  6105   return dr * dr - dx * dx - dy * dy > .001; // within epsilon
       
  6106 }
       
  6107 
       
  6108 function d3_layout_packCircle(nodes) {
       
  6109   var xMin = Infinity,
       
  6110       xMax = -Infinity,
       
  6111       yMin = Infinity,
       
  6112       yMax = -Infinity,
       
  6113       n = nodes.length,
       
  6114       a, b, c, j, k;
       
  6115 
       
  6116   function bound(node) {
       
  6117     xMin = Math.min(node.x - node.r, xMin);
       
  6118     xMax = Math.max(node.x + node.r, xMax);
       
  6119     yMin = Math.min(node.y - node.r, yMin);
       
  6120     yMax = Math.max(node.y + node.r, yMax);
       
  6121   }
       
  6122 
       
  6123   // Create node links.
       
  6124   nodes.forEach(d3_layout_packLink);
       
  6125 
       
  6126   // Create first node.
       
  6127   a = nodes[0];
       
  6128   a.x = -a.r;
       
  6129   a.y = 0;
       
  6130   bound(a);
       
  6131 
       
  6132   // Create second node.
       
  6133   if (n > 1) {
       
  6134     b = nodes[1];
       
  6135     b.x = b.r;
       
  6136     b.y = 0;
       
  6137     bound(b);
       
  6138 
       
  6139     // Create third node and build chain.
       
  6140     if (n > 2) {
       
  6141       c = nodes[2];
       
  6142       d3_layout_packPlace(a, b, c);
       
  6143       bound(c);
       
  6144       d3_layout_packInsert(a, c);
       
  6145       a._pack_prev = c;
       
  6146       d3_layout_packInsert(c, b);
       
  6147       b = a._pack_next;
       
  6148 
       
  6149       // Now iterate through the rest.
       
  6150       for (var i = 3; i < n; i++) {
       
  6151         d3_layout_packPlace(a, b, c = nodes[i]);
       
  6152 
       
  6153         // Search for the closest intersection.
       
  6154         var isect = 0, s1 = 1, s2 = 1;
       
  6155         for (j = b._pack_next; j !== b; j = j._pack_next, s1++) {
       
  6156           if (d3_layout_packIntersects(j, c)) {
       
  6157             isect = 1;
       
  6158             break;
       
  6159           }
       
  6160         }
       
  6161         if (isect == 1) {
       
  6162           for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) {
       
  6163             if (d3_layout_packIntersects(k, c)) {
       
  6164               break;
       
  6165             }
       
  6166           }
       
  6167         }
       
  6168 
       
  6169         // Update node chain.
       
  6170         if (isect) {
       
  6171           if (s1 < s2 || (s1 == s2 && b.r < a.r)) d3_layout_packSplice(a, b = j);
       
  6172           else d3_layout_packSplice(a = k, b);
       
  6173           i--;
       
  6174         } else {
       
  6175           d3_layout_packInsert(a, c);
       
  6176           b = c;
       
  6177           bound(c);
       
  6178         }
       
  6179       }
       
  6180     }
       
  6181   }
       
  6182 
       
  6183   // Re-center the circles and return the encompassing radius.
       
  6184   var cx = (xMin + xMax) / 2,
       
  6185       cy = (yMin + yMax) / 2,
       
  6186       cr = 0;
       
  6187   for (var i = 0; i < n; i++) {
       
  6188     var node = nodes[i];
       
  6189     node.x -= cx;
       
  6190     node.y -= cy;
       
  6191     cr = Math.max(cr, node.r + Math.sqrt(node.x * node.x + node.y * node.y));
       
  6192   }
       
  6193 
       
  6194   // Remove node links.
       
  6195   nodes.forEach(d3_layout_packUnlink);
       
  6196 
       
  6197   return cr;
       
  6198 }
       
  6199 
       
  6200 function d3_layout_packLink(node) {
       
  6201   node._pack_next = node._pack_prev = node;
       
  6202 }
       
  6203 
       
  6204 function d3_layout_packUnlink(node) {
       
  6205   delete node._pack_next;
       
  6206   delete node._pack_prev;
       
  6207 }
       
  6208 
       
  6209 function d3_layout_packTree(node) {
       
  6210   var children = node.children;
       
  6211   if (children && children.length) {
       
  6212     children.forEach(d3_layout_packTree);
       
  6213     node.r = d3_layout_packCircle(children);
       
  6214   } else {
       
  6215     node.r = Math.sqrt(node.value);
       
  6216   }
       
  6217 }
       
  6218 
       
  6219 function d3_layout_packTransform(node, x, y, k) {
       
  6220   var children = node.children;
       
  6221   node.x = (x += k * node.x);
       
  6222   node.y = (y += k * node.y);
       
  6223   node.r *= k;
       
  6224   if (children) {
       
  6225     var i = -1, n = children.length;
       
  6226     while (++i < n) d3_layout_packTransform(children[i], x, y, k);
       
  6227   }
       
  6228 }
       
  6229 
       
  6230 function d3_layout_packPlace(a, b, c) {
       
  6231   var db = a.r + c.r,
       
  6232       dx = b.x - a.x,
       
  6233       dy = b.y - a.y;
       
  6234   if (db && (dx || dy)) {
       
  6235     var da = b.r + c.r,
       
  6236         dc = Math.sqrt(dx * dx + dy * dy),
       
  6237         cos = Math.max(-1, Math.min(1, (db * db + dc * dc - da * da) / (2 * db * dc))),
       
  6238         theta = Math.acos(cos),
       
  6239         x = cos * (db /= dc),
       
  6240         y = Math.sin(theta) * db;
       
  6241     c.x = a.x + x * dx + y * dy;
       
  6242     c.y = a.y + x * dy - y * dx;
       
  6243   } else {
       
  6244     c.x = a.x + db;
       
  6245     c.y = a.y;
       
  6246   }
       
  6247 }
       
  6248 // Implements a hierarchical layout using the cluster (or dendrogram)
       
  6249 // algorithm.
       
  6250 d3.layout.cluster = function() {
       
  6251   var hierarchy = d3.layout.hierarchy().sort(null).value(null),
       
  6252       separation = d3_layout_treeSeparation,
       
  6253       size = [1, 1]; // width, height
       
  6254 
       
  6255   function cluster(d, i) {
       
  6256     var nodes = hierarchy.call(this, d, i),
       
  6257         root = nodes[0],
       
  6258         previousNode,
       
  6259         x = 0,
       
  6260         kx,
       
  6261         ky;
       
  6262 
       
  6263     // First walk, computing the initial x & y values.
       
  6264     d3_layout_treeVisitAfter(root, function(node) {
       
  6265       var children = node.children;
       
  6266       if (children && children.length) {
       
  6267         node.x = d3_layout_clusterX(children);
       
  6268         node.y = d3_layout_clusterY(children);
       
  6269       } else {
       
  6270         node.x = previousNode ? x += separation(node, previousNode) : 0;
       
  6271         node.y = 0;
       
  6272         previousNode = node;
       
  6273       }
       
  6274     });
       
  6275 
       
  6276     // Compute the left-most, right-most, and depth-most nodes for extents.
       
  6277     var left = d3_layout_clusterLeft(root),
       
  6278         right = d3_layout_clusterRight(root),
       
  6279         x0 = left.x - separation(left, right) / 2,
       
  6280         x1 = right.x + separation(right, left) / 2;
       
  6281 
       
  6282     // Second walk, normalizing x & y to the desired size.
       
  6283     d3_layout_treeVisitAfter(root, function(node) {
       
  6284       node.x = (node.x - x0) / (x1 - x0) * size[0];
       
  6285       node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1];
       
  6286     });
       
  6287 
       
  6288     return nodes;
       
  6289   }
       
  6290 
       
  6291   cluster.separation = function(x) {
       
  6292     if (!arguments.length) return separation;
       
  6293     separation = x;
       
  6294     return cluster;
       
  6295   };
       
  6296 
       
  6297   cluster.size = function(x) {
       
  6298     if (!arguments.length) return size;
       
  6299     size = x;
       
  6300     return cluster;
       
  6301   };
       
  6302 
       
  6303   return d3_layout_hierarchyRebind(cluster, hierarchy);
       
  6304 };
       
  6305 
       
  6306 function d3_layout_clusterY(children) {
       
  6307   return 1 + d3.max(children, function(child) {
       
  6308     return child.y;
       
  6309   });
       
  6310 }
       
  6311 
       
  6312 function d3_layout_clusterX(children) {
       
  6313   return children.reduce(function(x, child) {
       
  6314     return x + child.x;
       
  6315   }, 0) / children.length;
       
  6316 }
       
  6317 
       
  6318 function d3_layout_clusterLeft(node) {
       
  6319   var children = node.children;
       
  6320   return children && children.length ? d3_layout_clusterLeft(children[0]) : node;
       
  6321 }
       
  6322 
       
  6323 function d3_layout_clusterRight(node) {
       
  6324   var children = node.children, n;
       
  6325   return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node;
       
  6326 }
       
  6327 // Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
       
  6328 d3.layout.tree = function() {
       
  6329   var hierarchy = d3.layout.hierarchy().sort(null).value(null),
       
  6330       separation = d3_layout_treeSeparation,
       
  6331       size = [1, 1]; // width, height
       
  6332 
       
  6333   function tree(d, i) {
       
  6334     var nodes = hierarchy.call(this, d, i),
       
  6335         root = nodes[0];
       
  6336 
       
  6337     function firstWalk(node, previousSibling) {
       
  6338       var children = node.children,
       
  6339           layout = node._tree;
       
  6340       if (children && (n = children.length)) {
       
  6341         var n,
       
  6342             firstChild = children[0],
       
  6343             previousChild,
       
  6344             ancestor = firstChild,
       
  6345             child,
       
  6346             i = -1;
       
  6347         while (++i < n) {
       
  6348           child = children[i];
       
  6349           firstWalk(child, previousChild);
       
  6350           ancestor = apportion(child, previousChild, ancestor);
       
  6351           previousChild = child;
       
  6352         }
       
  6353         d3_layout_treeShift(node);
       
  6354         var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim);
       
  6355         if (previousSibling) {
       
  6356           layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
       
  6357           layout.mod = layout.prelim - midpoint;
       
  6358         } else {
       
  6359           layout.prelim = midpoint;
       
  6360         }
       
  6361       } else {
       
  6362         if (previousSibling) {
       
  6363           layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
       
  6364         }
       
  6365       }
       
  6366     }
       
  6367 
       
  6368     function secondWalk(node, x) {
       
  6369       node.x = node._tree.prelim + x;
       
  6370       var children = node.children;
       
  6371       if (children && (n = children.length)) {
       
  6372         var i = -1,
       
  6373             n;
       
  6374         x += node._tree.mod;
       
  6375         while (++i < n) {
       
  6376           secondWalk(children[i], x);
       
  6377         }
       
  6378       }
       
  6379     }
       
  6380 
       
  6381     function apportion(node, previousSibling, ancestor) {
       
  6382       if (previousSibling) {
       
  6383         var vip = node,
       
  6384             vop = node,
       
  6385             vim = previousSibling,
       
  6386             vom = node.parent.children[0],
       
  6387             sip = vip._tree.mod,
       
  6388             sop = vop._tree.mod,
       
  6389             sim = vim._tree.mod,
       
  6390             som = vom._tree.mod,
       
  6391             shift;
       
  6392         while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {
       
  6393           vom = d3_layout_treeLeft(vom);
       
  6394           vop = d3_layout_treeRight(vop);
       
  6395           vop._tree.ancestor = node;
       
  6396           shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip);
       
  6397           if (shift > 0) {
       
  6398             d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift);
       
  6399             sip += shift;
       
  6400             sop += shift;
       
  6401           }
       
  6402           sim += vim._tree.mod;
       
  6403           sip += vip._tree.mod;
       
  6404           som += vom._tree.mod;
       
  6405           sop += vop._tree.mod;
       
  6406         }
       
  6407         if (vim && !d3_layout_treeRight(vop)) {
       
  6408           vop._tree.thread = vim;
       
  6409           vop._tree.mod += sim - sop;
       
  6410         }
       
  6411         if (vip && !d3_layout_treeLeft(vom)) {
       
  6412           vom._tree.thread = vip;
       
  6413           vom._tree.mod += sip - som;
       
  6414           ancestor = node;
       
  6415         }
       
  6416       }
       
  6417       return ancestor;
       
  6418     }
       
  6419 
       
  6420     // Initialize temporary layout variables.
       
  6421     d3_layout_treeVisitAfter(root, function(node, previousSibling) {
       
  6422       node._tree = {
       
  6423         ancestor: node,
       
  6424         prelim: 0,
       
  6425         mod: 0,
       
  6426         change: 0,
       
  6427         shift: 0,
       
  6428         number: previousSibling ? previousSibling._tree.number + 1 : 0
       
  6429       };
       
  6430     });
       
  6431 
       
  6432     // Compute the layout using Buchheim et al.'s algorithm.
       
  6433     firstWalk(root);
       
  6434     secondWalk(root, -root._tree.prelim);
       
  6435 
       
  6436     // Compute the left-most, right-most, and depth-most nodes for extents.
       
  6437     var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost),
       
  6438         right = d3_layout_treeSearch(root, d3_layout_treeRightmost),
       
  6439         deep = d3_layout_treeSearch(root, d3_layout_treeDeepest),
       
  6440         x0 = left.x - separation(left, right) / 2,
       
  6441         x1 = right.x + separation(right, left) / 2,
       
  6442         y1 = deep.depth || 1;
       
  6443 
       
  6444     // Clear temporary layout variables; transform x and y.
       
  6445     d3_layout_treeVisitAfter(root, function(node) {
       
  6446       node.x = (node.x - x0) / (x1 - x0) * size[0];
       
  6447       node.y = node.depth / y1 * size[1];
       
  6448       delete node._tree;
       
  6449     });
       
  6450 
       
  6451     return nodes;
       
  6452   }
       
  6453 
       
  6454   tree.separation = function(x) {
       
  6455     if (!arguments.length) return separation;
       
  6456     separation = x;
       
  6457     return tree;
       
  6458   };
       
  6459 
       
  6460   tree.size = function(x) {
       
  6461     if (!arguments.length) return size;
       
  6462     size = x;
       
  6463     return tree;
       
  6464   };
       
  6465 
       
  6466   return d3_layout_hierarchyRebind(tree, hierarchy);
       
  6467 };
       
  6468 
       
  6469 function d3_layout_treeSeparation(a, b) {
       
  6470   return a.parent == b.parent ? 1 : 2;
       
  6471 }
       
  6472 
       
  6473 // function d3_layout_treeSeparationRadial(a, b) {
       
  6474 //   return (a.parent == b.parent ? 1 : 2) / a.depth;
       
  6475 // }
       
  6476 
       
  6477 function d3_layout_treeLeft(node) {
       
  6478   var children = node.children;
       
  6479   return children && children.length ? children[0] : node._tree.thread;
       
  6480 }
       
  6481 
       
  6482 function d3_layout_treeRight(node) {
       
  6483   var children = node.children,
       
  6484       n;
       
  6485   return children && (n = children.length) ? children[n - 1] : node._tree.thread;
       
  6486 }
       
  6487 
       
  6488 function d3_layout_treeSearch(node, compare) {
       
  6489   var children = node.children;
       
  6490   if (children && (n = children.length)) {
       
  6491     var child,
       
  6492         n,
       
  6493         i = -1;
       
  6494     while (++i < n) {
       
  6495       if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) {
       
  6496         node = child;
       
  6497       }
       
  6498     }
       
  6499   }
       
  6500   return node;
       
  6501 }
       
  6502 
       
  6503 function d3_layout_treeRightmost(a, b) {
       
  6504   return a.x - b.x;
       
  6505 }
       
  6506 
       
  6507 function d3_layout_treeLeftmost(a, b) {
       
  6508   return b.x - a.x;
       
  6509 }
       
  6510 
       
  6511 function d3_layout_treeDeepest(a, b) {
       
  6512   return a.depth - b.depth;
       
  6513 }
       
  6514 
       
  6515 function d3_layout_treeVisitAfter(node, callback) {
       
  6516   function visit(node, previousSibling) {
       
  6517     var children = node.children;
       
  6518     if (children && (n = children.length)) {
       
  6519       var child,
       
  6520           previousChild = null,
       
  6521           i = -1,
       
  6522           n;
       
  6523       while (++i < n) {
       
  6524         child = children[i];
       
  6525         visit(child, previousChild);
       
  6526         previousChild = child;
       
  6527       }
       
  6528     }
       
  6529     callback(node, previousSibling);
       
  6530   }
       
  6531   visit(node, null);
       
  6532 }
       
  6533 
       
  6534 function d3_layout_treeShift(node) {
       
  6535   var shift = 0,
       
  6536       change = 0,
       
  6537       children = node.children,
       
  6538       i = children.length,
       
  6539       child;
       
  6540   while (--i >= 0) {
       
  6541     child = children[i]._tree;
       
  6542     child.prelim += shift;
       
  6543     child.mod += shift;
       
  6544     shift += child.shift + (change += child.change);
       
  6545   }
       
  6546 }
       
  6547 
       
  6548 function d3_layout_treeMove(ancestor, node, shift) {
       
  6549   ancestor = ancestor._tree;
       
  6550   node = node._tree;
       
  6551   var change = shift / (node.number - ancestor.number);
       
  6552   ancestor.change += change;
       
  6553   node.change -= change;
       
  6554   node.shift += shift;
       
  6555   node.prelim += shift;
       
  6556   node.mod += shift;
       
  6557 }
       
  6558 
       
  6559 function d3_layout_treeAncestor(vim, node, ancestor) {
       
  6560   return vim._tree.ancestor.parent == node.parent
       
  6561       ? vim._tree.ancestor
       
  6562       : ancestor;
       
  6563 }
       
  6564 // Squarified Treemaps by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
       
  6565 // Modified to support a target aspect ratio by Jeff Heer
       
  6566 d3.layout.treemap = function() {
       
  6567   var hierarchy = d3.layout.hierarchy(),
       
  6568       round = Math.round,
       
  6569       size = [1, 1], // width, height
       
  6570       padding = null,
       
  6571       pad = d3_layout_treemapPadNull,
       
  6572       sticky = false,
       
  6573       stickies,
       
  6574       ratio = 0.5 * (1 + Math.sqrt(5)); // golden ratio
       
  6575 
       
  6576   // Compute the area for each child based on value & scale.
       
  6577   function scale(children, k) {
       
  6578     var i = -1,
       
  6579         n = children.length,
       
  6580         child,
       
  6581         area;
       
  6582     while (++i < n) {
       
  6583       area = (child = children[i]).value * (k < 0 ? 0 : k);
       
  6584       child.area = isNaN(area) || area <= 0 ? 0 : area;
       
  6585     }
       
  6586   }
       
  6587 
       
  6588   // Recursively arranges the specified node's children into squarified rows.
       
  6589   function squarify(node) {
       
  6590     var children = node.children;
       
  6591     if (children && children.length) {
       
  6592       var rect = pad(node),
       
  6593           row = [],
       
  6594           remaining = children.slice(), // copy-on-write
       
  6595           child,
       
  6596           best = Infinity, // the best row score so far
       
  6597           score, // the current row score
       
  6598           u = Math.min(rect.dx, rect.dy), // initial orientation
       
  6599           n;
       
  6600       scale(remaining, rect.dx * rect.dy / node.value);
       
  6601       row.area = 0;
       
  6602       while ((n = remaining.length) > 0) {
       
  6603         row.push(child = remaining[n - 1]);
       
  6604         row.area += child.area;
       
  6605         if ((score = worst(row, u)) <= best) { // continue with this orientation
       
  6606           remaining.pop();
       
  6607           best = score;
       
  6608         } else { // abort, and try a different orientation
       
  6609           row.area -= row.pop().area;
       
  6610           position(row, u, rect, false);
       
  6611           u = Math.min(rect.dx, rect.dy);
       
  6612           row.length = row.area = 0;
       
  6613           best = Infinity;
       
  6614         }
       
  6615       }
       
  6616       if (row.length) {
       
  6617         position(row, u, rect, true);
       
  6618         row.length = row.area = 0;
       
  6619       }
       
  6620       children.forEach(squarify);
       
  6621     }
       
  6622   }
       
  6623 
       
  6624   // Recursively resizes the specified node's children into existing rows.
       
  6625   // Preserves the existing layout!
       
  6626   function stickify(node) {
       
  6627     var children = node.children;
       
  6628     if (children && children.length) {
       
  6629       var rect = pad(node),
       
  6630           remaining = children.slice(), // copy-on-write
       
  6631           child,
       
  6632           row = [];
       
  6633       scale(remaining, rect.dx * rect.dy / node.value);
       
  6634       row.area = 0;
       
  6635       while (child = remaining.pop()) {
       
  6636         row.push(child);
       
  6637         row.area += child.area;
       
  6638         if (child.z != null) {
       
  6639           position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length);
       
  6640           row.length = row.area = 0;
       
  6641         }
       
  6642       }
       
  6643       children.forEach(stickify);
       
  6644     }
       
  6645   }
       
  6646 
       
  6647   // Computes the score for the specified row, as the worst aspect ratio.
       
  6648   function worst(row, u) {
       
  6649     var s = row.area,
       
  6650         r,
       
  6651         rmax = 0,
       
  6652         rmin = Infinity,
       
  6653         i = -1,
       
  6654         n = row.length;
       
  6655     while (++i < n) {
       
  6656       if (!(r = row[i].area)) continue;
       
  6657       if (r < rmin) rmin = r;
       
  6658       if (r > rmax) rmax = r;
       
  6659     }
       
  6660     s *= s;
       
  6661     u *= u;
       
  6662     return s
       
  6663         ? Math.max((u * rmax * ratio) / s, s / (u * rmin * ratio))
       
  6664         : Infinity;
       
  6665   }
       
  6666 
       
  6667   // Positions the specified row of nodes. Modifies `rect`.
       
  6668   function position(row, u, rect, flush) {
       
  6669     var i = -1,
       
  6670         n = row.length,
       
  6671         x = rect.x,
       
  6672         y = rect.y,
       
  6673         v = u ? round(row.area / u) : 0,
       
  6674         o;
       
  6675     if (u == rect.dx) { // horizontal subdivision
       
  6676       if (flush || v > rect.dy) v = rect.dy; // over+underflow
       
  6677       while (++i < n) {
       
  6678         o = row[i];
       
  6679         o.x = x;
       
  6680         o.y = y;
       
  6681         o.dy = v;
       
  6682         x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0);
       
  6683       }
       
  6684       o.z = true;
       
  6685       o.dx += rect.x + rect.dx - x; // rounding error
       
  6686       rect.y += v;
       
  6687       rect.dy -= v;
       
  6688     } else { // vertical subdivision
       
  6689       if (flush || v > rect.dx) v = rect.dx; // over+underflow
       
  6690       while (++i < n) {
       
  6691         o = row[i];
       
  6692         o.x = x;
       
  6693         o.y = y;
       
  6694         o.dx = v;
       
  6695         y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0);
       
  6696       }
       
  6697       o.z = false;
       
  6698       o.dy += rect.y + rect.dy - y; // rounding error
       
  6699       rect.x += v;
       
  6700       rect.dx -= v;
       
  6701     }
       
  6702   }
       
  6703 
       
  6704   function treemap(d) {
       
  6705     var nodes = stickies || hierarchy(d),
       
  6706         root = nodes[0];
       
  6707     root.x = 0;
       
  6708     root.y = 0;
       
  6709     root.dx = size[0];
       
  6710     root.dy = size[1];
       
  6711     if (stickies) hierarchy.revalue(root);
       
  6712     scale([root], root.dx * root.dy / root.value);
       
  6713     (stickies ? stickify : squarify)(root);
       
  6714     if (sticky) stickies = nodes;
       
  6715     return nodes;
       
  6716   }
       
  6717 
       
  6718   treemap.size = function(x) {
       
  6719     if (!arguments.length) return size;
       
  6720     size = x;
       
  6721     return treemap;
       
  6722   };
       
  6723 
       
  6724   treemap.padding = function(x) {
       
  6725     if (!arguments.length) return padding;
       
  6726 
       
  6727     function padFunction(node) {
       
  6728       var p = x.call(treemap, node, node.depth);
       
  6729       return p == null
       
  6730           ? d3_layout_treemapPadNull(node)
       
  6731           : d3_layout_treemapPad(node, typeof p === "number" ? [p, p, p, p] : p);
       
  6732     }
       
  6733 
       
  6734     function padConstant(node) {
       
  6735       return d3_layout_treemapPad(node, x);
       
  6736     }
       
  6737 
       
  6738     var type;
       
  6739     pad = (padding = x) == null ? d3_layout_treemapPadNull
       
  6740         : (type = typeof x) === "function" ? padFunction
       
  6741         : type === "number" ? (x = [x, x, x, x], padConstant)
       
  6742         : padConstant;
       
  6743     return treemap;
       
  6744   };
       
  6745 
       
  6746   treemap.round = function(x) {
       
  6747     if (!arguments.length) return round != Number;
       
  6748     round = x ? Math.round : Number;
       
  6749     return treemap;
       
  6750   };
       
  6751 
       
  6752   treemap.sticky = function(x) {
       
  6753     if (!arguments.length) return sticky;
       
  6754     sticky = x;
       
  6755     stickies = null;
       
  6756     return treemap;
       
  6757   };
       
  6758 
       
  6759   treemap.ratio = function(x) {
       
  6760     if (!arguments.length) return ratio;
       
  6761     ratio = x;
       
  6762     return treemap;
       
  6763   };
       
  6764 
       
  6765   return d3_layout_hierarchyRebind(treemap, hierarchy);
       
  6766 };
       
  6767 
       
  6768 function d3_layout_treemapPadNull(node) {
       
  6769   return {x: node.x, y: node.y, dx: node.dx, dy: node.dy};
       
  6770 }
       
  6771 
       
  6772 function d3_layout_treemapPad(node, padding) {
       
  6773   var x = node.x + padding[3],
       
  6774       y = node.y + padding[0],
       
  6775       dx = node.dx - padding[1] - padding[3],
       
  6776       dy = node.dy - padding[0] - padding[2];
       
  6777   if (dx < 0) { x += dx / 2; dx = 0; }
       
  6778   if (dy < 0) { y += dy / 2; dy = 0; }
       
  6779   return {x: x, y: y, dx: dx, dy: dy};
       
  6780 }
       
  6781 d3.csv = function(url, callback) {
       
  6782   d3.text(url, "text/csv", function(text) {
       
  6783     callback(text && d3.csv.parse(text));
       
  6784   });
       
  6785 };
       
  6786 d3.csv.parse = function(text) {
       
  6787   var header;
       
  6788   return d3.csv.parseRows(text, function(row, i) {
       
  6789     if (i) {
       
  6790       var o = {}, j = -1, m = header.length;
       
  6791       while (++j < m) o[header[j]] = row[j];
       
  6792       return o;
       
  6793     } else {
       
  6794       header = row;
       
  6795       return null;
       
  6796     }
       
  6797   });
       
  6798 };
       
  6799 
       
  6800 d3.csv.parseRows = function(text, f) {
       
  6801   var EOL = {}, // sentinel value for end-of-line
       
  6802       EOF = {}, // sentinel value for end-of-file
       
  6803       rows = [], // output rows
       
  6804       re = /\r\n|[,\r\n]/g, // field separator regex
       
  6805       n = 0, // the current line number
       
  6806       t, // the current token
       
  6807       eol; // is the current token followed by EOL?
       
  6808 
       
  6809   re.lastIndex = 0; // work-around bug in FF 3.6
       
  6810 
       
  6811   /** @private Returns the next token. */
       
  6812   function token() {
       
  6813     if (re.lastIndex >= text.length) return EOF; // special case: end of file
       
  6814     if (eol) { eol = false; return EOL; } // special case: end of line
       
  6815 
       
  6816     // special case: quotes
       
  6817     var j = re.lastIndex;
       
  6818     if (text.charCodeAt(j) === 34) {
       
  6819       var i = j;
       
  6820       while (i++ < text.length) {
       
  6821         if (text.charCodeAt(i) === 34) {
       
  6822           if (text.charCodeAt(i + 1) !== 34) break;
       
  6823           i++;
       
  6824         }
       
  6825       }
       
  6826       re.lastIndex = i + 2;
       
  6827       var c = text.charCodeAt(i + 1);
       
  6828       if (c === 13) {
       
  6829         eol = true;
       
  6830         if (text.charCodeAt(i + 2) === 10) re.lastIndex++;
       
  6831       } else if (c === 10) {
       
  6832         eol = true;
       
  6833       }
       
  6834       return text.substring(j + 1, i).replace(/""/g, "\"");
       
  6835     }
       
  6836 
       
  6837     // common case
       
  6838     var m = re.exec(text);
       
  6839     if (m) {
       
  6840       eol = m[0].charCodeAt(0) !== 44;
       
  6841       return text.substring(j, m.index);
       
  6842     }
       
  6843     re.lastIndex = text.length;
       
  6844     return text.substring(j);
       
  6845   }
       
  6846 
       
  6847   while ((t = token()) !== EOF) {
       
  6848     var a = [];
       
  6849     while ((t !== EOL) && (t !== EOF)) {
       
  6850       a.push(t);
       
  6851       t = token();
       
  6852     }
       
  6853     if (f && !(a = f(a, n++))) continue;
       
  6854     rows.push(a);
       
  6855   }
       
  6856 
       
  6857   return rows;
       
  6858 };
       
  6859 d3.csv.format = function(rows) {
       
  6860   return rows.map(d3_csv_formatRow).join("\n");
       
  6861 };
       
  6862 
       
  6863 function d3_csv_formatRow(row) {
       
  6864   return row.map(d3_csv_formatValue).join(",");
       
  6865 }
       
  6866 
       
  6867 function d3_csv_formatValue(text) {
       
  6868   return /[",\n]/.test(text)
       
  6869       ? "\"" + text.replace(/\"/g, "\"\"") + "\""
       
  6870       : text;
       
  6871 }
       
  6872 d3.geo = {};
       
  6873 
       
  6874 var d3_geo_radians = Math.PI / 180;
       
  6875 // TODO clip input coordinates on opposite hemisphere
       
  6876 d3.geo.azimuthal = function() {
       
  6877   var mode = "orthographic", // or stereographic, gnomonic, equidistant or equalarea
       
  6878       origin,
       
  6879       scale = 200,
       
  6880       translate = [480, 250],
       
  6881       x0,
       
  6882       y0,
       
  6883       cy0,
       
  6884       sy0;
       
  6885 
       
  6886   function azimuthal(coordinates) {
       
  6887     var x1 = coordinates[0] * d3_geo_radians - x0,
       
  6888         y1 = coordinates[1] * d3_geo_radians,
       
  6889         cx1 = Math.cos(x1),
       
  6890         sx1 = Math.sin(x1),
       
  6891         cy1 = Math.cos(y1),
       
  6892         sy1 = Math.sin(y1),
       
  6893         cc = mode !== "orthographic" ? sy0 * sy1 + cy0 * cy1 * cx1 : null,
       
  6894         c,
       
  6895         k = mode === "stereographic" ? 1 / (1 + cc)
       
  6896           : mode === "gnomonic" ? 1 / cc
       
  6897           : mode === "equidistant" ? (c = Math.acos(cc), c ? c / Math.sin(c) : 0)
       
  6898           : mode === "equalarea" ? Math.sqrt(2 / (1 + cc))
       
  6899           : 1,
       
  6900         x = k * cy1 * sx1,
       
  6901         y = k * (sy0 * cy1 * cx1 - cy0 * sy1);
       
  6902     return [
       
  6903       scale * x + translate[0],
       
  6904       scale * y + translate[1]
       
  6905     ];
       
  6906   }
       
  6907 
       
  6908   azimuthal.invert = function(coordinates) {
       
  6909     var x = (coordinates[0] - translate[0]) / scale,
       
  6910         y = (coordinates[1] - translate[1]) / scale,
       
  6911         p = Math.sqrt(x * x + y * y),
       
  6912         c = mode === "stereographic" ? 2 * Math.atan(p)
       
  6913           : mode === "gnomonic" ? Math.atan(p)
       
  6914           : mode === "equidistant" ? p
       
  6915           : mode === "equalarea" ? 2 * Math.asin(.5 * p)
       
  6916           : Math.asin(p),
       
  6917         sc = Math.sin(c),
       
  6918         cc = Math.cos(c);
       
  6919     return [
       
  6920       (x0 + Math.atan2(x * sc, p * cy0 * cc + y * sy0 * sc)) / d3_geo_radians,
       
  6921       Math.asin(cc * sy0 - (p ? (y * sc * cy0) / p : 0)) / d3_geo_radians
       
  6922     ];
       
  6923   };
       
  6924 
       
  6925   azimuthal.mode = function(x) {
       
  6926     if (!arguments.length) return mode;
       
  6927     mode = x + "";
       
  6928     return azimuthal;
       
  6929   };
       
  6930 
       
  6931   azimuthal.origin = function(x) {
       
  6932     if (!arguments.length) return origin;
       
  6933     origin = x;
       
  6934     x0 = origin[0] * d3_geo_radians;
       
  6935     y0 = origin[1] * d3_geo_radians;
       
  6936     cy0 = Math.cos(y0);
       
  6937     sy0 = Math.sin(y0);
       
  6938     return azimuthal;
       
  6939   };
       
  6940 
       
  6941   azimuthal.scale = function(x) {
       
  6942     if (!arguments.length) return scale;
       
  6943     scale = +x;
       
  6944     return azimuthal;
       
  6945   };
       
  6946 
       
  6947   azimuthal.translate = function(x) {
       
  6948     if (!arguments.length) return translate;
       
  6949     translate = [+x[0], +x[1]];
       
  6950     return azimuthal;
       
  6951   };
       
  6952 
       
  6953   return azimuthal.origin([0, 0]);
       
  6954 };
       
  6955 // Derived from Tom Carden's Albers implementation for Protovis.
       
  6956 // http://gist.github.com/476238
       
  6957 // http://mathworld.wolfram.com/AlbersEqual-AreaConicProjection.html
       
  6958 
       
  6959 d3.geo.albers = function() {
       
  6960   var origin = [-98, 38],
       
  6961       parallels = [29.5, 45.5],
       
  6962       scale = 1000,
       
  6963       translate = [480, 250],
       
  6964       lng0, // d3_geo_radians * origin[0]
       
  6965       n,
       
  6966       C,
       
  6967       p0;
       
  6968 
       
  6969   function albers(coordinates) {
       
  6970     var t = n * (d3_geo_radians * coordinates[0] - lng0),
       
  6971         p = Math.sqrt(C - 2 * n * Math.sin(d3_geo_radians * coordinates[1])) / n;
       
  6972     return [
       
  6973       scale * p * Math.sin(t) + translate[0],
       
  6974       scale * (p * Math.cos(t) - p0) + translate[1]
       
  6975     ];
       
  6976   }
       
  6977 
       
  6978   albers.invert = function(coordinates) {
       
  6979     var x = (coordinates[0] - translate[0]) / scale,
       
  6980         y = (coordinates[1] - translate[1]) / scale,
       
  6981         p0y = p0 + y,
       
  6982         t = Math.atan2(x, p0y),
       
  6983         p = Math.sqrt(x * x + p0y * p0y);
       
  6984     return [
       
  6985       (lng0 + t / n) / d3_geo_radians,
       
  6986       Math.asin((C - p * p * n * n) / (2 * n)) / d3_geo_radians
       
  6987     ];
       
  6988   };
       
  6989 
       
  6990   function reload() {
       
  6991     var phi1 = d3_geo_radians * parallels[0],
       
  6992         phi2 = d3_geo_radians * parallels[1],
       
  6993         lat0 = d3_geo_radians * origin[1],
       
  6994         s = Math.sin(phi1),
       
  6995         c = Math.cos(phi1);
       
  6996     lng0 = d3_geo_radians * origin[0];
       
  6997     n = .5 * (s + Math.sin(phi2));
       
  6998     C = c * c + 2 * n * s;
       
  6999     p0 = Math.sqrt(C - 2 * n * Math.sin(lat0)) / n;
       
  7000     return albers;
       
  7001   }
       
  7002 
       
  7003   albers.origin = function(x) {
       
  7004     if (!arguments.length) return origin;
       
  7005     origin = [+x[0], +x[1]];
       
  7006     return reload();
       
  7007   };
       
  7008 
       
  7009   albers.parallels = function(x) {
       
  7010     if (!arguments.length) return parallels;
       
  7011     parallels = [+x[0], +x[1]];
       
  7012     return reload();
       
  7013   };
       
  7014 
       
  7015   albers.scale = function(x) {
       
  7016     if (!arguments.length) return scale;
       
  7017     scale = +x;
       
  7018     return albers;
       
  7019   };
       
  7020 
       
  7021   albers.translate = function(x) {
       
  7022     if (!arguments.length) return translate;
       
  7023     translate = [+x[0], +x[1]];
       
  7024     return albers;
       
  7025   };
       
  7026 
       
  7027   return reload();
       
  7028 };
       
  7029 
       
  7030 // A composite projection for the United States, 960x500. The set of standard
       
  7031 // parallels for each region comes from USGS, which is published here:
       
  7032 // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
       
  7033 // TODO allow the composite projection to be rescaled?
       
  7034 d3.geo.albersUsa = function() {
       
  7035   var lower48 = d3.geo.albers();
       
  7036 
       
  7037   var alaska = d3.geo.albers()
       
  7038       .origin([-160, 60])
       
  7039       .parallels([55, 65]);
       
  7040 
       
  7041   var hawaii = d3.geo.albers()
       
  7042       .origin([-160, 20])
       
  7043       .parallels([8, 18]);
       
  7044 
       
  7045   var puertoRico = d3.geo.albers()
       
  7046       .origin([-60, 10])
       
  7047       .parallels([8, 18]);
       
  7048 
       
  7049   function albersUsa(coordinates) {
       
  7050     var lon = coordinates[0],
       
  7051         lat = coordinates[1];
       
  7052     return (lat > 50 ? alaska
       
  7053         : lon < -140 ? hawaii
       
  7054         : lat < 21 ? puertoRico
       
  7055         : lower48)(coordinates);
       
  7056   }
       
  7057 
       
  7058   albersUsa.scale = function(x) {
       
  7059     if (!arguments.length) return lower48.scale();
       
  7060     lower48.scale(x);
       
  7061     alaska.scale(x * .6);
       
  7062     hawaii.scale(x);
       
  7063     puertoRico.scale(x * 1.5);
       
  7064     return albersUsa.translate(lower48.translate());
       
  7065   };
       
  7066 
       
  7067   albersUsa.translate = function(x) {
       
  7068     if (!arguments.length) return lower48.translate();
       
  7069     var dz = lower48.scale() / 1000,
       
  7070         dx = x[0],
       
  7071         dy = x[1];
       
  7072     lower48.translate(x);
       
  7073     alaska.translate([dx - 400 * dz, dy + 170 * dz]);
       
  7074     hawaii.translate([dx - 190 * dz, dy + 200 * dz]);
       
  7075     puertoRico.translate([dx + 580 * dz, dy + 430 * dz]);
       
  7076     return albersUsa;
       
  7077   };
       
  7078 
       
  7079   return albersUsa.scale(lower48.scale());
       
  7080 };
       
  7081 d3.geo.bonne = function() {
       
  7082   var scale = 200,
       
  7083       translate = [480, 250],
       
  7084       x0, // origin longitude in radians
       
  7085       y0, // origin latitude in radians
       
  7086       y1, // parallel latitude in radians
       
  7087       c1; // cot(y1)
       
  7088 
       
  7089   function bonne(coordinates) {
       
  7090     var x = coordinates[0] * d3_geo_radians - x0,
       
  7091         y = coordinates[1] * d3_geo_radians - y0;
       
  7092     if (y1) {
       
  7093       var p = c1 + y1 - y, E = x * Math.cos(y) / p;
       
  7094       x = p * Math.sin(E);
       
  7095       y = p * Math.cos(E) - c1;
       
  7096     } else {
       
  7097       x *= Math.cos(y);
       
  7098       y *= -1;
       
  7099     }
       
  7100     return [
       
  7101       scale * x + translate[0],
       
  7102       scale * y + translate[1]
       
  7103     ];
       
  7104   }
       
  7105 
       
  7106   bonne.invert = function(coordinates) {
       
  7107     var x = (coordinates[0] - translate[0]) / scale,
       
  7108         y = (coordinates[1] - translate[1]) / scale;
       
  7109     if (y1) {
       
  7110       var c = c1 + y, p = Math.sqrt(x * x + c * c);
       
  7111       y = c1 + y1 - p;
       
  7112       x = x0 + p * Math.atan2(x, c) / Math.cos(y);
       
  7113     } else {
       
  7114       y *= -1;
       
  7115       x /= Math.cos(y);
       
  7116     }
       
  7117     return [
       
  7118       x / d3_geo_radians,
       
  7119       y / d3_geo_radians
       
  7120     ];
       
  7121   };
       
  7122 
       
  7123   // 90° for Werner, 0° for Sinusoidal
       
  7124   bonne.parallel = function(x) {
       
  7125     if (!arguments.length) return y1 / d3_geo_radians;
       
  7126     c1 = 1 / Math.tan(y1 = x * d3_geo_radians);
       
  7127     return bonne;
       
  7128   };
       
  7129 
       
  7130   bonne.origin = function(x) {
       
  7131     if (!arguments.length) return [x0 / d3_geo_radians, y0 / d3_geo_radians];
       
  7132     x0 = x[0] * d3_geo_radians;
       
  7133     y0 = x[1] * d3_geo_radians;
       
  7134     return bonne;
       
  7135   };
       
  7136 
       
  7137   bonne.scale = function(x) {
       
  7138     if (!arguments.length) return scale;
       
  7139     scale = +x;
       
  7140     return bonne;
       
  7141   };
       
  7142 
       
  7143   bonne.translate = function(x) {
       
  7144     if (!arguments.length) return translate;
       
  7145     translate = [+x[0], +x[1]];
       
  7146     return bonne;
       
  7147   };
       
  7148 
       
  7149   return bonne.origin([0, 0]).parallel(45);
       
  7150 };
       
  7151 d3.geo.equirectangular = function() {
       
  7152   var scale = 500,
       
  7153       translate = [480, 250];
       
  7154 
       
  7155   function equirectangular(coordinates) {
       
  7156     var x = coordinates[0] / 360,
       
  7157         y = -coordinates[1] / 360;
       
  7158     return [
       
  7159       scale * x + translate[0],
       
  7160       scale * y + translate[1]
       
  7161     ];
       
  7162   }
       
  7163 
       
  7164   equirectangular.invert = function(coordinates) {
       
  7165     var x = (coordinates[0] - translate[0]) / scale,
       
  7166         y = (coordinates[1] - translate[1]) / scale;
       
  7167     return [
       
  7168       360 * x,
       
  7169       -360 * y
       
  7170     ];
       
  7171   };
       
  7172 
       
  7173   equirectangular.scale = function(x) {
       
  7174     if (!arguments.length) return scale;
       
  7175     scale = +x;
       
  7176     return equirectangular;
       
  7177   };
       
  7178 
       
  7179   equirectangular.translate = function(x) {
       
  7180     if (!arguments.length) return translate;
       
  7181     translate = [+x[0], +x[1]];
       
  7182     return equirectangular;
       
  7183   };
       
  7184 
       
  7185   return equirectangular;
       
  7186 };
       
  7187 d3.geo.mercator = function() {
       
  7188   var scale = 500,
       
  7189       translate = [480, 250];
       
  7190 
       
  7191   function mercator(coordinates) {
       
  7192     var x = coordinates[0] / 360,
       
  7193         y = -(Math.log(Math.tan(Math.PI / 4 + coordinates[1] * d3_geo_radians / 2)) / d3_geo_radians) / 360;
       
  7194     return [
       
  7195       scale * x + translate[0],
       
  7196       scale * Math.max(-.5, Math.min(.5, y)) + translate[1]
       
  7197     ];
       
  7198   }
       
  7199 
       
  7200   mercator.invert = function(coordinates) {
       
  7201     var x = (coordinates[0] - translate[0]) / scale,
       
  7202         y = (coordinates[1] - translate[1]) / scale;
       
  7203     return [
       
  7204       360 * x,
       
  7205       2 * Math.atan(Math.exp(-360 * y * d3_geo_radians)) / d3_geo_radians - 90
       
  7206     ];
       
  7207   };
       
  7208 
       
  7209   mercator.scale = function(x) {
       
  7210     if (!arguments.length) return scale;
       
  7211     scale = +x;
       
  7212     return mercator;
       
  7213   };
       
  7214 
       
  7215   mercator.translate = function(x) {
       
  7216     if (!arguments.length) return translate;
       
  7217     translate = [+x[0], +x[1]];
       
  7218     return mercator;
       
  7219   };
       
  7220 
       
  7221   return mercator;
       
  7222 };
       
  7223 function d3_geo_type(types, defaultValue) {
       
  7224   return function(object) {
       
  7225     return object && types.hasOwnProperty(object.type) ? types[object.type](object) : defaultValue;
       
  7226   };
       
  7227 }
       
  7228 /**
       
  7229  * Returns a function that, given a GeoJSON object (e.g., a feature), returns
       
  7230  * the corresponding SVG path. The function can be customized by overriding the
       
  7231  * projection. Point features are mapped to circles with a default radius of
       
  7232  * 4.5px; the radius can be specified either as a constant or a function that
       
  7233  * is evaluated per object.
       
  7234  */
       
  7235 d3.geo.path = function() {
       
  7236   var pointRadius = 4.5,
       
  7237       pointCircle = d3_path_circle(pointRadius),
       
  7238       projection = d3.geo.albersUsa();
       
  7239 
       
  7240   function path(d, i) {
       
  7241     if (typeof pointRadius === "function") {
       
  7242       pointCircle = d3_path_circle(pointRadius.apply(this, arguments));
       
  7243     }
       
  7244     return pathType(d) || null;
       
  7245   }
       
  7246 
       
  7247   function project(coordinates) {
       
  7248     return projection(coordinates).join(",");
       
  7249   }
       
  7250 
       
  7251   var pathType = d3_geo_type({
       
  7252 
       
  7253     FeatureCollection: function(o) {
       
  7254       var path = [],
       
  7255           features = o.features,
       
  7256           i = -1, // features.index
       
  7257           n = features.length;
       
  7258       while (++i < n) path.push(pathType(features[i].geometry));
       
  7259       return path.join("");
       
  7260     },
       
  7261 
       
  7262     Feature: function(o) {
       
  7263       return pathType(o.geometry);
       
  7264     },
       
  7265 
       
  7266     Point: function(o) {
       
  7267       return "M" + project(o.coordinates) + pointCircle;
       
  7268     },
       
  7269 
       
  7270     MultiPoint: function(o) {
       
  7271       var path = [],
       
  7272           coordinates = o.coordinates,
       
  7273           i = -1, // coordinates.index
       
  7274           n = coordinates.length;
       
  7275       while (++i < n) path.push("M", project(coordinates[i]), pointCircle);
       
  7276       return path.join("");
       
  7277     },
       
  7278 
       
  7279     LineString: function(o) {
       
  7280       var path = ["M"],
       
  7281           coordinates = o.coordinates,
       
  7282           i = -1, // coordinates.index
       
  7283           n = coordinates.length;
       
  7284       while (++i < n) path.push(project(coordinates[i]), "L");
       
  7285       path.pop();
       
  7286       return path.join("");
       
  7287     },
       
  7288 
       
  7289     MultiLineString: function(o) {
       
  7290       var path = [],
       
  7291           coordinates = o.coordinates,
       
  7292           i = -1, // coordinates.index
       
  7293           n = coordinates.length,
       
  7294           subcoordinates, // coordinates[i]
       
  7295           j, // subcoordinates.index
       
  7296           m; // subcoordinates.length
       
  7297       while (++i < n) {
       
  7298         subcoordinates = coordinates[i];
       
  7299         j = -1;
       
  7300         m = subcoordinates.length;
       
  7301         path.push("M");
       
  7302         while (++j < m) path.push(project(subcoordinates[j]), "L");
       
  7303         path.pop();
       
  7304       }
       
  7305       return path.join("");
       
  7306     },
       
  7307 
       
  7308     Polygon: function(o) {
       
  7309       var path = [],
       
  7310           coordinates = o.coordinates,
       
  7311           i = -1, // coordinates.index
       
  7312           n = coordinates.length,
       
  7313           subcoordinates, // coordinates[i]
       
  7314           j, // subcoordinates.index
       
  7315           m; // subcoordinates.length
       
  7316       while (++i < n) {
       
  7317         subcoordinates = coordinates[i];
       
  7318         j = -1;
       
  7319         if ((m = subcoordinates.length - 1) > 0) {
       
  7320           path.push("M");
       
  7321           while (++j < m) path.push(project(subcoordinates[j]), "L");
       
  7322           path[path.length - 1] = "Z";
       
  7323         }
       
  7324       }
       
  7325       return path.join("");
       
  7326     },
       
  7327 
       
  7328     MultiPolygon: function(o) {
       
  7329       var path = [],
       
  7330           coordinates = o.coordinates,
       
  7331           i = -1, // coordinates index
       
  7332           n = coordinates.length,
       
  7333           subcoordinates, // coordinates[i]
       
  7334           j, // subcoordinates index
       
  7335           m, // subcoordinates.length
       
  7336           subsubcoordinates, // subcoordinates[j]
       
  7337           k, // subsubcoordinates index
       
  7338           p; // subsubcoordinates.length
       
  7339       while (++i < n) {
       
  7340         subcoordinates = coordinates[i];
       
  7341         j = -1;
       
  7342         m = subcoordinates.length;
       
  7343         while (++j < m) {
       
  7344           subsubcoordinates = subcoordinates[j];
       
  7345           k = -1;
       
  7346           if ((p = subsubcoordinates.length - 1) > 0) {
       
  7347             path.push("M");
       
  7348             while (++k < p) path.push(project(subsubcoordinates[k]), "L");
       
  7349             path[path.length - 1] = "Z";
       
  7350           }
       
  7351         }
       
  7352       }
       
  7353       return path.join("");
       
  7354     },
       
  7355 
       
  7356     GeometryCollection: function(o) {
       
  7357       var path = [],
       
  7358           geometries = o.geometries,
       
  7359           i = -1, // geometries index
       
  7360           n = geometries.length;
       
  7361       while (++i < n) path.push(pathType(geometries[i]));
       
  7362       return path.join("");
       
  7363     }
       
  7364 
       
  7365   });
       
  7366 
       
  7367   var areaType = path.area = d3_geo_type({
       
  7368 
       
  7369     FeatureCollection: function(o) {
       
  7370       var area = 0,
       
  7371           features = o.features,
       
  7372           i = -1, // features.index
       
  7373           n = features.length;
       
  7374       while (++i < n) area += areaType(features[i]);
       
  7375       return area;
       
  7376     },
       
  7377 
       
  7378     Feature: function(o) {
       
  7379       return areaType(o.geometry);
       
  7380     },
       
  7381 
       
  7382     Polygon: function(o) {
       
  7383       return polygonArea(o.coordinates);
       
  7384     },
       
  7385 
       
  7386     MultiPolygon: function(o) {
       
  7387       var sum = 0,
       
  7388           coordinates = o.coordinates,
       
  7389           i = -1, // coordinates index
       
  7390           n = coordinates.length;
       
  7391       while (++i < n) sum += polygonArea(coordinates[i]);
       
  7392       return sum;
       
  7393     },
       
  7394 
       
  7395     GeometryCollection: function(o) {
       
  7396       var sum = 0,
       
  7397           geometries = o.geometries,
       
  7398           i = -1, // geometries index
       
  7399           n = geometries.length;
       
  7400       while (++i < n) sum += areaType(geometries[i]);
       
  7401       return sum;
       
  7402     }
       
  7403 
       
  7404   }, 0);
       
  7405 
       
  7406   function polygonArea(coordinates) {
       
  7407     var sum = area(coordinates[0]), // exterior ring
       
  7408         i = 0, // coordinates.index
       
  7409         n = coordinates.length;
       
  7410     while (++i < n) sum -= area(coordinates[i]); // holes
       
  7411     return sum;
       
  7412   }
       
  7413 
       
  7414   function polygonCentroid(coordinates) {
       
  7415     var polygon = d3.geom.polygon(coordinates[0].map(projection)), // exterior ring
       
  7416         area = polygon.area(),
       
  7417         centroid = polygon.centroid(area < 0 ? (area *= -1, 1) : -1),
       
  7418         x = centroid[0],
       
  7419         y = centroid[1],
       
  7420         z = area,
       
  7421         i = 0, // coordinates index
       
  7422         n = coordinates.length;
       
  7423     while (++i < n) {
       
  7424       polygon = d3.geom.polygon(coordinates[i].map(projection)); // holes
       
  7425       area = polygon.area();
       
  7426       centroid = polygon.centroid(area < 0 ? (area *= -1, 1) : -1);
       
  7427       x -= centroid[0];
       
  7428       y -= centroid[1];
       
  7429       z -= area;
       
  7430     }
       
  7431     return [x, y, 6 * z]; // weighted centroid
       
  7432   }
       
  7433 
       
  7434   var centroidType = path.centroid = d3_geo_type({
       
  7435 
       
  7436     // TODO FeatureCollection
       
  7437     // TODO Point
       
  7438     // TODO MultiPoint
       
  7439     // TODO LineString
       
  7440     // TODO MultiLineString
       
  7441     // TODO GeometryCollection
       
  7442 
       
  7443     Feature: function(o) {
       
  7444       return centroidType(o.geometry);
       
  7445     },
       
  7446 
       
  7447     Polygon: function(o) {
       
  7448       var centroid = polygonCentroid(o.coordinates);
       
  7449       return [centroid[0] / centroid[2], centroid[1] / centroid[2]];
       
  7450     },
       
  7451 
       
  7452     MultiPolygon: function(o) {
       
  7453       var area = 0,
       
  7454           coordinates = o.coordinates,
       
  7455           centroid,
       
  7456           x = 0,
       
  7457           y = 0,
       
  7458           z = 0,
       
  7459           i = -1, // coordinates index
       
  7460           n = coordinates.length;
       
  7461       while (++i < n) {
       
  7462         centroid = polygonCentroid(coordinates[i]);
       
  7463         x += centroid[0];
       
  7464         y += centroid[1];
       
  7465         z += centroid[2];
       
  7466       }
       
  7467       return [x / z, y / z];
       
  7468     }
       
  7469 
       
  7470   });
       
  7471 
       
  7472   function area(coordinates) {
       
  7473     return Math.abs(d3.geom.polygon(coordinates.map(projection)).area());
       
  7474   }
       
  7475 
       
  7476   path.projection = function(x) {
       
  7477     projection = x;
       
  7478     return path;
       
  7479   };
       
  7480 
       
  7481   path.pointRadius = function(x) {
       
  7482     if (typeof x === "function") pointRadius = x;
       
  7483     else {
       
  7484       pointRadius = +x;
       
  7485       pointCircle = d3_path_circle(pointRadius);
       
  7486     }
       
  7487     return path;
       
  7488   };
       
  7489 
       
  7490   return path;
       
  7491 };
       
  7492 
       
  7493 function d3_path_circle(radius) {
       
  7494   return "m0," + radius
       
  7495       + "a" + radius + "," + radius + " 0 1,1 0," + (-2 * radius)
       
  7496       + "a" + radius + "," + radius + " 0 1,1 0," + (+2 * radius)
       
  7497       + "z";
       
  7498 }
       
  7499 /**
       
  7500  * Given a GeoJSON object, returns the corresponding bounding box. The bounding
       
  7501  * box is represented by a two-dimensional array: [[left, bottom], [right,
       
  7502  * top]], where left is the minimum longitude, bottom is the minimum latitude,
       
  7503  * right is maximum longitude, and top is the maximum latitude.
       
  7504  */
       
  7505 d3.geo.bounds = function(feature) {
       
  7506   var left = Infinity,
       
  7507       bottom = Infinity,
       
  7508       right = -Infinity,
       
  7509       top = -Infinity;
       
  7510   d3_geo_bounds(feature, function(x, y) {
       
  7511     if (x < left) left = x;
       
  7512     if (x > right) right = x;
       
  7513     if (y < bottom) bottom = y;
       
  7514     if (y > top) top = y;
       
  7515   });
       
  7516   return [[left, bottom], [right, top]];
       
  7517 };
       
  7518 
       
  7519 function d3_geo_bounds(o, f) {
       
  7520   if (d3_geo_boundsTypes.hasOwnProperty(o.type)) d3_geo_boundsTypes[o.type](o, f);
       
  7521 }
       
  7522 
       
  7523 var d3_geo_boundsTypes = {
       
  7524   Feature: d3_geo_boundsFeature,
       
  7525   FeatureCollection: d3_geo_boundsFeatureCollection,
       
  7526   GeometryCollection: d3_geo_boundsGeometryCollection,
       
  7527   LineString: d3_geo_boundsLineString,
       
  7528   MultiLineString: d3_geo_boundsMultiLineString,
       
  7529   MultiPoint: d3_geo_boundsLineString,
       
  7530   MultiPolygon: d3_geo_boundsMultiPolygon,
       
  7531   Point: d3_geo_boundsPoint,
       
  7532   Polygon: d3_geo_boundsPolygon
       
  7533 };
       
  7534 
       
  7535 function d3_geo_boundsFeature(o, f) {
       
  7536   d3_geo_bounds(o.geometry, f);
       
  7537 }
       
  7538 
       
  7539 function d3_geo_boundsFeatureCollection(o, f) {
       
  7540   for (var a = o.features, i = 0, n = a.length; i < n; i++) {
       
  7541     d3_geo_bounds(a[i].geometry, f);
       
  7542   }
       
  7543 }
       
  7544 
       
  7545 function d3_geo_boundsGeometryCollection(o, f) {
       
  7546   for (var a = o.geometries, i = 0, n = a.length; i < n; i++) {
       
  7547     d3_geo_bounds(a[i], f);
       
  7548   }
       
  7549 }
       
  7550 
       
  7551 function d3_geo_boundsLineString(o, f) {
       
  7552   for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
       
  7553     f.apply(null, a[i]);
       
  7554   }
       
  7555 }
       
  7556 
       
  7557 function d3_geo_boundsMultiLineString(o, f) {
       
  7558   for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
       
  7559     for (var b = a[i], j = 0, m = b.length; j < m; j++) {
       
  7560       f.apply(null, b[j]);
       
  7561     }
       
  7562   }
       
  7563 }
       
  7564 
       
  7565 function d3_geo_boundsMultiPolygon(o, f) {
       
  7566   for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
       
  7567     for (var b = a[i][0], j = 0, m = b.length; j < m; j++) {
       
  7568       f.apply(null, b[j]);
       
  7569     }
       
  7570   }
       
  7571 }
       
  7572 
       
  7573 function d3_geo_boundsPoint(o, f) {
       
  7574   f.apply(null, o.coordinates);
       
  7575 }
       
  7576 
       
  7577 function d3_geo_boundsPolygon(o, f) {
       
  7578   for (var a = o.coordinates[0], i = 0, n = a.length; i < n; i++) {
       
  7579     f.apply(null, a[i]);
       
  7580   }
       
  7581 }
       
  7582 // TODO breakAtDateLine?
       
  7583 
       
  7584 d3.geo.circle = function() {
       
  7585   var origin = [0, 0],
       
  7586       degrees = 90 - 1e-2,
       
  7587       radians = degrees * d3_geo_radians,
       
  7588       arc = d3.geo.greatArc().target(Object);
       
  7589 
       
  7590   function circle() {
       
  7591     // TODO render a circle as a Polygon
       
  7592   }
       
  7593 
       
  7594   function visible(point) {
       
  7595     return arc.distance(point) < radians;
       
  7596   }
       
  7597 
       
  7598   circle.clip = function(d) {
       
  7599     arc.source(typeof origin === "function" ? origin.apply(this, arguments) : origin);
       
  7600     return clipType(d);
       
  7601   };
       
  7602 
       
  7603   var clipType = d3_geo_type({
       
  7604 
       
  7605     FeatureCollection: function(o) {
       
  7606       var features = o.features.map(clipType).filter(Object);
       
  7607       return features && (o = Object.create(o), o.features = features, o);
       
  7608     },
       
  7609 
       
  7610     Feature: function(o) {
       
  7611       var geometry = clipType(o.geometry);
       
  7612       return geometry && (o = Object.create(o), o.geometry = geometry, o);
       
  7613     },
       
  7614 
       
  7615     Point: function(o) {
       
  7616       return visible(o.coordinates) && o;
       
  7617     },
       
  7618 
       
  7619     MultiPoint: function(o) {
       
  7620       var coordinates = o.coordinates.filter(visible);
       
  7621       return coordinates.length && {
       
  7622         type: o.type,
       
  7623         coordinates: coordinates
       
  7624       };
       
  7625     },
       
  7626 
       
  7627     LineString: function(o) {
       
  7628       var coordinates = clip(o.coordinates);
       
  7629       return coordinates.length && (o = Object.create(o), o.coordinates = coordinates, o);
       
  7630     },
       
  7631 
       
  7632     MultiLineString: function(o) {
       
  7633       var coordinates = o.coordinates.map(clip).filter(function(d) { return d.length; });
       
  7634       return coordinates.length && (o = Object.create(o), o.coordinates = coordinates, o);
       
  7635     },
       
  7636 
       
  7637     Polygon: function(o) {
       
  7638       var coordinates = o.coordinates.map(clip);
       
  7639       return coordinates[0].length && (o = Object.create(o), o.coordinates = coordinates, o);
       
  7640     },
       
  7641 
       
  7642     MultiPolygon: function(o) {
       
  7643       var coordinates = o.coordinates.map(function(d) { return d.map(clip); }).filter(function(d) { return d[0].length; });
       
  7644       return coordinates.length && (o = Object.create(o), o.coordinates = coordinates, o);
       
  7645     },
       
  7646 
       
  7647     GeometryCollection: function(o) {
       
  7648       var geometries = o.geometries.map(clipType).filter(Object);
       
  7649       return geometries.length && (o = Object.create(o), o.geometries = geometries, o);
       
  7650     }
       
  7651 
       
  7652   });
       
  7653 
       
  7654   function clip(coordinates) {
       
  7655     var i = -1,
       
  7656         n = coordinates.length,
       
  7657         clipped = [],
       
  7658         p0,
       
  7659         p1,
       
  7660         p2,
       
  7661         d0,
       
  7662         d1;
       
  7663 
       
  7664     while (++i < n) {
       
  7665       d1 = arc.distance(p2 = coordinates[i]);
       
  7666       if (d1 < radians) {
       
  7667         if (p1) clipped.push(d3_geo_greatArcInterpolate(p1, p2)((d0 - radians) / (d0 - d1)));
       
  7668         clipped.push(p2);
       
  7669         p0 = p1 = null;
       
  7670       } else {
       
  7671         p1 = p2;
       
  7672         if (!p0 && clipped.length) {
       
  7673           clipped.push(d3_geo_greatArcInterpolate(clipped[clipped.length - 1], p1)((radians - d0) / (d1 - d0)));
       
  7674           p0 = p1;
       
  7675         }
       
  7676       }
       
  7677       d0 = d1;
       
  7678     }
       
  7679 
       
  7680     if (p1 && clipped.length) {
       
  7681       d1 = arc.distance(p2 = clipped[0]);
       
  7682       clipped.push(d3_geo_greatArcInterpolate(p1, p2)((d0 - radians) / (d0 - d1)));
       
  7683     }
       
  7684 
       
  7685     return resample(clipped);
       
  7686   }
       
  7687 
       
  7688   // Resample coordinates, creating great arcs between each.
       
  7689   function resample(coordinates) {
       
  7690     var i = 0,
       
  7691         n = coordinates.length,
       
  7692         j,
       
  7693         m,
       
  7694         resampled = n ? [coordinates[0]] : coordinates,
       
  7695         resamples,
       
  7696         origin = arc.source();
       
  7697 
       
  7698     while (++i < n) {
       
  7699       resamples = arc.source(coordinates[i - 1])(coordinates[i]).coordinates;
       
  7700       for (j = 0, m = resamples.length; ++j < m;) resampled.push(resamples[j]);
       
  7701     }
       
  7702 
       
  7703     arc.source(origin);
       
  7704     return resampled;
       
  7705   }
       
  7706 
       
  7707   circle.origin = function(x) {
       
  7708     if (!arguments.length) return origin;
       
  7709     origin = x;
       
  7710     return circle;
       
  7711   };
       
  7712 
       
  7713   circle.angle = function(x) {
       
  7714     if (!arguments.length) return degrees;
       
  7715     radians = (degrees = +x) * d3_geo_radians;
       
  7716     return circle;
       
  7717   };
       
  7718 
       
  7719   // Precision is specified in degrees.
       
  7720   circle.precision = function(x) {
       
  7721     if (!arguments.length) return arc.precision();
       
  7722     arc.precision(x);
       
  7723     return circle;
       
  7724   };
       
  7725 
       
  7726   return circle;
       
  7727 }
       
  7728 d3.geo.greatArc = function() {
       
  7729   var source = d3_geo_greatArcSource,
       
  7730       target = d3_geo_greatArcTarget,
       
  7731       precision = 6 * d3_geo_radians;
       
  7732 
       
  7733   function greatArc() {
       
  7734     var a = typeof source === "function" ? source.apply(this, arguments) : source,
       
  7735         b = typeof target === "function" ? target.apply(this, arguments) : target,
       
  7736         i = d3_geo_greatArcInterpolate(a, b),
       
  7737         dt = precision / i.d,
       
  7738         t = 0,
       
  7739         coordinates = [a];
       
  7740     while ((t += dt) < 1) coordinates.push(i(t));
       
  7741     coordinates.push(b);
       
  7742     return {
       
  7743       type: "LineString",
       
  7744       coordinates: coordinates
       
  7745     };
       
  7746   }
       
  7747 
       
  7748   // Length returned in radians; multiply by radius for distance.
       
  7749   greatArc.distance = function() {
       
  7750     var a = typeof source === "function" ? source.apply(this, arguments) : source,
       
  7751         b = typeof target === "function" ? target.apply(this, arguments) : target;
       
  7752      return d3_geo_greatArcInterpolate(a, b).d;
       
  7753   };
       
  7754 
       
  7755   greatArc.source = function(x) {
       
  7756     if (!arguments.length) return source;
       
  7757     source = x;
       
  7758     return greatArc;
       
  7759   };
       
  7760 
       
  7761   greatArc.target = function(x) {
       
  7762     if (!arguments.length) return target;
       
  7763     target = x;
       
  7764     return greatArc;
       
  7765   };
       
  7766 
       
  7767   // Precision is specified in degrees.
       
  7768   greatArc.precision = function(x) {
       
  7769     if (!arguments.length) return precision / d3_geo_radians;
       
  7770     precision = x * d3_geo_radians;
       
  7771     return greatArc;
       
  7772   };
       
  7773 
       
  7774   return greatArc;
       
  7775 };
       
  7776 
       
  7777 function d3_geo_greatArcSource(d) {
       
  7778   return d.source;
       
  7779 }
       
  7780 
       
  7781 function d3_geo_greatArcTarget(d) {
       
  7782   return d.target;
       
  7783 }
       
  7784 
       
  7785 function d3_geo_greatArcInterpolate(a, b) {
       
  7786   var x0 = a[0] * d3_geo_radians, cx0 = Math.cos(x0), sx0 = Math.sin(x0),
       
  7787       y0 = a[1] * d3_geo_radians, cy0 = Math.cos(y0), sy0 = Math.sin(y0),
       
  7788       x1 = b[0] * d3_geo_radians, cx1 = Math.cos(x1), sx1 = Math.sin(x1),
       
  7789       y1 = b[1] * d3_geo_radians, cy1 = Math.cos(y1), sy1 = Math.sin(y1),
       
  7790       d = interpolate.d = Math.acos(Math.max(-1, Math.min(1, sy0 * sy1 + cy0 * cy1 * Math.cos(x1 - x0)))),
       
  7791       sd = Math.sin(d);
       
  7792 
       
  7793   // From http://williams.best.vwh.net/avform.htm#Intermediate
       
  7794   function interpolate(t) {
       
  7795     var A = Math.sin(d - (t *= d)) / sd,
       
  7796         B = Math.sin(t) / sd,
       
  7797         x = A * cy0 * cx0 + B * cy1 * cx1,
       
  7798         y = A * cy0 * sx0 + B * cy1 * sx1,
       
  7799         z = A * sy0       + B * sy1;
       
  7800     return [
       
  7801       Math.atan2(y, x) / d3_geo_radians,
       
  7802       Math.atan2(z, Math.sqrt(x * x + y * y)) / d3_geo_radians
       
  7803     ];
       
  7804   }
       
  7805 
       
  7806   return interpolate;
       
  7807 }
       
  7808 d3.geo.greatCircle = d3.geo.circle;
       
  7809 d3.geom = {};
       
  7810 /**
       
  7811  * Computes a contour for a given input grid function using the <a
       
  7812  * href="http://en.wikipedia.org/wiki/Marching_squares">marching
       
  7813  * squares</a> algorithm. Returns the contour polygon as an array of points.
       
  7814  *
       
  7815  * @param grid a two-input function(x, y) that returns true for values
       
  7816  * inside the contour and false for values outside the contour.
       
  7817  * @param start an optional starting point [x, y] on the grid.
       
  7818  * @returns polygon [[x1, y1], [x2, y2], …]
       
  7819  */
       
  7820 d3.geom.contour = function(grid, start) {
       
  7821   var s = start || d3_geom_contourStart(grid), // starting point
       
  7822       c = [],    // contour polygon
       
  7823       x = s[0],  // current x position
       
  7824       y = s[1],  // current y position
       
  7825       dx = 0,    // next x direction
       
  7826       dy = 0,    // next y direction
       
  7827       pdx = NaN, // previous x direction
       
  7828       pdy = NaN, // previous y direction
       
  7829       i = 0;
       
  7830 
       
  7831   do {
       
  7832     // determine marching squares index
       
  7833     i = 0;
       
  7834     if (grid(x-1, y-1)) i += 1;
       
  7835     if (grid(x,   y-1)) i += 2;
       
  7836     if (grid(x-1, y  )) i += 4;
       
  7837     if (grid(x,   y  )) i += 8;
       
  7838 
       
  7839     // determine next direction
       
  7840     if (i === 6) {
       
  7841       dx = pdy === -1 ? -1 : 1;
       
  7842       dy = 0;
       
  7843     } else if (i === 9) {
       
  7844       dx = 0;
       
  7845       dy = pdx === 1 ? -1 : 1;
       
  7846     } else {
       
  7847       dx = d3_geom_contourDx[i];
       
  7848       dy = d3_geom_contourDy[i];
       
  7849     }
       
  7850 
       
  7851     // update contour polygon
       
  7852     if (dx != pdx && dy != pdy) {
       
  7853       c.push([x, y]);
       
  7854       pdx = dx;
       
  7855       pdy = dy;
       
  7856     }
       
  7857 
       
  7858     x += dx;
       
  7859     y += dy;
       
  7860   } while (s[0] != x || s[1] != y);
       
  7861 
       
  7862   return c;
       
  7863 };
       
  7864 
       
  7865 // lookup tables for marching directions
       
  7866 var d3_geom_contourDx = [1, 0, 1, 1,-1, 0,-1, 1,0, 0,0,0,-1, 0,-1,NaN],
       
  7867     d3_geom_contourDy = [0,-1, 0, 0, 0,-1, 0, 0,1,-1,1,1, 0,-1, 0,NaN];
       
  7868 
       
  7869 function d3_geom_contourStart(grid) {
       
  7870   var x = 0,
       
  7871       y = 0;
       
  7872 
       
  7873   // search for a starting point; begin at origin
       
  7874   // and proceed along outward-expanding diagonals
       
  7875   while (true) {
       
  7876     if (grid(x,y)) {
       
  7877       return [x,y];
       
  7878     }
       
  7879     if (x === 0) {
       
  7880       x = y + 1;
       
  7881       y = 0;
       
  7882     } else {
       
  7883       x = x - 1;
       
  7884       y = y + 1;
       
  7885     }
       
  7886   }
       
  7887 }
       
  7888 /**
       
  7889  * Computes the 2D convex hull of a set of points using Graham's scanning
       
  7890  * algorithm. The algorithm has been implemented as described in Cormen,
       
  7891  * Leiserson, and Rivest's Introduction to Algorithms. The running time of
       
  7892  * this algorithm is O(n log n), where n is the number of input points.
       
  7893  *
       
  7894  * @param vertices [[x1, y1], [x2, y2], …]
       
  7895  * @returns polygon [[x1, y1], [x2, y2], …]
       
  7896  */
       
  7897 d3.geom.hull = function(vertices) {
       
  7898   if (vertices.length < 3) return [];
       
  7899 
       
  7900   var len = vertices.length,
       
  7901       plen = len - 1,
       
  7902       points = [],
       
  7903       stack = [],
       
  7904       i, j, h = 0, x1, y1, x2, y2, u, v, a, sp;
       
  7905 
       
  7906   // find the starting ref point: leftmost point with the minimum y coord
       
  7907   for (i=1; i<len; ++i) {
       
  7908     if (vertices[i][1] < vertices[h][1]) {
       
  7909       h = i;
       
  7910     } else if (vertices[i][1] == vertices[h][1]) {
       
  7911       h = (vertices[i][0] < vertices[h][0] ? i : h);
       
  7912     }
       
  7913   }
       
  7914 
       
  7915   // calculate polar angles from ref point and sort
       
  7916   for (i=0; i<len; ++i) {
       
  7917     if (i === h) continue;
       
  7918     y1 = vertices[i][1] - vertices[h][1];
       
  7919     x1 = vertices[i][0] - vertices[h][0];
       
  7920     points.push({angle: Math.atan2(y1, x1), index: i});
       
  7921   }
       
  7922   points.sort(function(a, b) { return a.angle - b.angle; });
       
  7923 
       
  7924   // toss out duplicate angles
       
  7925   a = points[0].angle;
       
  7926   v = points[0].index;
       
  7927   u = 0;
       
  7928   for (i=1; i<plen; ++i) {
       
  7929     j = points[i].index;
       
  7930     if (a == points[i].angle) {
       
  7931       // keep angle for point most distant from the reference
       
  7932       x1 = vertices[v][0] - vertices[h][0];
       
  7933       y1 = vertices[v][1] - vertices[h][1];
       
  7934       x2 = vertices[j][0] - vertices[h][0];
       
  7935       y2 = vertices[j][1] - vertices[h][1];
       
  7936       if ((x1*x1 + y1*y1) >= (x2*x2 + y2*y2)) {
       
  7937         points[i].index = -1;
       
  7938       } else {
       
  7939         points[u].index = -1;
       
  7940         a = points[i].angle;
       
  7941         u = i;
       
  7942         v = j;
       
  7943       }
       
  7944     } else {
       
  7945       a = points[i].angle;
       
  7946       u = i;
       
  7947       v = j;
       
  7948     }
       
  7949   }
       
  7950 
       
  7951   // initialize the stack
       
  7952   stack.push(h);
       
  7953   for (i=0, j=0; i<2; ++j) {
       
  7954     if (points[j].index !== -1) {
       
  7955       stack.push(points[j].index);
       
  7956       i++;
       
  7957     }
       
  7958   }
       
  7959   sp = stack.length;
       
  7960 
       
  7961   // do graham's scan
       
  7962   for (; j<plen; ++j) {
       
  7963     if (points[j].index === -1) continue; // skip tossed out points
       
  7964     while (!d3_geom_hullCCW(stack[sp-2], stack[sp-1], points[j].index, vertices)) {
       
  7965       --sp;
       
  7966     }
       
  7967     stack[sp++] = points[j].index;
       
  7968   }
       
  7969 
       
  7970   // construct the hull
       
  7971   var poly = [];
       
  7972   for (i=0; i<sp; ++i) {
       
  7973     poly.push(vertices[stack[i]]);
       
  7974   }
       
  7975   return poly;
       
  7976 }
       
  7977 
       
  7978 // are three points in counter-clockwise order?
       
  7979 function d3_geom_hullCCW(i1, i2, i3, v) {
       
  7980   var t, a, b, c, d, e, f;
       
  7981   t = v[i1]; a = t[0]; b = t[1];
       
  7982   t = v[i2]; c = t[0]; d = t[1];
       
  7983   t = v[i3]; e = t[0]; f = t[1];
       
  7984   return ((f-b)*(c-a) - (d-b)*(e-a)) > 0;
       
  7985 }
       
  7986 // Note: requires coordinates to be counterclockwise and convex!
       
  7987 d3.geom.polygon = function(coordinates) {
       
  7988 
       
  7989   coordinates.area = function() {
       
  7990     var i = 0,
       
  7991         n = coordinates.length,
       
  7992         a = coordinates[n - 1][0] * coordinates[0][1],
       
  7993         b = coordinates[n - 1][1] * coordinates[0][0];
       
  7994     while (++i < n) {
       
  7995       a += coordinates[i - 1][0] * coordinates[i][1];
       
  7996       b += coordinates[i - 1][1] * coordinates[i][0];
       
  7997     }
       
  7998     return (b - a) * .5;
       
  7999   };
       
  8000 
       
  8001   coordinates.centroid = function(k) {
       
  8002     var i = -1,
       
  8003         n = coordinates.length,
       
  8004         x = 0,
       
  8005         y = 0,
       
  8006         a,
       
  8007         b = coordinates[n - 1],
       
  8008         c;
       
  8009     if (!arguments.length) k = -1 / (6 * coordinates.area());
       
  8010     while (++i < n) {
       
  8011       a = b;
       
  8012       b = coordinates[i];
       
  8013       c = a[0] * b[1] - b[0] * a[1];
       
  8014       x += (a[0] + b[0]) * c;
       
  8015       y += (a[1] + b[1]) * c;
       
  8016     }
       
  8017     return [x * k, y * k];
       
  8018   };
       
  8019 
       
  8020   // The Sutherland-Hodgman clipping algorithm.
       
  8021   coordinates.clip = function(subject) {
       
  8022     var input,
       
  8023         i = -1,
       
  8024         n = coordinates.length,
       
  8025         j,
       
  8026         m,
       
  8027         a = coordinates[n - 1],
       
  8028         b,
       
  8029         c,
       
  8030         d;
       
  8031     while (++i < n) {
       
  8032       input = subject.slice();
       
  8033       subject.length = 0;
       
  8034       b = coordinates[i];
       
  8035       c = input[(m = input.length) - 1];
       
  8036       j = -1;
       
  8037       while (++j < m) {
       
  8038         d = input[j];
       
  8039         if (d3_geom_polygonInside(d, a, b)) {
       
  8040           if (!d3_geom_polygonInside(c, a, b)) {
       
  8041             subject.push(d3_geom_polygonIntersect(c, d, a, b));
       
  8042           }
       
  8043           subject.push(d);
       
  8044         } else if (d3_geom_polygonInside(c, a, b)) {
       
  8045           subject.push(d3_geom_polygonIntersect(c, d, a, b));
       
  8046         }
       
  8047         c = d;
       
  8048       }
       
  8049       a = b;
       
  8050     }
       
  8051     return subject;
       
  8052   };
       
  8053 
       
  8054   return coordinates;
       
  8055 };
       
  8056 
       
  8057 function d3_geom_polygonInside(p, a, b) {
       
  8058   return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]);
       
  8059 }
       
  8060 
       
  8061 // Intersect two infinite lines cd and ab.
       
  8062 function d3_geom_polygonIntersect(c, d, a, b) {
       
  8063   var x1 = c[0], x2 = d[0], x3 = a[0], x4 = b[0],
       
  8064       y1 = c[1], y2 = d[1], y3 = a[1], y4 = b[1],
       
  8065       x13 = x1 - x3,
       
  8066       x21 = x2 - x1,
       
  8067       x43 = x4 - x3,
       
  8068       y13 = y1 - y3,
       
  8069       y21 = y2 - y1,
       
  8070       y43 = y4 - y3,
       
  8071       ua = (x43 * y13 - y43 * x13) / (y43 * x21 - x43 * y21);
       
  8072   return [x1 + ua * x21, y1 + ua * y21];
       
  8073 }
       
  8074 // Adapted from Nicolas Garcia Belmonte's JIT implementation:
       
  8075 // http://blog.thejit.org/2010/02/12/voronoi-tessellation/
       
  8076 // http://blog.thejit.org/assets/voronoijs/voronoi.js
       
  8077 // See lib/jit/LICENSE for details.
       
  8078 
       
  8079 // Notes:
       
  8080 //
       
  8081 // This implementation does not clip the returned polygons, so if you want to
       
  8082 // clip them to a particular shape you will need to do that either in SVG or by
       
  8083 // post-processing with d3.geom.polygon's clip method.
       
  8084 //
       
  8085 // If any vertices are coincident or have NaN positions, the behavior of this
       
  8086 // method is undefined. Most likely invalid polygons will be returned. You
       
  8087 // should filter invalid points, and consolidate coincident points, before
       
  8088 // computing the tessellation.
       
  8089 
       
  8090 /**
       
  8091  * @param vertices [[x1, y1], [x2, y2], …]
       
  8092  * @returns polygons [[[x1, y1], [x2, y2], …], …]
       
  8093  */
       
  8094 d3.geom.voronoi = function(vertices) {
       
  8095   var polygons = vertices.map(function() { return []; });
       
  8096 
       
  8097   d3_voronoi_tessellate(vertices, function(e) {
       
  8098     var s1,
       
  8099         s2,
       
  8100         x1,
       
  8101         x2,
       
  8102         y1,
       
  8103         y2;
       
  8104     if (e.a === 1 && e.b >= 0) {
       
  8105       s1 = e.ep.r;
       
  8106       s2 = e.ep.l;
       
  8107     } else {
       
  8108       s1 = e.ep.l;
       
  8109       s2 = e.ep.r;
       
  8110     }
       
  8111     if (e.a === 1) {
       
  8112       y1 = s1 ? s1.y : -1e6;
       
  8113       x1 = e.c - e.b * y1;
       
  8114       y2 = s2 ? s2.y : 1e6;
       
  8115       x2 = e.c - e.b * y2;
       
  8116     } else {
       
  8117       x1 = s1 ? s1.x : -1e6;
       
  8118       y1 = e.c - e.a * x1;
       
  8119       x2 = s2 ? s2.x : 1e6;
       
  8120       y2 = e.c - e.a * x2;
       
  8121     }
       
  8122     var v1 = [x1, y1],
       
  8123         v2 = [x2, y2];
       
  8124     polygons[e.region.l.index].push(v1, v2);
       
  8125     polygons[e.region.r.index].push(v1, v2);
       
  8126   });
       
  8127 
       
  8128   // Reconnect the polygon segments into counterclockwise loops.
       
  8129   return polygons.map(function(polygon, i) {
       
  8130     var cx = vertices[i][0],
       
  8131         cy = vertices[i][1];
       
  8132     polygon.forEach(function(v) {
       
  8133       v.angle = Math.atan2(v[0] - cx, v[1] - cy);
       
  8134     });
       
  8135     return polygon.sort(function(a, b) {
       
  8136       return a.angle - b.angle;
       
  8137     }).filter(function(d, i) {
       
  8138       return !i || (d.angle - polygon[i - 1].angle > 1e-10);
       
  8139     });
       
  8140   });
       
  8141 };
       
  8142 
       
  8143 var d3_voronoi_opposite = {"l": "r", "r": "l"};
       
  8144 
       
  8145 function d3_voronoi_tessellate(vertices, callback) {
       
  8146 
       
  8147   var Sites = {
       
  8148     list: vertices
       
  8149       .map(function(v, i) {
       
  8150         return {
       
  8151           index: i,
       
  8152           x: v[0],
       
  8153           y: v[1]
       
  8154         };
       
  8155       })
       
  8156       .sort(function(a, b) {
       
  8157         return a.y < b.y ? -1
       
  8158           : a.y > b.y ? 1
       
  8159           : a.x < b.x ? -1
       
  8160           : a.x > b.x ? 1
       
  8161           : 0;
       
  8162       }),
       
  8163     bottomSite: null
       
  8164   };
       
  8165 
       
  8166   var EdgeList = {
       
  8167     list: [],
       
  8168     leftEnd: null,
       
  8169     rightEnd: null,
       
  8170 
       
  8171     init: function() {
       
  8172       EdgeList.leftEnd = EdgeList.createHalfEdge(null, "l");
       
  8173       EdgeList.rightEnd = EdgeList.createHalfEdge(null, "l");
       
  8174       EdgeList.leftEnd.r = EdgeList.rightEnd;
       
  8175       EdgeList.rightEnd.l = EdgeList.leftEnd;
       
  8176       EdgeList.list.unshift(EdgeList.leftEnd, EdgeList.rightEnd);
       
  8177     },
       
  8178 
       
  8179     createHalfEdge: function(edge, side) {
       
  8180       return {
       
  8181         edge: edge,
       
  8182         side: side,
       
  8183         vertex: null,
       
  8184         "l": null,
       
  8185         "r": null
       
  8186       };
       
  8187     },
       
  8188 
       
  8189     insert: function(lb, he) {
       
  8190       he.l = lb;
       
  8191       he.r = lb.r;
       
  8192       lb.r.l = he;
       
  8193       lb.r = he;
       
  8194     },
       
  8195 
       
  8196     leftBound: function(p) {
       
  8197       var he = EdgeList.leftEnd;
       
  8198       do {
       
  8199         he = he.r;
       
  8200       } while (he != EdgeList.rightEnd && Geom.rightOf(he, p));
       
  8201       he = he.l;
       
  8202       return he;
       
  8203     },
       
  8204 
       
  8205     del: function(he) {
       
  8206       he.l.r = he.r;
       
  8207       he.r.l = he.l;
       
  8208       he.edge = null;
       
  8209     },
       
  8210 
       
  8211     right: function(he) {
       
  8212       return he.r;
       
  8213     },
       
  8214 
       
  8215     left: function(he) {
       
  8216       return he.l;
       
  8217     },
       
  8218 
       
  8219     leftRegion: function(he) {
       
  8220       return he.edge == null
       
  8221           ? Sites.bottomSite
       
  8222           : he.edge.region[he.side];
       
  8223     },
       
  8224 
       
  8225     rightRegion: function(he) {
       
  8226       return he.edge == null
       
  8227           ? Sites.bottomSite
       
  8228           : he.edge.region[d3_voronoi_opposite[he.side]];
       
  8229     }
       
  8230   };
       
  8231 
       
  8232   var Geom = {
       
  8233 
       
  8234     bisect: function(s1, s2) {
       
  8235       var newEdge = {
       
  8236         region: {"l": s1, "r": s2},
       
  8237         ep: {"l": null, "r": null}
       
  8238       };
       
  8239 
       
  8240       var dx = s2.x - s1.x,
       
  8241           dy = s2.y - s1.y,
       
  8242           adx = dx > 0 ? dx : -dx,
       
  8243           ady = dy > 0 ? dy : -dy;
       
  8244 
       
  8245       newEdge.c = s1.x * dx + s1.y * dy
       
  8246           + (dx * dx + dy * dy) * .5;
       
  8247 
       
  8248       if (adx > ady) {
       
  8249         newEdge.a = 1;
       
  8250         newEdge.b = dy / dx;
       
  8251         newEdge.c /= dx;
       
  8252       } else {
       
  8253         newEdge.b = 1;
       
  8254         newEdge.a = dx / dy;
       
  8255         newEdge.c /= dy;
       
  8256       }
       
  8257 
       
  8258       return newEdge;
       
  8259     },
       
  8260 
       
  8261     intersect: function(el1, el2) {
       
  8262       var e1 = el1.edge,
       
  8263           e2 = el2.edge;
       
  8264       if (!e1 || !e2 || (e1.region.r == e2.region.r)) {
       
  8265         return null;
       
  8266       }
       
  8267       var d = (e1.a * e2.b) - (e1.b * e2.a);
       
  8268       if (Math.abs(d) < 1e-10) {
       
  8269         return null;
       
  8270       }
       
  8271       var xint = (e1.c * e2.b - e2.c * e1.b) / d,
       
  8272           yint = (e2.c * e1.a - e1.c * e2.a) / d,
       
  8273           e1r = e1.region.r,
       
  8274           e2r = e2.region.r,
       
  8275           el,
       
  8276           e;
       
  8277       if ((e1r.y < e2r.y) ||
       
  8278          (e1r.y == e2r.y && e1r.x < e2r.x)) {
       
  8279         el = el1;
       
  8280         e = e1;
       
  8281       } else {
       
  8282         el = el2;
       
  8283         e = e2;
       
  8284       }
       
  8285       var rightOfSite = (xint >= e.region.r.x);
       
  8286       if ((rightOfSite && (el.side === "l")) ||
       
  8287         (!rightOfSite && (el.side === "r"))) {
       
  8288         return null;
       
  8289       }
       
  8290       return {
       
  8291         x: xint,
       
  8292         y: yint
       
  8293       };
       
  8294     },
       
  8295 
       
  8296     rightOf: function(he, p) {
       
  8297       var e = he.edge,
       
  8298           topsite = e.region.r,
       
  8299           rightOfSite = (p.x > topsite.x);
       
  8300 
       
  8301       if (rightOfSite && (he.side === "l")) {
       
  8302         return 1;
       
  8303       }
       
  8304       if (!rightOfSite && (he.side === "r")) {
       
  8305         return 0;
       
  8306       }
       
  8307       if (e.a === 1) {
       
  8308         var dyp = p.y - topsite.y,
       
  8309             dxp = p.x - topsite.x,
       
  8310             fast = 0,
       
  8311             above = 0;
       
  8312 
       
  8313         if ((!rightOfSite && (e.b < 0)) ||
       
  8314           (rightOfSite && (e.b >= 0))) {
       
  8315           above = fast = (dyp >= e.b * dxp);
       
  8316         } else {
       
  8317           above = ((p.x + p.y * e.b) > e.c);
       
  8318           if (e.b < 0) {
       
  8319             above = !above;
       
  8320           }
       
  8321           if (!above) {
       
  8322             fast = 1;
       
  8323           }
       
  8324         }
       
  8325         if (!fast) {
       
  8326           var dxs = topsite.x - e.region.l.x;
       
  8327           above = (e.b * (dxp * dxp - dyp * dyp)) <
       
  8328             (dxs * dyp * (1 + 2 * dxp / dxs + e.b * e.b));
       
  8329 
       
  8330           if (e.b < 0) {
       
  8331             above = !above;
       
  8332           }
       
  8333         }
       
  8334       } else /* e.b == 1 */ {
       
  8335         var yl = e.c - e.a * p.x,
       
  8336             t1 = p.y - yl,
       
  8337             t2 = p.x - topsite.x,
       
  8338             t3 = yl - topsite.y;
       
  8339 
       
  8340         above = (t1 * t1) > (t2 * t2 + t3 * t3);
       
  8341       }
       
  8342       return he.side === "l" ? above : !above;
       
  8343     },
       
  8344 
       
  8345     endPoint: function(edge, side, site) {
       
  8346       edge.ep[side] = site;
       
  8347       if (!edge.ep[d3_voronoi_opposite[side]]) return;
       
  8348       callback(edge);
       
  8349     },
       
  8350 
       
  8351     distance: function(s, t) {
       
  8352       var dx = s.x - t.x,
       
  8353           dy = s.y - t.y;
       
  8354       return Math.sqrt(dx * dx + dy * dy);
       
  8355     }
       
  8356   };
       
  8357 
       
  8358   var EventQueue = {
       
  8359     list: [],
       
  8360 
       
  8361     insert: function(he, site, offset) {
       
  8362       he.vertex = site;
       
  8363       he.ystar = site.y + offset;
       
  8364       for (var i=0, list=EventQueue.list, l=list.length; i<l; i++) {
       
  8365         var next = list[i];
       
  8366         if (he.ystar > next.ystar ||
       
  8367           (he.ystar == next.ystar &&
       
  8368           site.x > next.vertex.x)) {
       
  8369           continue;
       
  8370         } else {
       
  8371           break;
       
  8372         }
       
  8373       }
       
  8374       list.splice(i, 0, he);
       
  8375     },
       
  8376 
       
  8377     del: function(he) {
       
  8378       for (var i=0, ls=EventQueue.list, l=ls.length; i<l && (ls[i] != he); ++i) {}
       
  8379       ls.splice(i, 1);
       
  8380     },
       
  8381 
       
  8382     empty: function() { return EventQueue.list.length === 0; },
       
  8383 
       
  8384     nextEvent: function(he) {
       
  8385       for (var i=0, ls=EventQueue.list, l=ls.length; i<l; ++i) {
       
  8386         if (ls[i] == he) return ls[i+1];
       
  8387       }
       
  8388       return null;
       
  8389     },
       
  8390 
       
  8391     min: function() {
       
  8392       var elem = EventQueue.list[0];
       
  8393       return {
       
  8394         x: elem.vertex.x,
       
  8395         y: elem.ystar
       
  8396       };
       
  8397     },
       
  8398 
       
  8399     extractMin: function() {
       
  8400       return EventQueue.list.shift();
       
  8401     }
       
  8402   };
       
  8403 
       
  8404   EdgeList.init();
       
  8405   Sites.bottomSite = Sites.list.shift();
       
  8406 
       
  8407   var newSite = Sites.list.shift(), newIntStar;
       
  8408   var lbnd, rbnd, llbnd, rrbnd, bisector;
       
  8409   var bot, top, temp, p, v;
       
  8410   var e, pm;
       
  8411 
       
  8412   while (true) {
       
  8413     if (!EventQueue.empty()) {
       
  8414       newIntStar = EventQueue.min();
       
  8415     }
       
  8416     if (newSite && (EventQueue.empty()
       
  8417       || newSite.y < newIntStar.y
       
  8418       || (newSite.y == newIntStar.y
       
  8419       && newSite.x < newIntStar.x))) { //new site is smallest
       
  8420       lbnd = EdgeList.leftBound(newSite);
       
  8421       rbnd = EdgeList.right(lbnd);
       
  8422       bot = EdgeList.rightRegion(lbnd);
       
  8423       e = Geom.bisect(bot, newSite);
       
  8424       bisector = EdgeList.createHalfEdge(e, "l");
       
  8425       EdgeList.insert(lbnd, bisector);
       
  8426       p = Geom.intersect(lbnd, bisector);
       
  8427       if (p) {
       
  8428         EventQueue.del(lbnd);
       
  8429         EventQueue.insert(lbnd, p, Geom.distance(p, newSite));
       
  8430       }
       
  8431       lbnd = bisector;
       
  8432       bisector = EdgeList.createHalfEdge(e, "r");
       
  8433       EdgeList.insert(lbnd, bisector);
       
  8434       p = Geom.intersect(bisector, rbnd);
       
  8435       if (p) {
       
  8436         EventQueue.insert(bisector, p, Geom.distance(p, newSite));
       
  8437       }
       
  8438       newSite = Sites.list.shift();
       
  8439     } else if (!EventQueue.empty()) { //intersection is smallest
       
  8440       lbnd = EventQueue.extractMin();
       
  8441       llbnd = EdgeList.left(lbnd);
       
  8442       rbnd = EdgeList.right(lbnd);
       
  8443       rrbnd = EdgeList.right(rbnd);
       
  8444       bot = EdgeList.leftRegion(lbnd);
       
  8445       top = EdgeList.rightRegion(rbnd);
       
  8446       v = lbnd.vertex;
       
  8447       Geom.endPoint(lbnd.edge, lbnd.side, v);
       
  8448       Geom.endPoint(rbnd.edge, rbnd.side, v);
       
  8449       EdgeList.del(lbnd);
       
  8450       EventQueue.del(rbnd);
       
  8451       EdgeList.del(rbnd);
       
  8452       pm = "l";
       
  8453       if (bot.y > top.y) {
       
  8454         temp = bot;
       
  8455         bot = top;
       
  8456         top = temp;
       
  8457         pm = "r";
       
  8458       }
       
  8459       e = Geom.bisect(bot, top);
       
  8460       bisector = EdgeList.createHalfEdge(e, pm);
       
  8461       EdgeList.insert(llbnd, bisector);
       
  8462       Geom.endPoint(e, d3_voronoi_opposite[pm], v);
       
  8463       p = Geom.intersect(llbnd, bisector);
       
  8464       if (p) {
       
  8465         EventQueue.del(llbnd);
       
  8466         EventQueue.insert(llbnd, p, Geom.distance(p, bot));
       
  8467       }
       
  8468       p = Geom.intersect(bisector, rrbnd);
       
  8469       if (p) {
       
  8470         EventQueue.insert(bisector, p, Geom.distance(p, bot));
       
  8471       }
       
  8472     } else {
       
  8473       break;
       
  8474     }
       
  8475   }//end while
       
  8476 
       
  8477   for (lbnd = EdgeList.right(EdgeList.leftEnd);
       
  8478       lbnd != EdgeList.rightEnd;
       
  8479       lbnd = EdgeList.right(lbnd)) {
       
  8480     callback(lbnd.edge);
       
  8481   }
       
  8482 }
       
  8483 /**
       
  8484 * @param vertices [[x1, y1], [x2, y2], …]
       
  8485 * @returns triangles [[[x1, y1], [x2, y2], [x3, y3]], …]
       
  8486  */
       
  8487 d3.geom.delaunay = function(vertices) {
       
  8488   var edges = vertices.map(function() { return []; }),
       
  8489       triangles = [];
       
  8490 
       
  8491   // Use the Voronoi tessellation to determine Delaunay edges.
       
  8492   d3_voronoi_tessellate(vertices, function(e) {
       
  8493     edges[e.region.l.index].push(vertices[e.region.r.index]);
       
  8494   });
       
  8495 
       
  8496   // Reconnect the edges into counterclockwise triangles.
       
  8497   edges.forEach(function(edge, i) {
       
  8498     var v = vertices[i],
       
  8499         cx = v[0],
       
  8500         cy = v[1];
       
  8501     edge.forEach(function(v) {
       
  8502       v.angle = Math.atan2(v[0] - cx, v[1] - cy);
       
  8503     });
       
  8504     edge.sort(function(a, b) {
       
  8505       return a.angle - b.angle;
       
  8506     });
       
  8507     for (var j = 0, m = edge.length - 1; j < m; j++) {
       
  8508       triangles.push([v, edge[j], edge[j + 1]]);
       
  8509     }
       
  8510   });
       
  8511 
       
  8512   return triangles;
       
  8513 };
       
  8514 // Constructs a new quadtree for the specified array of points. A quadtree is a
       
  8515 // two-dimensional recursive spatial subdivision. This implementation uses
       
  8516 // square partitions, dividing each square into four equally-sized squares. Each
       
  8517 // point exists in a unique node; if multiple points are in the same position,
       
  8518 // some points may be stored on internal nodes rather than leaf nodes. Quadtrees
       
  8519 // can be used to accelerate various spatial operations, such as the Barnes-Hut
       
  8520 // approximation for computing n-body forces, or collision detection.
       
  8521 d3.geom.quadtree = function(points, x1, y1, x2, y2) {
       
  8522   var p,
       
  8523       i = -1,
       
  8524       n = points.length;
       
  8525 
       
  8526   // Type conversion for deprecated API.
       
  8527   if (n && isNaN(points[0].x)) points = points.map(d3_geom_quadtreePoint);
       
  8528 
       
  8529   // Allow bounds to be specified explicitly.
       
  8530   if (arguments.length < 5) {
       
  8531     if (arguments.length === 3) {
       
  8532       y2 = x2 = y1;
       
  8533       y1 = x1;
       
  8534     } else {
       
  8535       x1 = y1 = Infinity;
       
  8536       x2 = y2 = -Infinity;
       
  8537 
       
  8538       // Compute bounds.
       
  8539       while (++i < n) {
       
  8540         p = points[i];
       
  8541         if (p.x < x1) x1 = p.x;
       
  8542         if (p.y < y1) y1 = p.y;
       
  8543         if (p.x > x2) x2 = p.x;
       
  8544         if (p.y > y2) y2 = p.y;
       
  8545       }
       
  8546 
       
  8547       // Squarify the bounds.
       
  8548       var dx = x2 - x1,
       
  8549           dy = y2 - y1;
       
  8550       if (dx > dy) y2 = y1 + dx;
       
  8551       else x2 = x1 + dy;
       
  8552     }
       
  8553   }
       
  8554 
       
  8555   // Recursively inserts the specified point p at the node n or one of its
       
  8556   // descendants. The bounds are defined by [x1, x2] and [y1, y2].
       
  8557   function insert(n, p, x1, y1, x2, y2) {
       
  8558     if (isNaN(p.x) || isNaN(p.y)) return; // ignore invalid points
       
  8559     if (n.leaf) {
       
  8560       var v = n.point;
       
  8561       if (v) {
       
  8562         // If the point at this leaf node is at the same position as the new
       
  8563         // point we are adding, we leave the point associated with the
       
  8564         // internal node while adding the new point to a child node. This
       
  8565         // avoids infinite recursion.
       
  8566         if ((Math.abs(v.x - p.x) + Math.abs(v.y - p.y)) < .01) {
       
  8567           insertChild(n, p, x1, y1, x2, y2);
       
  8568         } else {
       
  8569           n.point = null;
       
  8570           insertChild(n, v, x1, y1, x2, y2);
       
  8571           insertChild(n, p, x1, y1, x2, y2);
       
  8572         }
       
  8573       } else {
       
  8574         n.point = p;
       
  8575       }
       
  8576     } else {
       
  8577       insertChild(n, p, x1, y1, x2, y2);
       
  8578     }
       
  8579   }
       
  8580 
       
  8581   // Recursively inserts the specified point p into a descendant of node n. The
       
  8582   // bounds are defined by [x1, x2] and [y1, y2].
       
  8583   function insertChild(n, p, x1, y1, x2, y2) {
       
  8584     // Compute the split point, and the quadrant in which to insert p.
       
  8585     var sx = (x1 + x2) * .5,
       
  8586         sy = (y1 + y2) * .5,
       
  8587         right = p.x >= sx,
       
  8588         bottom = p.y >= sy,
       
  8589         i = (bottom << 1) + right;
       
  8590 
       
  8591     // Recursively insert into the child node.
       
  8592     n.leaf = false;
       
  8593     n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode());
       
  8594 
       
  8595     // Update the bounds as we recurse.
       
  8596     if (right) x1 = sx; else x2 = sx;
       
  8597     if (bottom) y1 = sy; else y2 = sy;
       
  8598     insert(n, p, x1, y1, x2, y2);
       
  8599   }
       
  8600 
       
  8601   // Create the root node.
       
  8602   var root = d3_geom_quadtreeNode();
       
  8603 
       
  8604   root.add = function(p) {
       
  8605     insert(root, p, x1, y1, x2, y2);
       
  8606   };
       
  8607 
       
  8608   root.visit = function(f) {
       
  8609     d3_geom_quadtreeVisit(f, root, x1, y1, x2, y2);
       
  8610   };
       
  8611 
       
  8612   // Insert all points.
       
  8613   points.forEach(root.add);
       
  8614   return root;
       
  8615 };
       
  8616 
       
  8617 function d3_geom_quadtreeNode() {
       
  8618   return {
       
  8619     leaf: true,
       
  8620     nodes: [],
       
  8621     point: null
       
  8622   };
       
  8623 }
       
  8624 
       
  8625 function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) {
       
  8626   if (!f(node, x1, y1, x2, y2)) {
       
  8627     var sx = (x1 + x2) * .5,
       
  8628         sy = (y1 + y2) * .5,
       
  8629         children = node.nodes;
       
  8630     if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy);
       
  8631     if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy);
       
  8632     if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2);
       
  8633     if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2);
       
  8634   }
       
  8635 }
       
  8636 
       
  8637 function d3_geom_quadtreePoint(p) {
       
  8638   return {
       
  8639     x: p[0],
       
  8640     y: p[1]
       
  8641   };
       
  8642 }
       
  8643 d3.time = {};
       
  8644 
       
  8645 var d3_time = Date;
       
  8646 
       
  8647 function d3_time_utc() {
       
  8648   this._ = new Date(arguments.length > 1
       
  8649       ? Date.UTC.apply(this, arguments)
       
  8650       : arguments[0]);
       
  8651 }
       
  8652 
       
  8653 d3_time_utc.prototype = {
       
  8654   getDate: function() { return this._.getUTCDate(); },
       
  8655   getDay: function() { return this._.getUTCDay(); },
       
  8656   getFullYear: function() { return this._.getUTCFullYear(); },
       
  8657   getHours: function() { return this._.getUTCHours(); },
       
  8658   getMilliseconds: function() { return this._.getUTCMilliseconds(); },
       
  8659   getMinutes: function() { return this._.getUTCMinutes(); },
       
  8660   getMonth: function() { return this._.getUTCMonth(); },
       
  8661   getSeconds: function() { return this._.getUTCSeconds(); },
       
  8662   getTime: function() { return this._.getTime(); },
       
  8663   getTimezoneOffset: function() { return 0; },
       
  8664   valueOf: function() { return this._.valueOf(); },
       
  8665   setDate: function() { d3_time_prototype.setUTCDate.apply(this._, arguments); },
       
  8666   setDay: function() { d3_time_prototype.setUTCDay.apply(this._, arguments); },
       
  8667   setFullYear: function() { d3_time_prototype.setUTCFullYear.apply(this._, arguments); },
       
  8668   setHours: function() { d3_time_prototype.setUTCHours.apply(this._, arguments); },
       
  8669   setMilliseconds: function() { d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); },
       
  8670   setMinutes: function() { d3_time_prototype.setUTCMinutes.apply(this._, arguments); },
       
  8671   setMonth: function() { d3_time_prototype.setUTCMonth.apply(this._, arguments); },
       
  8672   setSeconds: function() { d3_time_prototype.setUTCSeconds.apply(this._, arguments); },
       
  8673   setTime: function() { d3_time_prototype.setTime.apply(this._, arguments); }
       
  8674 };
       
  8675 
       
  8676 var d3_time_prototype = Date.prototype;
       
  8677 d3.time.format = function(template) {
       
  8678   var n = template.length;
       
  8679 
       
  8680   function format(date) {
       
  8681     var string = [],
       
  8682         i = -1,
       
  8683         j = 0,
       
  8684         c,
       
  8685         f;
       
  8686     while (++i < n) {
       
  8687       if (template.charCodeAt(i) == 37) {
       
  8688         string.push(
       
  8689             template.substring(j, i),
       
  8690             (f = d3_time_formats[c = template.charAt(++i)])
       
  8691             ? f(date) : c);
       
  8692         j = i + 1;
       
  8693       }
       
  8694     }
       
  8695     string.push(template.substring(j, i));
       
  8696     return string.join("");
       
  8697   }
       
  8698 
       
  8699   format.parse = function(string) {
       
  8700     var d = {y: 1900, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0},
       
  8701         i = d3_time_parse(d, template, string, 0);
       
  8702     if (i != string.length) return null;
       
  8703 
       
  8704     // The am-pm flag is 0 for AM, and 1 for PM.
       
  8705     if ("p" in d) d.H = d.H % 12 + d.p * 12;
       
  8706 
       
  8707     var date = new d3_time();
       
  8708     date.setFullYear(d.y, d.m, d.d);
       
  8709     date.setHours(d.H, d.M, d.S, d.L);
       
  8710     return date;
       
  8711   };
       
  8712 
       
  8713   format.toString = function() {
       
  8714     return template;
       
  8715   };
       
  8716 
       
  8717   return format;
       
  8718 };
       
  8719 
       
  8720 function d3_time_parse(date, template, string, j) {
       
  8721   var c,
       
  8722       p,
       
  8723       i = 0,
       
  8724       n = template.length,
       
  8725       m = string.length;
       
  8726   while (i < n) {
       
  8727     if (j >= m) return -1;
       
  8728     c = template.charCodeAt(i++);
       
  8729     if (c == 37) {
       
  8730       p = d3_time_parsers[template.charAt(i++)];
       
  8731       if (!p || ((j = p(date, string, j)) < 0)) return -1;
       
  8732     } else if (c != string.charCodeAt(j++)) {
       
  8733       return -1;
       
  8734     }
       
  8735   }
       
  8736   return j;
       
  8737 }
       
  8738 
       
  8739 var d3_time_zfill2 = d3.format("02d"),
       
  8740     d3_time_zfill3 = d3.format("03d"),
       
  8741     d3_time_zfill4 = d3.format("04d"),
       
  8742     d3_time_sfill2 = d3.format("2d");
       
  8743 
       
  8744 var d3_time_formats = {
       
  8745   a: function(d) { return d3_time_weekdays[d.getDay()].substring(0, 3); },
       
  8746   A: function(d) { return d3_time_weekdays[d.getDay()]; },
       
  8747   b: function(d) { return d3_time_months[d.getMonth()].substring(0, 3); },
       
  8748   B: function(d) { return d3_time_months[d.getMonth()]; },
       
  8749   c: d3.time.format("%a %b %e %H:%M:%S %Y"),
       
  8750   d: function(d) { return d3_time_zfill2(d.getDate()); },
       
  8751   e: function(d) { return d3_time_sfill2(d.getDate()); },
       
  8752   H: function(d) { return d3_time_zfill2(d.getHours()); },
       
  8753   I: function(d) { return d3_time_zfill2(d.getHours() % 12 || 12); },
       
  8754   j: function(d) { return d3_time_zfill3(1 + d3.time.dayOfYear(d)); },
       
  8755   L: function(d) { return d3_time_zfill3(d.getMilliseconds()); },
       
  8756   m: function(d) { return d3_time_zfill2(d.getMonth() + 1); },
       
  8757   M: function(d) { return d3_time_zfill2(d.getMinutes()); },
       
  8758   p: function(d) { return d.getHours() >= 12 ? "PM" : "AM"; },
       
  8759   S: function(d) { return d3_time_zfill2(d.getSeconds()); },
       
  8760   U: function(d) { return d3_time_zfill2(d3.time.sundayOfYear(d)); },
       
  8761   w: function(d) { return d.getDay(); },
       
  8762   W: function(d) { return d3_time_zfill2(d3.time.mondayOfYear(d)); },
       
  8763   x: d3.time.format("%m/%d/%y"),
       
  8764   X: d3.time.format("%H:%M:%S"),
       
  8765   y: function(d) { return d3_time_zfill2(d.getFullYear() % 100); },
       
  8766   Y: function(d) { return d3_time_zfill4(d.getFullYear() % 10000); },
       
  8767   Z: d3_time_zone,
       
  8768   "%": function(d) { return "%"; }
       
  8769 };
       
  8770 
       
  8771 var d3_time_parsers = {
       
  8772   a: d3_time_parseWeekdayAbbrev,
       
  8773   A: d3_time_parseWeekday,
       
  8774   b: d3_time_parseMonthAbbrev,
       
  8775   B: d3_time_parseMonth,
       
  8776   c: d3_time_parseLocaleFull,
       
  8777   d: d3_time_parseDay,
       
  8778   e: d3_time_parseDay,
       
  8779   H: d3_time_parseHour24,
       
  8780   I: d3_time_parseHour24,
       
  8781   // j: function(d, s, i) { /*TODO day of year [001,366] */ return i; },
       
  8782   L: d3_time_parseMilliseconds,
       
  8783   m: d3_time_parseMonthNumber,
       
  8784   M: d3_time_parseMinutes,
       
  8785   p: d3_time_parseAmPm,
       
  8786   S: d3_time_parseSeconds,
       
  8787   // U: function(d, s, i) { /*TODO week number (sunday) [00,53] */ return i; },
       
  8788   // w: function(d, s, i) { /*TODO weekday [0,6] */ return i; },
       
  8789   // W: function(d, s, i) { /*TODO week number (monday) [00,53] */ return i; },
       
  8790   x: d3_time_parseLocaleDate,
       
  8791   X: d3_time_parseLocaleTime,
       
  8792   y: d3_time_parseYear,
       
  8793   Y: d3_time_parseFullYear
       
  8794   // ,
       
  8795   // Z: function(d, s, i) { /*TODO time zone */ return i; },
       
  8796   // "%": function(d, s, i) { /*TODO literal % */ return i; }
       
  8797 };
       
  8798 
       
  8799 // Note: weekday is validated, but does not set the date.
       
  8800 function d3_time_parseWeekdayAbbrev(date, string, i) {
       
  8801   return d3_time_weekdayAbbrevRe.test(string.substring(i, i += 3)) ? i : -1;
       
  8802 }
       
  8803 
       
  8804 // Note: weekday is validated, but does not set the date.
       
  8805 function d3_time_parseWeekday(date, string, i) {
       
  8806   d3_time_weekdayRe.lastIndex = 0;
       
  8807   var n = d3_time_weekdayRe.exec(string.substring(i, i + 10));
       
  8808   return n ? i += n[0].length : -1;
       
  8809 }
       
  8810 
       
  8811 var d3_time_weekdayAbbrevRe = /^(?:sun|mon|tue|wed|thu|fri|sat)/i,
       
  8812     d3_time_weekdayRe = /^(?:Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday)/i;
       
  8813     d3_time_weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
       
  8814 
       
  8815 function d3_time_parseMonthAbbrev(date, string, i) {
       
  8816   var n = d3_time_monthAbbrevLookup.get(string.substring(i, i += 3).toLowerCase());
       
  8817   return n == null ? -1 : (date.m = n, i);
       
  8818 }
       
  8819 
       
  8820 var d3_time_monthAbbrevLookup = d3.map({
       
  8821   jan: 0,
       
  8822   feb: 1,
       
  8823   mar: 2,
       
  8824   apr: 3,
       
  8825   may: 4,
       
  8826   jun: 5,
       
  8827   jul: 6,
       
  8828   aug: 7,
       
  8829   sep: 8,
       
  8830   oct: 9,
       
  8831   nov: 10,
       
  8832   dec: 11
       
  8833 });
       
  8834 
       
  8835 function d3_time_parseMonth(date, string, i) {
       
  8836   d3_time_monthRe.lastIndex = 0;
       
  8837   var n = d3_time_monthRe.exec(string.substring(i, i + 12));
       
  8838   return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i += n[0].length) : -1;
       
  8839 }
       
  8840 
       
  8841 var d3_time_monthRe = /^(?:January|February|March|April|May|June|July|August|September|October|November|December)/ig;
       
  8842 
       
  8843 var d3_time_monthLookup = d3.map({
       
  8844   january: 0,
       
  8845   february: 1,
       
  8846   march: 2,
       
  8847   april: 3,
       
  8848   may: 4,
       
  8849   june: 5,
       
  8850   july: 6,
       
  8851   august: 7,
       
  8852   september: 8,
       
  8853   october: 9,
       
  8854   november: 10,
       
  8855   december: 11
       
  8856 });
       
  8857 
       
  8858 var d3_time_months = [
       
  8859   "January",
       
  8860   "February",
       
  8861   "March",
       
  8862   "April",
       
  8863   "May",
       
  8864   "June",
       
  8865   "July",
       
  8866   "August",
       
  8867   "September",
       
  8868   "October",
       
  8869   "November",
       
  8870   "December"
       
  8871 ];
       
  8872 
       
  8873 function d3_time_parseLocaleFull(date, string, i) {
       
  8874   return d3_time_parse(date, d3_time_formats.c.toString(), string, i);
       
  8875 }
       
  8876 
       
  8877 function d3_time_parseLocaleDate(date, string, i) {
       
  8878   return d3_time_parse(date, d3_time_formats.x.toString(), string, i);
       
  8879 }
       
  8880 
       
  8881 function d3_time_parseLocaleTime(date, string, i) {
       
  8882   return d3_time_parse(date, d3_time_formats.X.toString(), string, i);
       
  8883 }
       
  8884 
       
  8885 function d3_time_parseFullYear(date, string, i) {
       
  8886   d3_time_numberRe.lastIndex = 0;
       
  8887   var n = d3_time_numberRe.exec(string.substring(i, i + 4));
       
  8888   return n ? (date.y = +n[0], i += n[0].length) : -1;
       
  8889 }
       
  8890 
       
  8891 function d3_time_parseYear(date, string, i) {
       
  8892   d3_time_numberRe.lastIndex = 0;
       
  8893   var n = d3_time_numberRe.exec(string.substring(i, i + 2));
       
  8894   return n ? (date.y = d3_time_century() + +n[0], i += n[0].length) : -1;
       
  8895 }
       
  8896 
       
  8897 function d3_time_century() {
       
  8898   return ~~(new Date().getFullYear() / 1000) * 1000;
       
  8899 }
       
  8900 
       
  8901 function d3_time_parseMonthNumber(date, string, i) {
       
  8902   d3_time_numberRe.lastIndex = 0;
       
  8903   var n = d3_time_numberRe.exec(string.substring(i, i + 2));
       
  8904   return n ? (date.m = n[0] - 1, i += n[0].length) : -1;
       
  8905 }
       
  8906 
       
  8907 function d3_time_parseDay(date, string, i) {
       
  8908   d3_time_numberRe.lastIndex = 0;
       
  8909   var n = d3_time_numberRe.exec(string.substring(i, i + 2));
       
  8910   return n ? (date.d = +n[0], i += n[0].length) : -1;
       
  8911 }
       
  8912 
       
  8913 // Note: we don't validate that the hour is in the range [0,23] or [1,12].
       
  8914 function d3_time_parseHour24(date, string, i) {
       
  8915   d3_time_numberRe.lastIndex = 0;
       
  8916   var n = d3_time_numberRe.exec(string.substring(i, i + 2));
       
  8917   return n ? (date.H = +n[0], i += n[0].length) : -1;
       
  8918 }
       
  8919 
       
  8920 function d3_time_parseMinutes(date, string, i) {
       
  8921   d3_time_numberRe.lastIndex = 0;
       
  8922   var n = d3_time_numberRe.exec(string.substring(i, i + 2));
       
  8923   return n ? (date.M = +n[0], i += n[0].length) : -1;
       
  8924 }
       
  8925 
       
  8926 function d3_time_parseSeconds(date, string, i) {
       
  8927   d3_time_numberRe.lastIndex = 0;
       
  8928   var n = d3_time_numberRe.exec(string.substring(i, i + 2));
       
  8929   return n ? (date.S = +n[0], i += n[0].length) : -1;
       
  8930 }
       
  8931 
       
  8932 function d3_time_parseMilliseconds(date, string, i) {
       
  8933   d3_time_numberRe.lastIndex = 0;
       
  8934   var n = d3_time_numberRe.exec(string.substring(i, i + 3));
       
  8935   return n ? (date.L = +n[0], i += n[0].length) : -1;
       
  8936 }
       
  8937 
       
  8938 // Note: we don't look at the next directive.
       
  8939 var d3_time_numberRe = /\s*\d+/;
       
  8940 
       
  8941 function d3_time_parseAmPm(date, string, i) {
       
  8942   var n = d3_time_amPmLookup.get(string.substring(i, i += 2).toLowerCase());
       
  8943   return n == null ? -1 : (date.p = n, i);
       
  8944 }
       
  8945 
       
  8946 var d3_time_amPmLookup = d3.map({
       
  8947   am: 0,
       
  8948   pm: 1
       
  8949 });
       
  8950 
       
  8951 // TODO table of time zone offset names?
       
  8952 function d3_time_zone(d) {
       
  8953   var z = d.getTimezoneOffset(),
       
  8954       zs = z > 0 ? "-" : "+",
       
  8955       zh = ~~(Math.abs(z) / 60),
       
  8956       zm = Math.abs(z) % 60;
       
  8957   return zs + d3_time_zfill2(zh) + d3_time_zfill2(zm);
       
  8958 }
       
  8959 d3.time.format.utc = function(template) {
       
  8960   var local = d3.time.format(template);
       
  8961 
       
  8962   function format(date) {
       
  8963     try {
       
  8964       d3_time = d3_time_utc;
       
  8965       var utc = new d3_time();
       
  8966       utc._ = date;
       
  8967       return local(utc);
       
  8968     } finally {
       
  8969       d3_time = Date;
       
  8970     }
       
  8971   }
       
  8972 
       
  8973   format.parse = function(string) {
       
  8974     try {
       
  8975       d3_time = d3_time_utc;
       
  8976       var date = local.parse(string);
       
  8977       return date && date._;
       
  8978     } finally {
       
  8979       d3_time = Date;
       
  8980     }
       
  8981   };
       
  8982 
       
  8983   format.toString = local.toString;
       
  8984 
       
  8985   return format;
       
  8986 };
       
  8987 var d3_time_formatIso = d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");
       
  8988 
       
  8989 d3.time.format.iso = Date.prototype.toISOString ? d3_time_formatIsoNative : d3_time_formatIso;
       
  8990 
       
  8991 function d3_time_formatIsoNative(date) {
       
  8992   return date.toISOString();
       
  8993 }
       
  8994 
       
  8995 d3_time_formatIsoNative.parse = function(string) {
       
  8996   return new Date(string);
       
  8997 };
       
  8998 
       
  8999 d3_time_formatIsoNative.toString = d3_time_formatIso.toString;
       
  9000 function d3_time_interval(local, step, number) {
       
  9001 
       
  9002   function round(date) {
       
  9003     var d0 = local(date), d1 = offset(d0, 1);
       
  9004     return date - d0 < d1 - date ? d0 : d1;
       
  9005   }
       
  9006 
       
  9007   function ceil(date) {
       
  9008     step(date = local(new d3_time(date - 1)), 1);
       
  9009     return date;
       
  9010   }
       
  9011 
       
  9012   function offset(date, k) {
       
  9013     step(date = new d3_time(+date), k);
       
  9014     return date;
       
  9015   }
       
  9016 
       
  9017   function range(t0, t1, dt) {
       
  9018     var time = ceil(t0), times = [];
       
  9019     if (dt > 1) {
       
  9020       while (time < t1) {
       
  9021         if (!(number(time) % dt)) times.push(new Date(+time));
       
  9022         step(time, 1);
       
  9023       }
       
  9024     } else {
       
  9025       while (time < t1) times.push(new Date(+time)), step(time, 1);
       
  9026     }
       
  9027     return times;
       
  9028   }
       
  9029 
       
  9030   function range_utc(t0, t1, dt) {
       
  9031     try {
       
  9032       d3_time = d3_time_utc;
       
  9033       var utc = new d3_time_utc();
       
  9034       utc._ = t0;
       
  9035       return range(utc, t1, dt);
       
  9036     } finally {
       
  9037       d3_time = Date;
       
  9038     }
       
  9039   }
       
  9040 
       
  9041   local.floor = local;
       
  9042   local.round = round;
       
  9043   local.ceil = ceil;
       
  9044   local.offset = offset;
       
  9045   local.range = range;
       
  9046 
       
  9047   var utc = local.utc = d3_time_interval_utc(local);
       
  9048   utc.floor = utc;
       
  9049   utc.round = d3_time_interval_utc(round);
       
  9050   utc.ceil = d3_time_interval_utc(ceil);
       
  9051   utc.offset = d3_time_interval_utc(offset);
       
  9052   utc.range = range_utc;
       
  9053 
       
  9054   return local;
       
  9055 }
       
  9056 
       
  9057 function d3_time_interval_utc(method) {
       
  9058   return function(date, k) {
       
  9059     try {
       
  9060       d3_time = d3_time_utc;
       
  9061       var utc = new d3_time_utc();
       
  9062       utc._ = date;
       
  9063       return method(utc, k)._;
       
  9064     } finally {
       
  9065       d3_time = Date;
       
  9066     }
       
  9067   };
       
  9068 }
       
  9069 d3.time.second = d3_time_interval(function(date) {
       
  9070   return new d3_time(Math.floor(date / 1e3) * 1e3);
       
  9071 }, function(date, offset) {
       
  9072   date.setTime(date.getTime() + Math.floor(offset) * 1e3); // DST breaks setSeconds
       
  9073 }, function(date) {
       
  9074   return date.getSeconds();
       
  9075 });
       
  9076 
       
  9077 d3.time.seconds = d3.time.second.range;
       
  9078 d3.time.seconds.utc = d3.time.second.utc.range;
       
  9079 d3.time.minute = d3_time_interval(function(date) {
       
  9080   return new d3_time(Math.floor(date / 6e4) * 6e4);
       
  9081 }, function(date, offset) {
       
  9082   date.setTime(date.getTime() + Math.floor(offset) * 6e4); // DST breaks setMinutes
       
  9083 }, function(date) {
       
  9084   return date.getMinutes();
       
  9085 });
       
  9086 
       
  9087 d3.time.minutes = d3.time.minute.range;
       
  9088 d3.time.minutes.utc = d3.time.minute.utc.range;
       
  9089 d3.time.hour = d3_time_interval(function(date) {
       
  9090   var timezone = date.getTimezoneOffset() / 60;
       
  9091   return new d3_time((Math.floor(date / 36e5 - timezone) + timezone) * 36e5);
       
  9092 }, function(date, offset) {
       
  9093   date.setTime(date.getTime() + Math.floor(offset) * 36e5); // DST breaks setHours
       
  9094 }, function(date) {
       
  9095   return date.getHours();
       
  9096 });
       
  9097 
       
  9098 d3.time.hours = d3.time.hour.range;
       
  9099 d3.time.hours.utc = d3.time.hour.utc.range;
       
  9100 d3.time.day = d3_time_interval(function(date) {
       
  9101   return new d3_time(date.getFullYear(), date.getMonth(), date.getDate());
       
  9102 }, function(date, offset) {
       
  9103   date.setDate(date.getDate() + offset);
       
  9104 }, function(date) {
       
  9105   return date.getDate() - 1;
       
  9106 });
       
  9107 
       
  9108 d3.time.days = d3.time.day.range;
       
  9109 d3.time.days.utc = d3.time.day.utc.range;
       
  9110 
       
  9111 d3.time.dayOfYear = function(date) {
       
  9112   var year = d3.time.year(date);
       
  9113   return Math.floor((date - year) / 864e5 - (date.getTimezoneOffset() - year.getTimezoneOffset()) / 1440);
       
  9114 };
       
  9115 d3_time_weekdays.forEach(function(day, i) {
       
  9116   day = day.toLowerCase();
       
  9117   i = 7 - i;
       
  9118 
       
  9119   var interval = d3.time[day] = d3_time_interval(function(date) {
       
  9120     (date = d3.time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7);
       
  9121     return date;
       
  9122   }, function(date, offset) {
       
  9123     date.setDate(date.getDate() + Math.floor(offset) * 7);
       
  9124   }, function(date) {
       
  9125     var day = d3.time.year(date).getDay();
       
  9126     return Math.floor((d3.time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i);
       
  9127   });
       
  9128 
       
  9129   d3.time[day + "s"] = interval.range;
       
  9130   d3.time[day + "s"].utc = interval.utc.range;
       
  9131 
       
  9132   d3.time[day + "OfYear"] = function(date) {
       
  9133     var day = d3.time.year(date).getDay();
       
  9134     return Math.floor((d3.time.dayOfYear(date) + (day + i) % 7) / 7);
       
  9135   };
       
  9136 });
       
  9137 
       
  9138 d3.time.week = d3.time.sunday;
       
  9139 d3.time.weeks = d3.time.sunday.range;
       
  9140 d3.time.weeks.utc = d3.time.sunday.utc.range;
       
  9141 d3.time.weekOfYear = d3.time.sundayOfYear;
       
  9142 d3.time.month = d3_time_interval(function(date) {
       
  9143   return new d3_time(date.getFullYear(), date.getMonth(), 1);
       
  9144 }, function(date, offset) {
       
  9145   date.setMonth(date.getMonth() + offset);
       
  9146 }, function(date) {
       
  9147   return date.getMonth();
       
  9148 });
       
  9149 
       
  9150 d3.time.months = d3.time.month.range;
       
  9151 d3.time.months.utc = d3.time.month.utc.range;
       
  9152 d3.time.year = d3_time_interval(function(date) {
       
  9153   return new d3_time(date.getFullYear(), 0, 1);
       
  9154 }, function(date, offset) {
       
  9155   date.setFullYear(date.getFullYear() + offset);
       
  9156 }, function(date) {
       
  9157   return date.getFullYear();
       
  9158 });
       
  9159 
       
  9160 d3.time.years = d3.time.year.range;
       
  9161 d3.time.years.utc = d3.time.year.utc.range;
       
  9162 function d3_time_scale(linear, methods, format) {
       
  9163 
       
  9164   function scale(x) {
       
  9165     return linear(x);
       
  9166   }
       
  9167 
       
  9168   scale.invert = function(x) {
       
  9169     return d3_time_scaleDate(linear.invert(x));
       
  9170   };
       
  9171 
       
  9172   scale.domain = function(x) {
       
  9173     if (!arguments.length) return linear.domain().map(d3_time_scaleDate);
       
  9174     linear.domain(x);
       
  9175     return scale;
       
  9176   };
       
  9177 
       
  9178   scale.nice = function(m) {
       
  9179     var extent = d3_time_scaleExtent(scale.domain());
       
  9180     return scale.domain([m.floor(extent[0]), m.ceil(extent[1])]);
       
  9181   };
       
  9182 
       
  9183   scale.ticks = function(m, k) {
       
  9184     var extent = d3_time_scaleExtent(scale.domain());
       
  9185     if (typeof m !== "function") {
       
  9186       var span = extent[1] - extent[0],
       
  9187           target = span / m,
       
  9188           i = d3.bisect(d3_time_scaleSteps, target);
       
  9189       if (i == d3_time_scaleSteps.length) return methods.year(extent, m);
       
  9190       if (!i) return linear.ticks(m).map(d3_time_scaleDate);
       
  9191       if (Math.log(target / d3_time_scaleSteps[i - 1]) < Math.log(d3_time_scaleSteps[i] / target)) --i;
       
  9192       m = methods[i];
       
  9193       k = m[1];
       
  9194       m = m[0].range;
       
  9195     }
       
  9196     return m(extent[0], new Date(+extent[1] + 1), k); // inclusive upper bound
       
  9197   };
       
  9198 
       
  9199   scale.tickFormat = function() {
       
  9200     return format;
       
  9201   };
       
  9202 
       
  9203   scale.copy = function() {
       
  9204     return d3_time_scale(linear.copy(), methods, format);
       
  9205   };
       
  9206 
       
  9207   // TOOD expose d3_scale_linear_rebind?
       
  9208   return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp");
       
  9209 }
       
  9210 
       
  9211 // TODO expose d3_scaleExtent?
       
  9212 function d3_time_scaleExtent(domain) {
       
  9213   var start = domain[0], stop = domain[domain.length - 1];
       
  9214   return start < stop ? [start, stop] : [stop, start];
       
  9215 }
       
  9216 
       
  9217 function d3_time_scaleDate(t) {
       
  9218   return new Date(t);
       
  9219 }
       
  9220 
       
  9221 function d3_time_scaleFormat(formats) {
       
  9222   return function(date) {
       
  9223     var i = formats.length - 1, f = formats[i];
       
  9224     while (!f[1](date)) f = formats[--i];
       
  9225     return f[0](date);
       
  9226   };
       
  9227 }
       
  9228 
       
  9229 function d3_time_scaleSetYear(y) {
       
  9230   var d = new Date(y, 0, 1);
       
  9231   d.setFullYear(y); // Y2K fail
       
  9232   return d;
       
  9233 }
       
  9234 
       
  9235 function d3_time_scaleGetYear(d) {
       
  9236   var y = d.getFullYear(),
       
  9237       d0 = d3_time_scaleSetYear(y),
       
  9238       d1 = d3_time_scaleSetYear(y + 1);
       
  9239   return y + (d - d0) / (d1 - d0);
       
  9240 }
       
  9241 
       
  9242 var d3_time_scaleSteps = [
       
  9243   1e3,    // 1-second
       
  9244   5e3,    // 5-second
       
  9245   15e3,   // 15-second
       
  9246   3e4,    // 30-second
       
  9247   6e4,    // 1-minute
       
  9248   3e5,    // 5-minute
       
  9249   9e5,    // 15-minute
       
  9250   18e5,   // 30-minute
       
  9251   36e5,   // 1-hour
       
  9252   108e5,  // 3-hour
       
  9253   216e5,  // 6-hour
       
  9254   432e5,  // 12-hour
       
  9255   864e5,  // 1-day
       
  9256   1728e5, // 2-day
       
  9257   6048e5, // 1-week
       
  9258   2592e6, // 1-month
       
  9259   7776e6, // 3-month
       
  9260   31536e6 // 1-year
       
  9261 ];
       
  9262 
       
  9263 var d3_time_scaleLocalMethods = [
       
  9264   [d3.time.second, 1],
       
  9265   [d3.time.second, 5],
       
  9266   [d3.time.second, 15],
       
  9267   [d3.time.second, 30],
       
  9268   [d3.time.minute, 1],
       
  9269   [d3.time.minute, 5],
       
  9270   [d3.time.minute, 15],
       
  9271   [d3.time.minute, 30],
       
  9272   [d3.time.hour, 1],
       
  9273   [d3.time.hour, 3],
       
  9274   [d3.time.hour, 6],
       
  9275   [d3.time.hour, 12],
       
  9276   [d3.time.day, 1],
       
  9277   [d3.time.day, 2],
       
  9278   [d3.time.week, 1],
       
  9279   [d3.time.month, 1],
       
  9280   [d3.time.month, 3],
       
  9281   [d3.time.year, 1]
       
  9282 ];
       
  9283 
       
  9284 var d3_time_scaleLocalFormats = [
       
  9285   [d3.time.format("%Y"), function(d) { return true; }],
       
  9286   [d3.time.format("%B"), function(d) { return d.getMonth(); }],
       
  9287   [d3.time.format("%b %d"), function(d) { return d.getDate() != 1; }],
       
  9288   [d3.time.format("%a %d"), function(d) { return d.getDay() && d.getDate() != 1; }],
       
  9289   [d3.time.format("%I %p"), function(d) { return d.getHours(); }],
       
  9290   [d3.time.format("%I:%M"), function(d) { return d.getMinutes(); }],
       
  9291   [d3.time.format(":%S"), function(d) { return d.getSeconds(); }],
       
  9292   [d3.time.format(".%L"), function(d) { return d.getMilliseconds(); }]
       
  9293 ];
       
  9294 
       
  9295 var d3_time_scaleLinear = d3.scale.linear(),
       
  9296     d3_time_scaleLocalFormat = d3_time_scaleFormat(d3_time_scaleLocalFormats);
       
  9297 
       
  9298 d3_time_scaleLocalMethods.year = function(extent, m) {
       
  9299   return d3_time_scaleLinear.domain(extent.map(d3_time_scaleGetYear)).ticks(m).map(d3_time_scaleSetYear);
       
  9300 };
       
  9301 
       
  9302 d3.time.scale = function() {
       
  9303   return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat);
       
  9304 };
       
  9305 var d3_time_scaleUTCMethods = d3_time_scaleLocalMethods.map(function(m) {
       
  9306   return [m[0].utc, m[1]];
       
  9307 });
       
  9308 
       
  9309 var d3_time_scaleUTCFormats = [
       
  9310   [d3.time.format.utc("%Y"), function(d) { return true; }],
       
  9311   [d3.time.format.utc("%B"), function(d) { return d.getUTCMonth(); }],
       
  9312   [d3.time.format.utc("%b %d"), function(d) { return d.getUTCDate() != 1; }],
       
  9313   [d3.time.format.utc("%a %d"), function(d) { return d.getUTCDay() && d.getUTCDate() != 1; }],
       
  9314   [d3.time.format.utc("%I %p"), function(d) { return d.getUTCHours(); }],
       
  9315   [d3.time.format.utc("%I:%M"), function(d) { return d.getUTCMinutes(); }],
       
  9316   [d3.time.format.utc(":%S"), function(d) { return d.getUTCSeconds(); }],
       
  9317   [d3.time.format.utc(".%L"), function(d) { return d.getUTCMilliseconds(); }]
       
  9318 ];
       
  9319 
       
  9320 var d3_time_scaleUTCFormat = d3_time_scaleFormat(d3_time_scaleUTCFormats);
       
  9321 
       
  9322 function d3_time_scaleUTCSetYear(y) {
       
  9323   var d = new Date(Date.UTC(y, 0, 1));
       
  9324   d.setUTCFullYear(y); // Y2K fail
       
  9325   return d;
       
  9326 }
       
  9327 
       
  9328 function d3_time_scaleUTCGetYear(d) {
       
  9329   var y = d.getUTCFullYear(),
       
  9330       d0 = d3_time_scaleUTCSetYear(y),
       
  9331       d1 = d3_time_scaleUTCSetYear(y + 1);
       
  9332   return y + (d - d0) / (d1 - d0);
       
  9333 }
       
  9334 
       
  9335 d3_time_scaleUTCMethods.year = function(extent, m) {
       
  9336   return d3_time_scaleLinear.domain(extent.map(d3_time_scaleUTCGetYear)).ticks(m).map(d3_time_scaleUTCSetYear);
       
  9337 };
       
  9338 
       
  9339 d3.time.scale.utc = function() {
       
  9340   return d3_time_scale(d3.scale.linear(), d3_time_scaleUTCMethods, d3_time_scaleUTCFormat);
       
  9341 };
       
  9342 })();