text: (function(){d3.geo = {};
  
      var d3_geo_radians = Math.PI / 180;
  // TODO clip input coordinates on opposite hemisphere
      d3.geo.azimuthal = function() {
          var mode = "orthographic", // or stereographic, gnomonic, equidistant or equalarea
              origin,
              scale = 200,
              translate = [480, 250],
              x0,
              y0,
              cy0,
              sy0;
  
          function azimuthal(coordinates) {
              var x1 = coordinates[0] * d3_geo_radians - x0,
                  y1 = coordinates[1] * d3_geo_radians,
                  cx1 = Math.cos(x1),
                  sx1 = Math.sin(x1),
                  cy1 = Math.cos(y1),
                  sy1 = Math.sin(y1),
                  cc = mode !== "orthographic" ? sy0 * sy1 + cy0 * cy1 * cx1 : null,
                  c,
                  k = mode === "stereographic" ? 1 / (1 + cc)
                      : mode === "gnomonic" ? 1 / cc
                          : mode === "equidistant" ? (c = Math.acos(cc), c ? c / Math.sin(c) : 0)
                              : mode === "equalarea" ? Math.sqrt(2 / (1 + cc))
                                  : 1,
                  x = k * cy1 * sx1,
                  y = k * (sy0 * cy1 * cx1 - cy0 * sy1);
              return [
                  scale * x + translate[0],
                  scale * y + translate[1]
              ];
          }
  
          azimuthal.invert = function(coordinates) {
              var x = (coordinates[0] - translate[0]) / scale,
                  y = (coordinates[1] - translate[1]) / scale,
                  p = Math.sqrt(x * x + y * y),
                  c = mode === "stereographic" ? 2 * Math.atan(p)
                      : mode === "gnomonic" ? Math.atan(p)
                          : mode === "equidistant" ? p
                              : mode === "equalarea" ? 2 * Math.asin(.5 * p)
                                  : Math.asin(p),
                  sc = Math.sin(c),
                  cc = Math.cos(c);
              return [
                  (x0 + Math.atan2(x * sc, p * cy0 * cc + y * sy0 * sc)) / d3_geo_radians,
                  Math.asin(cc * sy0 - (p ? (y * sc * cy0) / p : 0)) / d3_geo_radians
              ];
          };
  
          azimuthal.mode = function(x) {
              if (!arguments.length) return mode;
              mode = x + "";
              return azimuthal;
          };
  
          azimuthal.origin = function(x) {
              if (!arguments.length) return origin;
              origin = x;
              x0 = origin[0] * d3_geo_radians;
              y0 = origin[1] * d3_geo_radians;
              cy0 = Math.cos(y0);
              sy0 = Math.sin(y0);
              return azimuthal;
          };
  
          azimuthal.scale = function(x) {
              if (!arguments.length) return scale;
              scale = +x;
              return azimuthal;
          };
  
          azimuthal.translate = function(x) {
              if (!arguments.length) return translate;
              translate = [+x[0], +x[1]];
              return azimuthal;
          };
  
          return azimuthal.origin([0, 0]);
      };
  // Derived from Tom Carden's Albers implementation for Protovis.
  // http://gist.github.com/476238
  // http://mathworld.wolfram.com/AlbersEqual-AreaConicProjection.html
  
      d3.geo.albers = function() {
          var origin = [-98, 38],
              parallels = [29.5, 45.5],
              scale = 1000,
              translate = [480, 250],
              lng0, // d3_geo_radians * origin[0]
              n,
              C,
              p0;
  
          function albers(coordinates) {
              var t = n * (d3_geo_radians * coordinates[0] - lng0),
                  p = Math.sqrt(C - 2 * n * Math.sin(d3_geo_radians * coordinates[1])) / n;
              return [
                  scale * p * Math.sin(t) + translate[0],
                  scale * (p * Math.cos(t) - p0) + translate[1]
              ];
          }
  
          albers.invert = function(coordinates) {
              var x = (coordinates[0] - translate[0]) / scale,
                  y = (coordinates[1] - translate[1]) / scale,
                  p0y = p0 + y,
                  t = Math.atan2(x, p0y),
                  p = Math.sqrt(x * x + p0y * p0y);
              return [
                  (lng0 + t / n) / d3_geo_radians,
                  Math.asin((C - p * p * n * n) / (2 * n)) / d3_geo_radians
              ];
          };
  
          function reload() {
              var phi1 = d3_geo_radians * parallels[0],
                  phi2 = d3_geo_radians * parallels[1],
                  lat0 = d3_geo_radians * origin[1],
                  s = Math.sin(phi1),
                  c = Math.cos(phi1);
              lng0 = d3_geo_radians * origin[0];
              n = .5 * (s + Math.sin(phi2));
              C = c * c + 2 * n * s;
              p0 = Math.sqrt(C - 2 * n * Math.sin(lat0)) / n;
              return albers;
          }
  
          albers.origin = function(x) {
              if (!arguments.length) return origin;
              origin = [+x[0], +x[1]];
              return reload();
          };
  
          albers.parallels = function(x) {
              if (!arguments.length) return parallels;
              parallels = [+x[0], +x[1]];
              return reload();
          };
  
          albers.scale = function(x) {
              if (!arguments.length) return scale;
              scale = +x;
              return albers;
          };
  
          albers.translate = function(x) {
              if (!arguments.length) return translate;
              translate = [+x[0], +x[1]];
              return albers;
          };
  
          return reload();
      };
  
  // A composite projection for the United States, 960x500. The set of standard
  // parallels for each region comes from USGS, which is published here:
  // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
  // TODO allow the composite projection to be rescaled?
      d3.geo.albersUsa = function() {
          var lower48 = d3.geo.albers();
  
          var alaska = d3.geo.albers()
              .origin([-160, 60])
              .parallels([55, 65]);
  
          var hawaii = d3.geo.albers()
              .origin([-160, 20])
              .parallels([8, 18]);
  
          var puertoRico = d3.geo.albers()
              .origin([-60, 10])
              .parallels([8, 18]);
  
          function albersUsa(coordinates) {
              var lon = coordinates[0],
                  lat = coordinates[1];
              return (lat > 50 ? alaska
                  : lon < -140 ? hawaii
                      : lat < 21 ? puertoRico
                          : lower48)(coordinates);
          }
  
          albersUsa.scale = function(x) {
              if (!arguments.length) return lower48.scale();
              lower48.scale(x);
              alaska.scale(x * .6);
              hawaii.scale(x);
              puertoRico.scale(x * 1.5);
              return albersUsa.translate(lower48.translate());
          };
  
          albersUsa.translate = function(x) {
              if (!arguments.length) return lower48.translate();
              var dz = lower48.scale() / 1000,
                  dx = x[0],
                  dy = x[1];
              lower48.translate(x);
              alaska.translate([dx - 400 * dz, dy + 170 * dz]);
              hawaii.translate([dx - 190 * dz, dy + 200 * dz]);
              puertoRico.translate([dx + 580 * dz, dy + 430 * dz]);
              return albersUsa;
          };
  
          return albersUsa.scale(lower48.scale());
      };
      d3.geo.bonne = function() {
          var scale = 200,
              translate = [480, 250],
              x0, // origin longitude in radians
              y0, // origin latitude in radians
              y1, // parallel latitude in radians
              c1; // cot(y1)
  
          function bonne(coordinates) {
              var x = coordinates[0] * d3_geo_radians - x0,
                  y = coordinates[1] * d3_geo_radians - y0;
              if (y1) {
                  var p = c1 + y1 - y, E = x * Math.cos(y) / p;
                  x = p * Math.sin(E);
                  y = p * Math.cos(E) - c1;
              } else {
                  x *= Math.cos(y);
                  y *= -1;
              }
              return [
                  scale * x + translate[0],
                  scale * y + translate[1]
              ];
          }
  
          bonne.invert = function(coordinates) {
              var x = (coordinates[0] - translate[0]) / scale,
                  y = (coordinates[1] - translate[1]) / scale;
              if (y1) {
                  var c = c1 + y, p = Math.sqrt(x * x + c * c);
                  y = c1 + y1 - p;
                  x = x0 + p * Math.atan2(x, c) / Math.cos(y);
              } else {
                  y *= -1;
                  x /= Math.cos(y);
              }
              return [
                  x / d3_geo_radians,
                  y / d3_geo_radians
              ];
          };
  
          // 90° for Werner, 0° for Sinusoidal
          bonne.parallel = function(x) {
              if (!arguments.length) return y1 / d3_geo_radians;
              c1 = 1 / Math.tan(y1 = x * d3_geo_radians);
              return bonne;
          };
  
          bonne.origin = function(x) {
              if (!arguments.length) return [x0 / d3_geo_radians, y0 / d3_geo_radians];
              x0 = x[0] * d3_geo_radians;
              y0 = x[1] * d3_geo_radians;
              return bonne;
          };
  
          bonne.scale = function(x) {
              if (!arguments.length) return scale;
              scale = +x;
              return bonne;
          };
  
          bonne.translate = function(x) {
              if (!arguments.length) return translate;
              translate = [+x[0], +x[1]];
              return bonne;
          };
  
          return bonne.origin([0, 0]).parallel(45);
      };
      d3.geo.equirectangular = function() {
          var scale = 500,
              translate = [480, 250];
  
          function equirectangular(coordinates) {
              var x = coordinates[0] / 360,
                  y = -coordinates[1] / 360;
              return [
                  scale * x + translate[0],
                  scale * y + translate[1]
              ];
          }
  
          equirectangular.invert = function(coordinates) {
              var x = (coordinates[0] - translate[0]) / scale,
                  y = (coordinates[1] - translate[1]) / scale;
              return [
                  360 * x,
                  -360 * y
              ];
          };
  
          equirectangular.scale = function(x) {
              if (!arguments.length) return scale;
              scale = +x;
              return equirectangular;
          };
  
          equirectangular.translate = function(x) {
              if (!arguments.length) return translate;
              translate = [+x[0], +x[1]];
              return equirectangular;
          };
  
          return equirectangular;
      };
      d3.geo.mercator = function() {
          var scale = 500,
              translate = [480, 250];
  
          function mercator(coordinates) {
              var x = coordinates[0] / 360,
                  y = -(Math.log(Math.tan(Math.PI / 4 + coordinates[1] * d3_geo_radians / 2)) / d3_geo_radians) / 360;
              return [
                  scale * x + translate[0],
                  scale * Math.max(-.5, Math.min(.5, y)) + translate[1]
              ];
          }
  
          mercator.invert = function(coordinates) {
              var x = (coordinates[0] - translate[0]) / scale,
                  y = (coordinates[1] - translate[1]) / scale;
              return [
                  360 * x,
                  2 * Math.atan(Math.exp(-360 * y * d3_geo_radians)) / d3_geo_radians - 90
              ];
          };
  
          mercator.scale = function(x) {
              if (!arguments.length) return scale;
              scale = +x;
              return mercator;
          };
  
          mercator.translate = function(x) {
              if (!arguments.length) return translate;
              translate = [+x[0], +x[1]];
              return mercator;
          };
  
          return mercator;
      };
      function d3_geo_type(types, defaultValue) {
          return function(object) {
              return object && object.type in types ? types[object.type](object) : defaultValue;
          };
      }
      /**
       * Returns a function that, given a GeoJSON object (e.g., a feature), returns
       * the corresponding SVG path. The function can be customized by overriding the
       * projection. Point features are mapped to circles with a default radius of
       * 4.5px; the radius can be specified either as a constant or a function that
       * is evaluated per object.
       */
      d3.geo.path = function() {
          var pointRadius = 4.5,
              pointCircle = d3_path_circle(pointRadius),
              projection = d3.geo.albersUsa();
  
          function path(d, i) {
              if (typeof pointRadius === "function") {
                  pointCircle = d3_path_circle(pointRadius.apply(this, arguments));
              }
              return pathType(d) || null;
          }
  
          function project(coordinates) {
              return projection(coordinates).join(",");
          }
  
          var pathType = d3_geo_type({
  
              FeatureCollection: function(o) {
                  var path = [],
                      features = o.features,
                      i = -1, // features.index
                      n = features.length;
                  while (++i < n) path.push(pathType(features[i].geometry));
                  return path.join("");
              },
  
              Feature: function(o) {
                  return pathType(o.geometry);
              },
  
              Point: function(o) {
                  return "M" + project(o.coordinates) + pointCircle;
              },
  
              MultiPoint: function(o) {
                  var path = [],
                      coordinates = o.coordinates,
                      i = -1, // coordinates.index
                      n = coordinates.length;
                  while (++i < n) path.push("M", project(coordinates[i]), pointCircle);
                  return path.join("");
              },
  
              LineString: function(o) {
                  var path = ["M"],
                      coordinates = o.coordinates,
                      i = -1, // coordinates.index
                      n = coordinates.length;
                  while (++i < n) path.push(project(coordinates[i]), "L");
                  path.pop();
                  return path.join("");
              },
  
              MultiLineString: function(o) {
                  var path = [],
                      coordinates = o.coordinates,
                      i = -1, // coordinates.index
                      n = coordinates.length,
                      subcoordinates, // coordinates[i]
                      j, // subcoordinates.index
                      m; // subcoordinates.length
                  while (++i < n) {
                      subcoordinates = coordinates[i];
                      j = -1;
                      m = subcoordinates.length;
                      path.push("M");
                      while (++j < m) path.push(project(subcoordinates[j]), "L");
                      path.pop();
                  }
                  return path.join("");
              },
  
              Polygon: function(o) {
                  var path = [],
                      coordinates = o.coordinates,
                      i = -1, // coordinates.index
                      n = coordinates.length,
                      subcoordinates, // coordinates[i]
                      j, // subcoordinates.index
                      m; // subcoordinates.length
                  while (++i < n) {
                      subcoordinates = coordinates[i];
                      j = -1;
                      if ((m = subcoordinates.length - 1) > 0) {
                          path.push("M");
                          while (++j < m) path.push(project(subcoordinates[j]), "L");
                          path[path.length - 1] = "Z";
                      }
                  }
                  return path.join("");
              },
  
              MultiPolygon: function(o) {
                  var path = [],
                      coordinates = o.coordinates,
                      i = -1, // coordinates index
                      n = coordinates.length,
                      subcoordinates, // coordinates[i]
                      j, // subcoordinates index
                      m, // subcoordinates.length
                      subsubcoordinates, // subcoordinates[j]
                      k, // subsubcoordinates index
                      p; // subsubcoordinates.length
                  while (++i < n) {
                      subcoordinates = coordinates[i];
                      j = -1;
                      m = subcoordinates.length;
                      while (++j < m) {
                          subsubcoordinates = subcoordinates[j];
                          k = -1;
                          if ((p = subsubcoordinates.length - 1) > 0) {
                              path.push("M");
                              while (++k < p) path.push(project(subsubcoordinates[k]), "L");
                              path[path.length - 1] = "Z";
                          }
                      }
                  }
                  return path.join("");
              },
  
              GeometryCollection: function(o) {
                  var path = [],
                      geometries = o.geometries,
                      i = -1, // geometries index
                      n = geometries.length;
                  while (++i < n) path.push(pathType(geometries[i]));
                  return path.join("");
              }
  
          });
  
          var areaType = path.area = d3_geo_type({
  
              FeatureCollection: function(o) {
                  var area = 0,
                      features = o.features,
                      i = -1, // features.index
                      n = features.length;
                  while (++i < n) area += areaType(features[i]);
                  return area;
              },
  
              Feature: function(o) {
                  return areaType(o.geometry);
              },
  
              Polygon: function(o) {
                  return polygonArea(o.coordinates);
              },
  
              MultiPolygon: function(o) {
                  var sum = 0,
                      coordinates = o.coordinates,
                      i = -1, // coordinates index
                      n = coordinates.length;
                  while (++i < n) sum += polygonArea(coordinates[i]);
                  return sum;
              },
  
              GeometryCollection: function(o) {
                  var sum = 0,
                      geometries = o.geometries,
                      i = -1, // geometries index
                      n = geometries.length;
                  while (++i < n) sum += areaType(geometries[i]);
                  return sum;
              }
  
          }, 0);
  
          function polygonArea(coordinates) {
              var sum = area(coordinates[0]), // exterior ring
                  i = 0, // coordinates.index
                  n = coordinates.length;
              while (++i < n) sum -= area(coordinates[i]); // holes
              return sum;
          }
  
          function polygonCentroid(coordinates) {
              var polygon = d3.geom.polygon(coordinates[0].map(projection)), // exterior ring
                  area = polygon.area(),
                  centroid = polygon.centroid(area < 0 ? (area *= -1, 1) : -1),
                  x = centroid[0],
                  y = centroid[1],
                  z = area,
                  i = 0, // coordinates index
                  n = coordinates.length;
              while (++i < n) {
                  polygon = d3.geom.polygon(coordinates[i].map(projection)); // holes
                  area = polygon.area();
                  centroid = polygon.centroid(area < 0 ? (area *= -1, 1) : -1);
                  x -= centroid[0];
                  y -= centroid[1];
                  z -= area;
              }
              return [x, y, 6 * z]; // weighted centroid
          }
  
          var centroidType = path.centroid = d3_geo_type({
  
              // TODO FeatureCollection
              // TODO Point
              // TODO MultiPoint
              // TODO LineString
              // TODO MultiLineString
              // TODO GeometryCollection
  
              Feature: function(o) {
                  return centroidType(o.geometry);
              },
  
              Polygon: function(o) {
                  var centroid = polygonCentroid(o.coordinates);
                  return [centroid[0] / centroid[2], centroid[1] / centroid[2]];
              },
  
              MultiPolygon: function(o) {
                  var area = 0,
                      coordinates = o.coordinates,
                      centroid,
                      x = 0,
                      y = 0,
                      z = 0,
                      i = -1, // coordinates index
                      n = coordinates.length;
                  while (++i < n) {
                      centroid = polygonCentroid(coordinates[i]);
                      x += centroid[0];
                      y += centroid[1];
                      z += centroid[2];
                  }
                  return [x / z, y / z];
              }
  
          });
  
          function area(coordinates) {
              return Math.abs(d3.geom.polygon(coordinates.map(projection)).area());
          }
  
          path.projection = function(x) {
              projection = x;
              return path;
          };
  
          path.pointRadius = function(x) {
              if (typeof x === "function") pointRadius = x;
              else {
                  pointRadius = +x;
                  pointCircle = d3_path_circle(pointRadius);
              }
              return path;
          };
  
          return path;
      };
  
      function d3_path_circle(radius) {
          return "m0," + radius
              + "a" + radius + "," + radius + " 0 1,1 0," + (-2 * radius)
              + "a" + radius + "," + radius + " 0 1,1 0," + (+2 * radius)
              + "z";
      }
      /**
       * Given a GeoJSON object, returns the corresponding bounding box. The bounding
       * box is represented by a two-dimensional array: [[left, bottom], [right,
       * top]], where left is the minimum longitude, bottom is the minimum latitude,
       * right is maximum longitude, and top is the maximum latitude.
       */
      d3.geo.bounds = function(feature) {
          var left = Infinity,
              bottom = Infinity,
              right = -Infinity,
              top = -Infinity;
          d3_geo_bounds(feature, function(x, y) {
              if (x < left) left = x;
              if (x > right) right = x;
              if (y < bottom) bottom = y;
              if (y > top) top = y;
          });
          return [[left, bottom], [right, top]];
      };
  
      function d3_geo_bounds(o, f) {
          if (o.type in d3_geo_boundsTypes) d3_geo_boundsTypes[o.type](o, f);
      }
  
      var d3_geo_boundsTypes = {
          Feature: d3_geo_boundsFeature,
          FeatureCollection: d3_geo_boundsFeatureCollection,
          LineString: d3_geo_boundsLineString,
          MultiLineString: d3_geo_boundsMultiLineString,
          MultiPoint: d3_geo_boundsLineString,
          MultiPolygon: d3_geo_boundsMultiPolygon,
          Point: d3_geo_boundsPoint,
          Polygon: d3_geo_boundsPolygon
      };
  
      function d3_geo_boundsFeature(o, f) {
          d3_geo_bounds(o.geometry, f);
      }
  
      function d3_geo_boundsFeatureCollection(o, f) {
          for (var a = o.features, i = 0, n = a.length; i < n; i++) {
              d3_geo_bounds(a[i].geometry, f);
          }
      }
  
      function d3_geo_boundsLineString(o, f) {
          for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
              f.apply(null, a[i]);
          }
      }
  
      function d3_geo_boundsMultiLineString(o, f) {
          for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
              for (var b = a[i], j = 0, m = b.length; j < m; j++) {
                  f.apply(null, b[j]);
              }
          }
      }
  
      function d3_geo_boundsMultiPolygon(o, f) {
          for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
              for (var b = a[i][0], j = 0, m = b.length; j < m; j++) {
                  f.apply(null, b[j]);
              }
          }
      }
  
      function d3_geo_boundsPoint(o, f) {
          f.apply(null, o.coordinates);
      }
  
      function d3_geo_boundsPolygon(o, f) {
          for (var a = o.coordinates[0], i = 0, n = a.length; i < n; i++) {
              f.apply(null, a[i]);
          }
      }
  // TODO breakAtDateLine?
  
      d3.geo.circle = function() {
          var origin = [0, 0],
              degrees = 90 - 1e-2,
              radians = degrees * d3_geo_radians,
              arc = d3.geo.greatArc().target(Object);
  
          function circle() {
              // TODO render a circle as a Polygon
          }
  
          function visible(point) {
              return arc.distance(point) < radians;
          }
  
          circle.clip = function(d) {
              arc.source(typeof origin === "function" ? origin.apply(this, arguments) : origin);
              return clipType(d);
          };
  
          var clipType = d3_geo_type({
  
              FeatureCollection: function(o) {
                  var features = o.features.map(clipType).filter(Object);
                  return features && (o = Object.create(o), o.features = features, o);
              },
  
              Feature: function(o) {
                  var geometry = clipType(o.geometry);
                  return geometry && (o = Object.create(o), o.geometry = geometry, o);
              },
  
              Point: function(o) {
                  return visible(o.coordinates) && o;
              },
  
              MultiPoint: function(o) {
                  var coordinates = o.coordinates.filter(visible);
                  return coordinates.length && {
                          type: o.type,
                          coordinates: coordinates
                      };
              },
  
              LineString: function(o) {
                  var coordinates = clip(o.coordinates);
                  return coordinates.length && (o = Object.create(o), o.coordinates = coordinates, o);
              },
  
              MultiLineString: function(o) {
                  var coordinates = o.coordinates.map(clip).filter(function(d) { return d.length; });
                  return coordinates.length && (o = Object.create(o), o.coordinates = coordinates, o);
              },
  
              Polygon: function(o) {
                  var coordinates = o.coordinates.map(clip);
                  return coordinates[0].length && (o = Object.create(o), o.coordinates = coordinates, o);
              },
  
              MultiPolygon: function(o) {
                  var coordinates = o.coordinates.map(function(d) { return d.map(clip); }).filter(function(d) { return d[0].length; });
                  return coordinates.length && (o = Object.create(o), o.coordinates = coordinates, o);
              },
  
              GeometryCollection: function(o) {
                  var geometries = o.geometries.map(clipType).filter(Object);
                  return geometries.length && (o = Object.create(o), o.geometries = geometries, o);
              }
  
          });
  
          function clip(coordinates) {
              var i = -1,
                  n = coordinates.length,
                  clipped = [],
                  p0,
                  p1,
                  p2,
                  d0,
                  d1;
  
              while (++i < n) {
                  d1 = arc.distance(p2 = coordinates[i]);
                  if (d1 < radians) {
                      if (p1) clipped.push(d3_geo_greatArcInterpolate(p1, p2)((d0 - radians) / (d0 - d1)));
                      clipped.push(p2);
                      p0 = p1 = null;
                  } else {
                      p1 = p2;
                      if (!p0 && clipped.length) {
                          clipped.push(d3_geo_greatArcInterpolate(clipped[clipped.length - 1], p1)((radians - d0) / (d1 - d0)));
                          p0 = p1;
                      }
                  }
                  d0 = d1;
              }
  
              if (p1 && clipped.length) {
                  d1 = arc.distance(p2 = clipped[0]);
                  clipped.push(d3_geo_greatArcInterpolate(p1, p2)((d0 - radians) / (d0 - d1)));
              }
  
              return resample(clipped);
          }
  
          // Resample coordinates, creating great arcs between each.
          function resample(coordinates) {
              var i = 0,
                  n = coordinates.length,
                  j,
                  m,
                  resampled = n ? [coordinates[0]] : coordinates,
                  resamples,
                  origin = arc.source();
  
              while (++i < n) {
                  resamples = arc.source(coordinates[i - 1])(coordinates[i]).coordinates;
                  for (j = 0, m = resamples.length; ++j < m;) resampled.push(resamples[j]);
              }
  
              arc.source(origin);
              return resampled;
          }
  
          circle.origin = function(x) {
              if (!arguments.length) return origin;
              origin = x;
              return circle;
          };
  
          circle.angle = function(x) {
              if (!arguments.length) return degrees;
              radians = (degrees = +x) * d3_geo_radians;
              return circle;
          };
  
          // Precision is specified in degrees.
          circle.precision = function(x) {
              if (!arguments.length) return arc.precision();
              arc.precision(x);
              return circle;
          };
  
          return circle;
      }
      d3.geo.greatArc = function() {
          var source = d3_geo_greatArcSource,
              target = d3_geo_greatArcTarget,
              precision = 6 * d3_geo_radians;
  
          function greatArc() {
              var a = typeof source === "function" ? source.apply(this, arguments) : source,
                  b = typeof target === "function" ? target.apply(this, arguments) : target,
                  i = d3_geo_greatArcInterpolate(a, b),
                  dt = precision / i.d,
                  t = 0,
                  coordinates = [a];
              while ((t += dt) < 1) coordinates.push(i(t));
              coordinates.push(b);
              return {
                  type: "LineString",
                  coordinates: coordinates
              };
          }
  
          // Length returned in radians; multiply by radius for distance.
          greatArc.distance = function() {
              var a = typeof source === "function" ? source.apply(this, arguments) : source,
                  b = typeof target === "function" ? target.apply(this, arguments) : target;
              return d3_geo_greatArcInterpolate(a, b).d;
          };
  
          greatArc.source = function(x) {
              if (!arguments.length) return source;
              source = x;
              return greatArc;
          };
  
          greatArc.target = function(x) {
              if (!arguments.length) return target;
              target = x;
              return greatArc;
          };
  
          // Precision is specified in degrees.
          greatArc.precision = function(x) {
              if (!arguments.length) return precision / d3_geo_radians;
              precision = x * d3_geo_radians;
              return greatArc;
          };
  
          return greatArc;
      };
  
      function d3_geo_greatArcSource(d) {
          return d.source;
      }
  
      function d3_geo_greatArcTarget(d) {
          return d.target;
      }
  
      function d3_geo_greatArcInterpolate(a, b) {
          var x0 = a[0] * d3_geo_radians, cx0 = Math.cos(x0), sx0 = Math.sin(x0),
              y0 = a[1] * d3_geo_radians, cy0 = Math.cos(y0), sy0 = Math.sin(y0),
              x1 = b[0] * d3_geo_radians, cx1 = Math.cos(x1), sx1 = Math.sin(x1),
              y1 = b[1] * d3_geo_radians, cy1 = Math.cos(y1), sy1 = Math.sin(y1),
              d = interpolate.d = Math.acos(Math.max(-1, Math.min(1, sy0 * sy1 + cy0 * cy1 * Math.cos(x1 - x0)))),
              sd = Math.sin(d);
  
          // From http://williams.best.vwh.net/avform.htm#Intermediate
          function interpolate(t) {
              var A = Math.sin(d - (t *= d)) / sd,
                  B = Math.sin(t) / sd,
                  x = A * cy0 * cx0 + B * cy1 * cx1,
                  y = A * cy0 * sx0 + B * cy1 * sx1,
                  z = A * sy0       + B * sy1;
              return [
                  Math.atan2(y, x) / d3_geo_radians,
                  Math.atan2(z, Math.sqrt(x * x + y * y)) / d3_geo_radians
              ];
          }
  
          return interpolate;
      }
      d3.geo.greatCircle = d3.geo.circle;
  })();
  