text: !function() {
    var topojson = {
      version: "1.6.4",
      mesh: function(topology) { return object(topology, meshArcs.apply(this, arguments)); },
      meshArcs: meshArcs,
      merge: function(topology) { return object(topology, mergeArcs.apply(this, arguments)); },
      mergeArcs: mergeArcs,
      feature: featureOrCollection,
      neighbors: neighbors,
      presimplify: presimplify
    };
  
    function stitchArcs(topology, arcs) {
      var stitchedArcs = {},
          fragmentByStart = {},
          fragmentByEnd = {},
          fragments = [],
          emptyIndex = -1;
  
      // Stitch empty arcs first, since they may be subsumed by other arcs.
      arcs.forEach(function(i, j) {
        var arc = topology.arcs[i < 0 ? ~i : i], t;
        if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {
          t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;
        }
      });
  
      arcs.forEach(function(i) {
        var e = ends(i),
            start = e[0],
            end = e[1],
            f, g;
  
        if (f = fragmentByEnd[start]) {
          delete fragmentByEnd[f.end];
          f.push(i);
          f.end = end;
          if (g = fragmentByStart[end]) {
            delete fragmentByStart[g.start];
            var fg = g === f ? f : f.concat(g);
            fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;
          } else {
            fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
          }
        } else if (f = fragmentByStart[end]) {
          delete fragmentByStart[f.start];
          f.unshift(i);
          f.start = start;
          if (g = fragmentByEnd[start]) {
            delete fragmentByEnd[g.end];
            var gf = g === f ? f : g.concat(f);
            fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;
          } else {
            fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
          }
        } else {
          f = [i];
          fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;
        }
      });
  
      function ends(i) {
        var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;
        if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });
        else p1 = arc[arc.length - 1];
        return i < 0 ? [p1, p0] : [p0, p1];
      }
  
      function flush(fragmentByEnd, fragmentByStart) {
        for (var k in fragmentByEnd) {
          var f = fragmentByEnd[k];
          delete fragmentByStart[f.start];
          delete f.start;
          delete f.end;
          f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });
          fragments.push(f);
        }
      }
  
      flush(fragmentByEnd, fragmentByStart);
      flush(fragmentByStart, fragmentByEnd);
      arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });
  
      return fragments;
    }
  
    function meshArcs(topology, o, filter) {
      var arcs = [];
  
      if (arguments.length > 1) {
        var geomsByArc = [],
            geom;
  
        function arc(i) {
          var j = i < 0 ? ~i : i;
          (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});
        }
  
        function line(arcs) {
          arcs.forEach(arc);
        }
  
        function polygon(arcs) {
          arcs.forEach(line);
        }
  
        function geometry(o) {
          if (o.type === "GeometryCollection") o.geometries.forEach(geometry);
          else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs);
        }
  
        var geometryType = {
          LineString: line,
          MultiLineString: polygon,
          Polygon: polygon,
          MultiPolygon: function(arcs) { arcs.forEach(polygon); }
        };
  
        geometry(o);
  
        geomsByArc.forEach(arguments.length < 3
            ? function(geoms) { arcs.push(geoms[0].i); }
            : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });
      } else {
        for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i);
      }
  
      return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)};
    }
  
    function mergeArcs(topology, objects) {
      var polygonsByArc = {},
          polygons = [],
          components = [];
  
      objects.forEach(function(o) {
        if (o.type === "Polygon") register(o.arcs);
        else if (o.type === "MultiPolygon") o.arcs.forEach(register);
      });
  
      function register(polygon) {
        polygon.forEach(function(ring) {
          ring.forEach(function(arc) {
            (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);
          });
        });
        polygons.push(polygon);
      }
  
      function exterior(ring) {
        return cartesianRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]) > 0; // TODO allow spherical?
      }
  
      polygons.forEach(function(polygon) {
        if (!polygon._) {
          var component = [],
              neighbors = [polygon];
          polygon._ = 1;
          components.push(component);
          while (polygon = neighbors.pop()) {
            component.push(polygon);
            polygon.forEach(function(ring) {
              ring.forEach(function(arc) {
                polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {
                  if (!polygon._) {
                    polygon._ = 1;
                    neighbors.push(polygon);
                  }
                });
              });
            });
          }
        }
      });
  
      polygons.forEach(function(polygon) {
        delete polygon._;
      });
  
      return {
        type: "MultiPolygon",
        arcs: components.map(function(polygons) {
          var arcs = [];
  
          // Extract the exterior (unique) arcs.
          polygons.forEach(function(polygon) {
            polygon.forEach(function(ring) {
              ring.forEach(function(arc) {
                if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {
                  arcs.push(arc);
                }
              });
            });
          });
  
          // Stitch the arcs into one or more rings.
          arcs = stitchArcs(topology, arcs);
  
          // If more than one ring is returned,
          // at most one of these rings can be the exterior;
          // this exterior ring has the same winding order
          // as any exterior ring in the original polygons.
          if ((n = arcs.length) > 1) {
            var sgn = exterior(polygons[0][0]);
            for (var i = 0, t; i < n; ++i) {
              if (sgn === exterior(arcs[i])) {
                t = arcs[0], arcs[0] = arcs[i], arcs[i] = t;
                break;
              }
            }
          }
  
          return arcs;
        })
      };
    }
  
    function featureOrCollection(topology, o) {
      return o.type === "GeometryCollection" ? {
        type: "FeatureCollection",
        features: o.geometries.map(function(o) { return feature(topology, o); })
      } : feature(topology, o);
    }
  
    function feature(topology, o) {
      var f = {
        type: "Feature",
        id: o.id,
        properties: o.properties || {},
        geometry: object(topology, o)
      };
      if (o.id == null) delete f.id;
      return f;
    }
  
    function object(topology, o) {
      var absolute = transformAbsolute(topology.transform),
          arcs = topology.arcs;
  
      function arc(i, points) {
        if (points.length) points.pop();
        for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) {
          points.push(p = a[k].slice());
          absolute(p, k);
        }
        if (i < 0) reverse(points, n);
      }
  
      function point(p) {
        p = p.slice();
        absolute(p, 0);
        return p;
      }
  
      function line(arcs) {
        var points = [];
        for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);
        if (points.length < 2) points.push(points[0].slice());
        return points;
      }
  
      function ring(arcs) {
        var points = line(arcs);
        while (points.length < 4) points.push(points[0].slice());
        return points;
      }
  
      function polygon(arcs) {
        return arcs.map(ring);
      }
  
      function geometry(o) {
        var t = o.type;
        return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)}
            : t in geometryType ? {type: t, coordinates: geometryType[t](o)}
            : null;
      }
  
      var geometryType = {
        Point: function(o) { return point(o.coordinates); },
        MultiPoint: function(o) { return o.coordinates.map(point); },
        LineString: function(o) { return line(o.arcs); },
        MultiLineString: function(o) { return o.arcs.map(line); },
        Polygon: function(o) { return polygon(o.arcs); },
        MultiPolygon: function(o) { return o.arcs.map(polygon); }
      };
  
      return geometry(o);
    }
  
    function reverse(array, n) {
      var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;
    }
  
    function bisect(a, x) {
      var lo = 0, hi = a.length;
      while (lo < hi) {
        var mid = lo + hi >>> 1;
        if (a[mid] < x) lo = mid + 1;
        else hi = mid;
      }
      return lo;
    }
  
    function neighbors(objects) {
      var indexesByArc = {}, // arc index -> array of object indexes
          neighbors = objects.map(function() { return []; });
  
      function line(arcs, i) {
        arcs.forEach(function(a) {
          if (a < 0) a = ~a;
          var o = indexesByArc[a];
          if (o) o.push(i);
          else indexesByArc[a] = [i];
        });
      }
  
      function polygon(arcs, i) {
        arcs.forEach(function(arc) { line(arc, i); });
      }
  
      function geometry(o, i) {
        if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); });
        else if (o.type in geometryType) geometryType[o.type](o.arcs, i);
      }
  
      var geometryType = {
        LineString: line,
        MultiLineString: polygon,
        Polygon: polygon,
        MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }
      };
  
      objects.forEach(geometry);
  
      for (var i in indexesByArc) {
        for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {
          for (var k = j + 1; k < m; ++k) {
            var ij = indexes[j], ik = indexes[k], n;
            if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);
            if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);
          }
        }
      }
  
      return neighbors;
    }
  
    function presimplify(topology, triangleArea) {
      var absolute = transformAbsolute(topology.transform),
          relative = transformRelative(topology.transform),
          heap = minHeap(compareArea),
          maxArea = 0,
          triangle;
  
      if (!triangleArea) triangleArea = cartesianTriangleArea;
  
      topology.arcs.forEach(function(arc) {
        var triangles = [];
  
        arc.forEach(absolute);
  
        for (var i = 1, n = arc.length - 1; i < n; ++i) {
          triangle = arc.slice(i - 1, i + 2);
          triangle[1][2] = triangleArea(triangle);
          triangles.push(triangle);
          heap.push(triangle);
        }
  
        // Always keep the arc endpoints!
        arc[0][2] = arc[n][2] = Infinity;
  
        for (var i = 0, n = triangles.length; i < n; ++i) {
          triangle = triangles[i];
          triangle.previous = triangles[i - 1];
          triangle.next = triangles[i + 1];
        }
      });
  
      while (triangle = heap.pop()) {
        var previous = triangle.previous,
            next = triangle.next;
  
        // If the area of the current point is less than that of the previous point
        // to be eliminated, use the latter's area instead. This ensures that the
        // current point cannot be eliminated without eliminating previously-
        // eliminated points.
        if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;
        else maxArea = triangle[1][2];
  
        if (previous) {
          previous.next = next;
          previous[2] = triangle[2];
          update(previous);
        }
  
        if (next) {
          next.previous = previous;
          next[0] = triangle[0];
          update(next);
        }
      }
  
      topology.arcs.forEach(function(arc) {
        arc.forEach(relative);
      });
  
      function update(triangle) {
        heap.remove(triangle);
        triangle[1][2] = triangleArea(triangle);
        heap.push(triangle);
      }
  
      return topology;
    };
  
    function cartesianRingArea(ring) {
      var i = -1,
          n = ring.length,
          a,
          b = ring[n - 1],
          area = 0;
  
      while (++i < n) {
        a = b;
        b = ring[i];
        area += a[0] * b[1] - a[1] * b[0];
      }
  
      return area * .5;
    }
  
    function cartesianTriangleArea(triangle) {
      var a = triangle[0], b = triangle[1], c = triangle[2];
      return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]));
    }
  
    function compareArea(a, b) {
      return a[1][2] - b[1][2];
    }
  
    function minHeap(compare) {
      var heap = {},
          array = [];
  
      heap.push = function() {
        for (var i = 0, n = arguments.length; i < n; ++i) {
          var object = arguments[i];
          up(object.index = array.push(object) - 1);
        }
        return array.length;
      };
  
      heap.pop = function() {
        var removed = array[0],
            object = array.pop();
        if (array.length) {
          array[object.index = 0] = object;
          down(0);
        }
        return removed;
      };
  
      heap.remove = function(removed) {
        var i = removed.index,
            object = array.pop();
        if (i !== array.length) {
          array[object.index = i] = object;
          (compare(object, removed) < 0 ? up : down)(i);
        }
        return i;
      };
  
      function up(i) {
        var object = array[i];
        while (i > 0) {
          var up = ((i + 1) >> 1) - 1,
              parent = array[up];
          if (compare(object, parent) >= 0) break;
          array[parent.index = i] = parent;
          array[object.index = i = up] = object;
        }
      }
  
      function down(i) {
        var object = array[i];
        while (true) {
          var right = (i + 1) << 1,
              left = right - 1,
              down = i,
              child = array[down];
          if (left < array.length && compare(array[left], child) < 0) child = array[down = left];
          if (right < array.length && compare(array[right], child) < 0) child = array[down = right];
          if (down === i) break;
          array[child.index = i] = child;
          array[object.index = i = down] = object;
        }
      }
  
      return heap;
    }
  
    function transformAbsolute(transform) {
      if (!transform) return noop;
      var x0,
          y0,
          kx = transform.scale[0],
          ky = transform.scale[1],
          dx = transform.translate[0],
          dy = transform.translate[1];
      return function(point, i) {
        if (!i) x0 = y0 = 0;
        point[0] = (x0 += point[0]) * kx + dx;
        point[1] = (y0 += point[1]) * ky + dy;
      };
    }
  
    function transformRelative(transform) {
      if (!transform) return noop;
      var x0,
          y0,
          kx = transform.scale[0],
          ky = transform.scale[1],
          dx = transform.translate[0],
          dy = transform.translate[1];
      return function(point, i) {
        if (!i) x0 = y0 = 0;
        var x1 = (point[0] - dx) / kx | 0,
            y1 = (point[1] - dy) / ky | 0;
        point[0] = x1 - x0;
        point[1] = y1 - y0;
        x0 = x1;
        y0 = y1;
      };
    }
  
    function noop() {}
  
    if (typeof define === "function" && define.amd) define(topojson);
    else if (typeof module === "object" && module.exports) module.exports = topojson;
    else this.topojson = topojson;
  }();
  