text: (function() {
    var svg;
  
    // Save off default references
    var d3 = window.d3, topojson = window.topojson;
  
    var defaultOptions = {
      scope: 'world',
      responsive: false,
      aspectRatio: 0.5625,
      setProjection: setProjection,
      projection: 'equirectangular',
      dataType: 'json',
      data: {},
      done: function() {},
      fills: {
        defaultFill: '#ABDDA4'
      },
      filters: {},
      geographyConfig: {
          dataUrl: null,
          hideAntarctica: true,
          hideHawaiiAndAlaska : false,
          borderWidth: 1,
          borderOpacity: 1,
          borderColor: '#FDFDFD',
          popupTemplate: function(geography, data) {
            return '<div class="hoverinfo"><strong>' + geography.properties.name + '</strong></div>';
          },
          popupOnHover: true,
          highlightOnHover: true,
          highlightFillColor: '#FC8D59',
          highlightBorderColor: 'rgba(250, 15, 160, 0.2)',
          highlightBorderWidth: 2,
          highlightBorderOpacity: 1
      },
      projectionConfig: {
        rotation: [97, 0]
      },
      bubblesConfig: {
          borderWidth: 2,
          borderOpacity: 1,
          borderColor: '#FFFFFF',
          popupOnHover: true,
          radius: null,
          popupTemplate: function(geography, data) {
            return '<div class="hoverinfo"><strong>' + data.name + '</strong></div>';
          },
          fillOpacity: 0.75,
          animate: true,
          highlightOnHover: true,
          highlightFillColor: '#FC8D59',
          highlightBorderColor: 'rgba(250, 15, 160, 0.2)',
          highlightBorderWidth: 2,
          highlightBorderOpacity: 1,
          highlightFillOpacity: 0.85,
          exitDelay: 100,
          key: JSON.stringify
      },
      arcConfig: {
        strokeColor: '#DD1C77',
        strokeWidth: 1,
        arcSharpness: 1,
        animationSpeed: 600,
        popupOnHover: false,
        popupTemplate: function(geography, data) {
          // Case with latitude and longitude
          if ( ( data.origin && data.destination ) && data.origin.latitude && data.origin.longitude && data.destination.latitude && data.destination.longitude ) {
            return '<div class="hoverinfo"><strong>Arc</strong><br>Origin: ' + JSON.stringify(data.origin) + '<br>Destination: ' + JSON.stringify(data.destination) + '</div>';
          }
          // Case with only country name
          else if ( data.origin && data.destination ) {
            return '<div class="hoverinfo"><strong>Arc</strong><br>' + data.origin + ' -> ' + data.destination + '</div>';
          }
          // Missing information
          else {
            return '';
          }
        }
      }
    };
  
    /*
      Getter for value. If not declared on datumValue, look up the chain into optionsValue
    */
    function val( datumValue, optionsValue, context ) {
      if ( typeof context === 'undefined' ) {
        context = optionsValue;
        optionsValues = undefined;
      }
      var value = typeof datumValue !== 'undefined' ? datumValue : optionsValue;
  
      if (typeof value === 'undefined') {
        return  null;
      }
  
      if ( typeof value === 'function' ) {
        var fnContext = [context];
        if ( context.geography ) {
          fnContext = [context.geography, context.data];
        }
        return value.apply(null, fnContext);
      }
      else {
        return value;
      }
    }
  
    function addContainer( element, height, width ) {
      this.svg = d3.select( element ).append('svg')
        .attr('width', width || element.offsetWidth)
        .attr('data-width', width || element.offsetWidth)
        .attr('class', 'datamap')
        .attr('height', height || element.offsetHeight)
        .style('overflow', 'hidden'); // IE10+ doesn't respect height/width when map is zoomed in
  
      if (this.options.responsive) {
        d3.select(this.options.element).style({'position': 'relative', 'padding-bottom': (this.options.aspectRatio*100) + '%'});
        d3.select(this.options.element).select('svg').style({'position': 'absolute', 'width': '100%', 'height': '100%'});
        d3.select(this.options.element).select('svg').select('g').selectAll('path').style('vector-effect', 'non-scaling-stroke');
  
      }
  
      return this.svg;
    }
  
    // setProjection takes the svg element and options
    function setProjection( element, options ) {
      var width = options.width || element.offsetWidth;
      var height = options.height || element.offsetHeight;
      var projection, path;
      var svg = this.svg;
  
      if ( options && typeof options.scope === 'undefined') {
        options.scope = 'world';
      }
  
      if ( options.scope === 'usa' ) {
        projection = d3.geo.albersUsa()
          .scale(width)
          .translate([width / 2, height / 2]);
      }
      else if ( options.scope === 'world' ) {
        projection = d3.geo[options.projection]()
          .scale((width + 1) / 2 / Math.PI)
          .translate([width / 2, height / (options.projection === "mercator" ? 1.45 : 1.8)]);
      }
  
      if ( options.projection === 'orthographic' ) {
  
        svg.append("defs").append("path")
          .datum({type: "Sphere"})
          .attr("id", "sphere")
          .attr("d", path);
  
        svg.append("use")
            .attr("class", "stroke")
            .attr("xlink:href", "#sphere");
  
        svg.append("use")
            .attr("class", "fill")
            .attr("xlink:href", "#sphere");
        projection.scale(250).clipAngle(90).rotate(options.projectionConfig.rotation)
      }
  
      path = d3.geo.path()
        .projection( projection );
  
      return {path: path, projection: projection};
    }
  
    function addStyleBlock() {
      if ( d3.select('.datamaps-style-block').empty() ) {
        d3.select('head').append('style').attr('class', 'datamaps-style-block')
        .html('.datamap path.datamaps-graticule { fill: none; stroke: #777; stroke-width: 0.5px; stroke-opacity: .5; pointer-events: none; } .datamap .labels {pointer-events: none;} .datamap path:not(.datamaps-arc), .datamap circle, .datamap line {stroke: #FFFFFF; vector-effect: non-scaling-stroke; stroke-width: 1px;} .datamaps-legend dt, .datamaps-legend dd { float: left; margin: 0 3px 0 0;} .datamaps-legend dd {width: 20px; margin-right: 6px; border-radius: 3px;} .datamaps-legend {padding-bottom: 20px; z-index: 1001; position: absolute; left: 4px; font-size: 12px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;} .datamaps-hoverover {display: none; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } .hoverinfo {padding: 4px; border-radius: 1px; background-color: #FFF; box-shadow: 1px 1px 5px #CCC; font-size: 12px; border: 1px solid #CCC; } .hoverinfo hr {border:1px dotted #CCC; }');
      }
    }
  
    function drawSubunits( data ) {
      var fillData = this.options.fills,
          colorCodeData = this.options.data || {},
          geoConfig = this.options.geographyConfig;
  
      var subunits = this.svg.select('g.datamaps-subunits');
      if ( subunits.empty() ) {
        subunits = this.addLayer('datamaps-subunits', null, true);
      }
  
      var geoData = topojson.feature( data, data.objects[ this.options.scope ] ).features;
      if ( geoConfig.hideAntarctica ) {
        geoData = geoData.filter(function(feature) {
          return feature.id !== "ATA";
        });
      }
  
      if ( geoConfig.hideHawaiiAndAlaska ) {
        geoData = geoData.filter(function(feature) {
          return feature.id !== "HI" && feature.id !== 'AK';
        });
      }
  
      var geo = subunits.selectAll('path.datamaps-subunit').data( geoData );
  
      geo.enter()
        .append('path')
        .attr('d', this.path)
        .attr('class', function(d) {
          return 'datamaps-subunit ' + d.id;
        })
        .attr('data-info', function(d) {
          return JSON.stringify( colorCodeData[d.id]);
        })
        .style('fill', function(d) {
          // If fillKey - use that
          // Otherwise check 'fill'
          // Otherwise check 'defaultFill'
          var fillColor;
  
          var datum = colorCodeData[d.id];
          if ( datum && datum.fillKey ) {
            fillColor = fillData[ val(datum.fillKey, {data: colorCodeData[d.id], geography: d}) ];
          }
  
          if ( typeof fillColor === 'undefined' ) {
            fillColor = val(datum && datum.fillColor, fillData.defaultFill, {data: colorCodeData[d.id], geography: d});
          }
  
          return fillColor;
        })
        .style('stroke-width', geoConfig.borderWidth)
        .style('stroke-opacity', geoConfig.borderOpacity)
        .style('stroke', geoConfig.borderColor);
    }
  
    function handleGeographyConfig () {
      var hoverover;
      var svg = this.svg;
      var self = this;
      var options = this.options.geographyConfig;
  
      if ( options.highlightOnHover || options.popupOnHover ) {
        svg.selectAll('.datamaps-subunit')
          .on('mouseover', function(d) {
            var $this = d3.select(this);
            var datum = self.options.data[d.id] || {};
            if ( options.highlightOnHover ) {
              var previousAttributes = {
                'fill':  $this.style('fill'),
                'stroke': $this.style('stroke'),
                'stroke-width': $this.style('stroke-width'),
                'fill-opacity': $this.style('fill-opacity')
              };
  
              $this
                .style('fill', val(datum.highlightFillColor, options.highlightFillColor, datum))
                .style('stroke', val(datum.highlightBorderColor, options.highlightBorderColor, datum))
                .style('stroke-width', val(datum.highlightBorderWidth, options.highlightBorderWidth, datum))
                .style('stroke-opacity', val(datum.highlightBorderOpacity, options.highlightBorderOpacity, datum))
                .style('fill-opacity', val(datum.highlightFillOpacity, options.highlightFillOpacity, datum))
                .attr('data-previousAttributes', JSON.stringify(previousAttributes));
  
              // As per discussion on https://github.com/markmarkoh/datamaps/issues/19
              if ( ! /((MSIE)|(Trident))/.test(navigator.userAgent) ) {
               moveToFront.call(this);
              }
            }
  
            if ( options.popupOnHover ) {
              self.updatePopup($this, d, options, svg);
            }
          })
          .on('mouseout', function() {
            var $this = d3.select(this);
  
            if (options.highlightOnHover) {
              // Reapply previous attributes
              var previousAttributes = JSON.parse( $this.attr('data-previousAttributes') );
              for ( var attr in previousAttributes ) {
                $this.style(attr, previousAttributes[attr]);
              }
            }
            $this.on('mousemove', null);
            d3.selectAll('.datamaps-hoverover').style('display', 'none');
          });
      }
  
      function moveToFront() {
        this.parentNode.appendChild(this);
      }
    }
  
    // Plugin to add a simple map legend
    function addLegend(layer, data, options) {
      data = data || {};
      if ( !this.options.fills ) {
        return;
      }
  
      var html = '<dl>';
      var label = '';
      if ( data.legendTitle ) {
        html = '<h2>' + data.legendTitle + '</h2>' + html;
      }
      for ( var fillKey in this.options.fills ) {
  
        if ( fillKey === 'defaultFill') {
          if (! data.defaultFillName ) {
            continue;
          }
          label = data.defaultFillName;
        } else {
          if (data.labels && data.labels[fillKey]) {
            label = data.labels[fillKey];
          } else {
            label= fillKey + ': ';
          }
        }
        html += '<dt>' + label + '</dt>';
        html += '<dd style="background-color:' +  this.options.fills[fillKey] + '">&nbsp;</dd>';
      }
      html += '</dl>';
  
      var hoverover = d3.select( this.options.element ).append('div')
        .attr('class', 'datamaps-legend')
        .html(html);
    }
  
      function addGraticule ( layer, options ) {
        var graticule = d3.geo.graticule();
        this.svg.insert("path", '.datamaps-subunits')
          .datum(graticule)
          .attr("class", "datamaps-graticule")
          .attr("d", this.path);
    }
  
    function handleArcs (layer, data, options) {
      var self = this,
          svg = this.svg;
  
      if ( !data || (data && !data.slice) ) {
        throw "Datamaps Error - arcs must be an array";
      }
  
      // For some reason arc options were put in an `options` object instead of the parent arc
      // I don't like this, so to match bubbles and other plugins I'm moving it
      // This is to keep backwards compatability
      for ( var i = 0; i < data.length; i++ ) {
        data[i] = defaults(data[i], data[i].options);
        delete data[i].options;
      }
  
      if ( typeof options === "undefined" ) {
        options = defaultOptions.arcConfig;
      }
  
      var arcs = layer.selectAll('path.datamaps-arc').data( data, JSON.stringify );
  
      var path = d3.geo.path()
          .projection(self.projection);
  
      arcs
        .enter()
          .append('svg:path')
          .attr('class', 'datamaps-arc')
          .style('stroke-linecap', 'round')
          .style('stroke', function(datum) {
            return val(datum.strokeColor, options.strokeColor, datum);
          })
          .style('fill', 'none')
          .style('stroke-width', function(datum) {
              return val(datum.strokeWidth, options.strokeWidth, datum);
          })
          .attr('d', function(datum) {
  
              var originXY, destXY;
  
              if (typeof datum.origin === "string") {
                switch (datum.origin) {
                     case "CAN":
                         originXY = self.latLngToXY(56.624472, -114.665293);
                         break;
                     case "CHL":
                         originXY = self.latLngToXY(-33.448890, -70.669265);
                         break;
                     case "IDN":
                         originXY = self.latLngToXY(-6.208763, 106.845599);
                         break;
                     case "JPN":
                         originXY = self.latLngToXY(35.689487, 139.691706);
                         break;
                     case "MYS":
                         originXY = self.latLngToXY(3.139003, 101.686855);
                         break;
                     case "NOR":
                         originXY = self.latLngToXY(59.913869, 10.752245);
                         break;
                     case "USA":
                         originXY = self.latLngToXY(41.140276, -100.760145);
                         break;
                     case "VNM":
                         originXY = self.latLngToXY(21.027764, 105.834160);
                         break;
                     default:
                         originXY = self.path.centroid(svg.select('path.' + datum.origin).data()[0]);
                 }
              } else {
                originXY = self.latLngToXY(val(datum.origin.latitude, datum), val(datum.origin.longitude, datum))
              }
  
              if (typeof datum.destination === 'string') {
                switch (datum.destination) {
                       case "CAN":
                          destXY = self.latLngToXY(56.624472, -114.665293);
                          break;
                      case "CHL":
                          destXY = self.latLngToXY(-33.448890, -70.669265);
                          break;
                      case "IDN":
                          destXY = self.latLngToXY(-6.208763, 106.845599);
                          break;
                      case "JPN":
                          destXY = self.latLngToXY(35.689487, 139.691706);
                          break;
                      case "MYS":
                          destXY = self.latLngToXY(3.139003, 101.686855);
                          break;
                      case "NOR":
                          destXY = self.latLngToXY(59.913869, 10.752245);
                          break;
                      case "USA":
                          destXY = self.latLngToXY(41.140276, -100.760145);
                          break;
                      case "VNM":
                          destXY = self.latLngToXY(21.027764, 105.834160);
                          break;
                      default:
                          destXY = self.path.centroid(svg.select('path.' + datum.destination).data()[0]);
                }
              } else {
                destXY = self.latLngToXY(val(datum.destination.latitude, datum), val(datum.destination.longitude, datum));
              }
              var midXY = [ (originXY[0] + destXY[0]) / 2, (originXY[1] + destXY[1]) / 2];
              if (options.greatArc) {
                    // TODO: Move this to inside `if` clause when setting attr `d`
                var greatArc = d3.geo.greatArc()
                    .source(function(d) { return [val(d.origin.longitude, d), val(d.origin.latitude, d)]; })
                    .target(function(d) { return [val(d.destination.longitude, d), val(d.destination.latitude, d)]; });
  
                return path(greatArc(datum))
              }
              var sharpness = val(datum.arcSharpness, options.arcSharpness, datum);
              return "M" + originXY[0] + ',' + originXY[1] + "S" + (midXY[0] + (50 * sharpness)) + "," + (midXY[1] - (75 * sharpness)) + "," + destXY[0] + "," + destXY[1];
          })
          .attr('data-info', function(datum) {
            return JSON.stringify(datum);
          })
          .on('mouseover', function ( datum ) {
            var $this = d3.select(this);
  
            if (options.popupOnHover) {
              self.updatePopup($this, datum, options, svg);
            }
          })
          .on('mouseout', function ( datum ) {
            var $this = d3.select(this);
  
            d3.selectAll('.datamaps-hoverover').style('display', 'none');
          })
          .transition()
            .delay(100)
            .style('fill', function(datum) {
              /*
                Thank you Jake Archibald, this is awesome.
                Source: http://jakearchibald.com/2013/animated-line-drawing-svg/
              */
              var length = this.getTotalLength();
              this.style.transition = this.style.WebkitTransition = 'none';
              this.style.strokeDasharray = length + ' ' + length;
              this.style.strokeDashoffset = length;
              this.getBoundingClientRect();
              this.style.transition = this.style.WebkitTransition = 'stroke-dashoffset ' + val(datum.animationSpeed, options.animationSpeed, datum) + 'ms ease-out';
              this.style.strokeDashoffset = '0';
              return 'none';
            })
  
      arcs.exit()
        .transition()
        .style('opacity', 0)
        .remove();
    }
  
    function handleLabels ( layer, options ) {
      var self = this;
      options = options || {};
      var labelStartCoodinates = this.projection([-67.707617, 42.722131]);
      this.svg.selectAll(".datamaps-subunit")
        .attr("data-foo", function(d) {
          var center = self.path.centroid(d);
          var xOffset = 7.5, yOffset = 5;
  
          if ( ["FL", "KY", "MI"].indexOf(d.id) > -1 ) xOffset = -2.5;
          if ( d.id === "NY" ) xOffset = -1;
          if ( d.id === "MI" ) yOffset = 18;
          if ( d.id === "LA" ) xOffset = 13;
  
          var x,y;
  
          x = center[0] - xOffset;
          y = center[1] + yOffset;
  
          var smallStateIndex = ["VT", "NH", "MA", "RI", "CT", "NJ", "DE", "MD", "DC"].indexOf(d.id);
          if ( smallStateIndex > -1) {
            var yStart = labelStartCoodinates[1];
            x = labelStartCoodinates[0];
            y = yStart + (smallStateIndex * (2+ (options.fontSize || 12)));
            layer.append("line")
              .attr("x1", x - 3)
              .attr("y1", y - 5)
              .attr("x2", center[0])
              .attr("y2", center[1])
              .style("stroke", options.labelColor || "#000")
              .style("stroke-width", options.lineWidth || 1)
          }
  
            layer.append("text")
                .attr("x", x)
                .attr("y", y)
                .style("font-size", (options.fontSize || 10) + 'px')
                .style("font-family", options.fontFamily || "Verdana")
                .style("fill", options.labelColor || "#000")
                .text(function() {
                    if (options.customLabelText && options.customLabelText[d.id]) {
                        return options.customLabelText[d.id]
                    } else {
                        return d.id
                    }
                });
  
          return "bar";
        });
    }
  
  
    function handleBubbles (layer, data, options ) {
      var self = this,
          fillData = this.options.fills,
          filterData = this.options.filters,
          svg = this.svg;
  
      if ( !data || (data && !data.slice) ) {
        throw "Datamaps Error - bubbles must be an array";
      }
  
      var bubbles = layer.selectAll('circle.datamaps-bubble').data( data, options.key );
  
      bubbles
        .enter()
          .append('svg:circle')
          .attr('class', 'datamaps-bubble')
          .attr('cx', function ( datum ) {
            var latLng;
            if ( datumHasCoords(datum) ) {
              latLng = self.latLngToXY(datum.latitude, datum.longitude);
            }
            else if ( datum.centered ) {
              if ( datum.centered === 'USA' ) {
                latLng = self.projection([-98.58333, 39.83333])
              } else {
                latLng = self.path.centroid(svg.select('path.' + datum.centered).data()[0]);
              }
            }
            if ( latLng ) return latLng[0];
          })
          .attr('cy', function ( datum ) {
            var latLng;
            if ( datumHasCoords(datum) ) {
              latLng = self.latLngToXY(datum.latitude, datum.longitude);
            }
            else if ( datum.centered ) {
              if ( datum.centered === 'USA' ) {
                latLng = self.projection([-98.58333, 39.83333])
              } else {
                latLng = self.path.centroid(svg.select('path.' + datum.centered).data()[0]);
              }
            }
            if ( latLng ) return latLng[1];
          })
          .attr('r', function(datum) {
            // If animation enabled start with radius 0, otherwise use full size.
            return options.animate ? 0 : val(datum.radius, options.radius, datum);
          })
          .attr('data-info', function(datum) {
            return JSON.stringify(datum);
          })
          .attr('filter', function (datum) {
            var filterKey = filterData[ val(datum.filterKey, options.filterKey, datum) ];
  
            if (filterKey) {
              return filterKey;
            }
          })
          .style('stroke', function ( datum ) {
            return val(datum.borderColor, options.borderColor, datum);
          })
          .style('stroke-width', function ( datum ) {
            return val(datum.borderWidth, options.borderWidth, datum);
          })
          .style('stroke-opacity', function ( datum ) {
            return val(datum.borderOpacity, options.borderOpacity, datum);
          })
          .style('fill-opacity', function ( datum ) {
            return val(datum.fillOpacity, options.fillOpacity, datum);
          })
          .style('fill', function ( datum ) {
            var fillColor = fillData[ val(datum.fillKey, options.fillKey, datum) ];
            return fillColor || fillData.defaultFill;
          })
          .on('mouseover', function ( datum ) {
            var $this = d3.select(this);
  
            if (options.highlightOnHover) {
              // Save all previous attributes for mouseout
              var previousAttributes = {
                'fill':  $this.style('fill'),
                'stroke': $this.style('stroke'),
                'stroke-width': $this.style('stroke-width'),
                'fill-opacity': $this.style('fill-opacity')
              };
  
              $this
                .style('fill', val(datum.highlightFillColor, options.highlightFillColor, datum))
                .style('stroke', val(datum.highlightBorderColor, options.highlightBorderColor, datum))
                .style('stroke-width', val(datum.highlightBorderWidth, options.highlightBorderWidth, datum))
                .style('stroke-opacity', val(datum.highlightBorderOpacity, options.highlightBorderOpacity, datum))
                .style('fill-opacity', val(datum.highlightFillOpacity, options.highlightFillOpacity, datum))
                .attr('data-previousAttributes', JSON.stringify(previousAttributes));
            }
  
            if (options.popupOnHover) {
              self.updatePopup($this, datum, options, svg);
            }
          })
          .on('mouseout', function ( datum ) {
            var $this = d3.select(this);
  
            if (options.highlightOnHover) {
              // Reapply previous attributes
              var previousAttributes = JSON.parse( $this.attr('data-previousAttributes') );
              for ( var attr in previousAttributes ) {
                $this.style(attr, previousAttributes[attr]);
              }
            }
  
            d3.selectAll('.datamaps-hoverover').style('display', 'none');
          })
  
      bubbles.transition()
        .duration(400)
        .attr('r', function ( datum ) {
          return val(datum.radius, options.radius, datum);
        })
      .transition()
        .duration(0)
        .attr('data-info', function(d) {
          return JSON.stringify(d);
        });
  
      bubbles.exit()
        .transition()
          .delay(options.exitDelay)
          .attr("r", 0)
          .remove();
  
      function datumHasCoords (datum) {
        return typeof datum !== 'undefined' && typeof datum.latitude !== 'undefined' && typeof datum.longitude !== 'undefined';
      }
    }
  
    function defaults(obj) {
      Array.prototype.slice.call(arguments, 1).forEach(function(source) {
        if (source) {
          for (var prop in source) {
            // Deep copy if property not set
            if (obj[prop] == null) {
              if (typeof source[prop] == 'function') {
                obj[prop] = source[prop];
              }
              else {
                obj[prop] = JSON.parse(JSON.stringify(source[prop]));
              }
            }
          }
        }
      });
      return obj;
    }
    /**************************************
               Public Functions
    ***************************************/
  
    function Datamap( options ) {
  
      if ( typeof d3 === 'undefined' || typeof topojson === 'undefined' ) {
        throw new Error('Include d3.js (v3.0.3 or greater) and topojson on this page before creating a new map');
     }
      // Set options for global use
      this.options = defaults(options, defaultOptions);
      this.options.geographyConfig = defaults(options.geographyConfig, defaultOptions.geographyConfig);
      this.options.projectionConfig = defaults(options.projectionConfig, defaultOptions.projectionConfig);
      this.options.bubblesConfig = defaults(options.bubblesConfig, defaultOptions.bubblesConfig);
      this.options.arcConfig = defaults(options.arcConfig, defaultOptions.arcConfig);
  
      // Add the SVG container
      if ( d3.select( this.options.element ).select('svg').length > 0 ) {
        addContainer.call(this, this.options.element, this.options.height, this.options.width );
      }
  
      // Add core plugins to this instance
      this.addPlugin('bubbles', handleBubbles);
      this.addPlugin('legend', addLegend);
      this.addPlugin('arc', handleArcs);
      this.addPlugin('labels', handleLabels);
      this.addPlugin('graticule', addGraticule);
  
      // Append style block with basic hoverover styles
      if ( ! this.options.disableDefaultStyles ) {
        addStyleBlock();
      }
  
      return this.draw();
    }
  
    // Resize map
    Datamap.prototype.resize = function () {
  
      var self = this;
      var options = self.options;
  
      if (options.responsive) {
        var newsize = options.element.clientWidth,
            oldsize = d3.select( options.element).select('svg').attr('data-width');
  
        d3.select(options.element).select('svg').selectAll('g').attr('transform', 'scale(' + (newsize / oldsize) + ')');
      }
    }
  
    // Actually draw the features(states & countries)
    Datamap.prototype.draw = function() {
      // Save off in a closure
      var self = this;
      var options = self.options;
  
      // Set projections and paths based on scope
      var pathAndProjection = options.setProjection.apply(this, [options.element, options] );
  
      this.path = pathAndProjection.path;
      this.projection = pathAndProjection.projection;
  
      // If custom URL for topojson data, retrieve it and render
      if ( options.geographyConfig.dataUrl ) {
        d3.json( options.geographyConfig.dataUrl, function(error, results) {
          if ( error ) throw new Error(error);
          self.customTopo = results;
          draw( results );
        });
      }
      else {
        draw( this[options.scope + 'Topo'] || options.geographyConfig.dataJson);
      }
  
      return this;
  
        function draw (data) {
          // If fetching remote data, draw the map first then call `updateChoropleth`
          if ( self.options.dataUrl ) {
            // Allow for csv or json data types
            d3[self.options.dataType](self.options.dataUrl, function(data) {
              // In the case of csv, transform data to object
              if ( self.options.dataType === 'csv' && (data && data.slice) ) {
                var tmpData = {};
                for(var i = 0; i < data.length; i++) {
                  tmpData[data[i].id] = data[i];
                }
                data = tmpData;
              }
              Datamaps.prototype.updateChoropleth.call(self, data);
            });
          }
          drawSubunits.call(self, data);
          handleGeographyConfig.call(self);
  
          if ( self.options.geographyConfig.popupOnHover || self.options.bubblesConfig.popupOnHover) {
            hoverover = d3.select( self.options.element ).append('div')
              .attr('class', 'datamaps-hoverover')
              .style('z-index', 10001)
              .style('position', 'absolute');
          }
  
          // Fire off finished callback
          self.options.done(self);
        }
    };
    /**************************************
                  TopoJSON
    ***************************************/
    Datamap.prototype.worldTopo = '__WORLD__';
    Datamap.prototype.abwTopo = '__ABW__';
    Datamap.prototype.afgTopo = '__AFG__';
    Datamap.prototype.agoTopo = '__AGO__';
    Datamap.prototype.aiaTopo = '__AIA__';
    Datamap.prototype.albTopo = '__ALB__';
    Datamap.prototype.aldTopo = '__ALD__';
    Datamap.prototype.andTopo = '__AND__';
    Datamap.prototype.areTopo = '__ARE__';
    Datamap.prototype.argTopo = '__ARG__';
    Datamap.prototype.armTopo = '__ARM__';
    Datamap.prototype.asmTopo = '__ASM__';
    Datamap.prototype.ataTopo = '__ATA__';
    Datamap.prototype.atcTopo = '__ATC__';
    Datamap.prototype.atfTopo = '__ATF__';
    Datamap.prototype.atgTopo = '__ATG__';
    Datamap.prototype.ausTopo = '__AUS__';
    Datamap.prototype.autTopo = '__AUT__';
    Datamap.prototype.azeTopo = '__AZE__';
    Datamap.prototype.bdiTopo = '__BDI__';
    Datamap.prototype.belTopo = '__BEL__';
    Datamap.prototype.benTopo = '__BEN__';
    Datamap.prototype.bfaTopo = '__BFA__';
    Datamap.prototype.bgdTopo = '__BGD__';
    Datamap.prototype.bgrTopo = '__BGR__';
    Datamap.prototype.bhrTopo = '__BHR__';
    Datamap.prototype.bhsTopo = '__BHS__';
    Datamap.prototype.bihTopo = '__BIH__';
    Datamap.prototype.bjnTopo = '__BJN__';
    Datamap.prototype.blmTopo = '__BLM__';
    Datamap.prototype.blrTopo = '__BLR__';
    Datamap.prototype.blzTopo = '__BLZ__';
    Datamap.prototype.bmuTopo = '__BMU__';
    Datamap.prototype.bolTopo = '__BOL__';
    Datamap.prototype.braTopo = '__BRA__';
    Datamap.prototype.brbTopo = '__BRB__';
    Datamap.prototype.brnTopo = '__BRN__';
    Datamap.prototype.btnTopo = '__BTN__';
    Datamap.prototype.norTopo = '__NOR__';
    Datamap.prototype.bwaTopo = '__BWA__';
    Datamap.prototype.cafTopo = '__CAF__';
    Datamap.prototype.canTopo = '__CAN__';
    Datamap.prototype.cheTopo = '__CHE__';
    Datamap.prototype.chlTopo = '__CHL__';
    Datamap.prototype.chnTopo = '__CHN__';
    Datamap.prototype.civTopo = '__CIV__';
    Datamap.prototype.clpTopo = '__CLP__';
    Datamap.prototype.cmrTopo = '__CMR__';
    Datamap.prototype.codTopo = '__COD__';
    Datamap.prototype.cogTopo = '__COG__';
    Datamap.prototype.cokTopo = '__COK__';
    Datamap.prototype.colTopo = '__COL__';
    Datamap.prototype.comTopo = '__COM__';
    Datamap.prototype.cpvTopo = '__CPV__';
    Datamap.prototype.criTopo = '__CRI__';
    Datamap.prototype.csiTopo = '__CSI__';
    Datamap.prototype.cubTopo = '__CUB__';
    Datamap.prototype.cuwTopo = '__CUW__';
    Datamap.prototype.cymTopo = '__CYM__';
    Datamap.prototype.cynTopo = '__CYN__';
    Datamap.prototype.cypTopo = '__CYP__';
    Datamap.prototype.czeTopo = '__CZE__';
    Datamap.prototype.deuTopo = '__DEU__';
    Datamap.prototype.djiTopo = '__DJI__';
    Datamap.prototype.dmaTopo = '__DMA__';
    Datamap.prototype.dnkTopo = '__DNK__';
    Datamap.prototype.domTopo = '__DOM__';
    Datamap.prototype.dzaTopo = '__DZA__';
    Datamap.prototype.ecuTopo = '__ECU__';
    Datamap.prototype.egyTopo = '__EGY__';
    Datamap.prototype.eriTopo = '__ERI__';
    Datamap.prototype.esbTopo = '__ESB__';
    Datamap.prototype.espTopo = '__ESP__';
    Datamap.prototype.estTopo = '__EST__';
    Datamap.prototype.ethTopo = '__ETH__';
    Datamap.prototype.finTopo = '__FIN__';
    Datamap.prototype.fjiTopo = '__FJI__';
    Datamap.prototype.flkTopo = '__FLK__';
    Datamap.prototype.fraTopo = '__FRA__';
    Datamap.prototype.froTopo = '__FRO__';
    Datamap.prototype.fsmTopo = '__FSM__';
    Datamap.prototype.gabTopo = '__GAB__';
    Datamap.prototype.psxTopo = '__PSX__';
    Datamap.prototype.gbrTopo = '__GBR__';
    Datamap.prototype.geoTopo = '__GEO__';
    Datamap.prototype.ggyTopo = '__GGY__';
    Datamap.prototype.ghaTopo = '__GHA__';
    Datamap.prototype.gibTopo = '__GIB__';
    Datamap.prototype.ginTopo = '__GIN__';
    Datamap.prototype.gmbTopo = '__GMB__';
    Datamap.prototype.gnbTopo = '__GNB__';
    Datamap.prototype.gnqTopo = '__GNQ__';
    Datamap.prototype.grcTopo = '__GRC__';
    Datamap.prototype.grdTopo = '__GRD__';
    Datamap.prototype.grlTopo = '__GRL__';
    Datamap.prototype.gtmTopo = '__GTM__';
    Datamap.prototype.gumTopo = '__GUM__';
    Datamap.prototype.guyTopo = '__GUY__';
    Datamap.prototype.hkgTopo = '__HKG__';
    Datamap.prototype.hmdTopo = '__HMD__';
    Datamap.prototype.hndTopo = '__HND__';
    Datamap.prototype.hrvTopo = '__HRV__';
    Datamap.prototype.htiTopo = '__HTI__';
    Datamap.prototype.hunTopo = '__HUN__';
    Datamap.prototype.idnTopo = '__IDN__';
    Datamap.prototype.imnTopo = '__IMN__';
    Datamap.prototype.indTopo = '__IND__';
    Datamap.prototype.ioaTopo = '__IOA__';
    Datamap.prototype.iotTopo = '__IOT__';
    Datamap.prototype.irlTopo = '__IRL__';
    Datamap.prototype.irnTopo = '__IRN__';
    Datamap.prototype.irqTopo = '__IRQ__';
    Datamap.prototype.islTopo = '__ISL__';
    Datamap.prototype.isrTopo = '__ISR__';
    Datamap.prototype.itaTopo = '__ITA__';
    Datamap.prototype.jamTopo = '__JAM__';
    Datamap.prototype.jeyTopo = '__JEY__';
    Datamap.prototype.jorTopo = '__JOR__';
    Datamap.prototype.jpnTopo = '__JPN__';
    Datamap.prototype.kabTopo = '__KAB__';
    Datamap.prototype.kasTopo = '__KAS__';
    Datamap.prototype.kazTopo = '__KAZ__';
    Datamap.prototype.kenTopo = '__KEN__';
    Datamap.prototype.kgzTopo = '__KGZ__';
    Datamap.prototype.khmTopo = '__KHM__';
    Datamap.prototype.kirTopo = '__KIR__';
    Datamap.prototype.knaTopo = '__KNA__';
    Datamap.prototype.korTopo = '__KOR__';
    Datamap.prototype.kosTopo = '__KOS__';
    Datamap.prototype.kwtTopo = '__KWT__';
    Datamap.prototype.laoTopo = '__LAO__';
    Datamap.prototype.lbnTopo = '__LBN__';
    Datamap.prototype.lbrTopo = '__LBR__';
    Datamap.prototype.lbyTopo = '__LBY__';
    Datamap.prototype.lcaTopo = '__LCA__';
    Datamap.prototype.lieTopo = '__LIE__';
    Datamap.prototype.lkaTopo = '__LKA__';
    Datamap.prototype.lsoTopo = '__LSO__';
    Datamap.prototype.ltuTopo = '__LTU__';
    Datamap.prototype.luxTopo = '__LUX__';
    Datamap.prototype.lvaTopo = '__LVA__';
    Datamap.prototype.macTopo = '__MAC__';
    Datamap.prototype.mafTopo = '__MAF__';
    Datamap.prototype.marTopo = '__MAR__';
    Datamap.prototype.mcoTopo = '__MCO__';
    Datamap.prototype.mdaTopo = '__MDA__';
    Datamap.prototype.mdgTopo = '__MDG__';
    Datamap.prototype.mdvTopo = '__MDV__';
    Datamap.prototype.mexTopo = '__MEX__';
    Datamap.prototype.mhlTopo = '__MHL__';
    Datamap.prototype.mkdTopo = '__MKD__';
    Datamap.prototype.mliTopo = '__MLI__';
    Datamap.prototype.mltTopo = '__MLT__';
    Datamap.prototype.mmrTopo = '__MMR__';
    Datamap.prototype.mneTopo = '__MNE__';
    Datamap.prototype.mngTopo = '__MNG__';
    Datamap.prototype.mnpTopo = '__MNP__';
    Datamap.prototype.mozTopo = '__MOZ__';
    Datamap.prototype.mrtTopo = '__MRT__';
    Datamap.prototype.msrTopo = '__MSR__';
    Datamap.prototype.musTopo = '__MUS__';
    Datamap.prototype.mwiTopo = '__MWI__';
    Datamap.prototype.mysTopo = '__MYS__';
    Datamap.prototype.namTopo = '__NAM__';
    Datamap.prototype.nclTopo = '__NCL__';
    Datamap.prototype.nerTopo = '__NER__';
    Datamap.prototype.nfkTopo = '__NFK__';
    Datamap.prototype.ngaTopo = '__NGA__';
    Datamap.prototype.nicTopo = '__NIC__';
    Datamap.prototype.niuTopo = '__NIU__';
    Datamap.prototype.nldTopo = '__NLD__';
    Datamap.prototype.nplTopo = '__NPL__';
    Datamap.prototype.nruTopo = '__NRU__';
    Datamap.prototype.nulTopo = '__NUL__';
    Datamap.prototype.nzlTopo = '__NZL__';
    Datamap.prototype.omnTopo = '__OMN__';
    Datamap.prototype.pakTopo = '__PAK__';
    Datamap.prototype.panTopo = '__PAN__';
    Datamap.prototype.pcnTopo = '__PCN__';
    Datamap.prototype.perTopo = '__PER__';
    Datamap.prototype.pgaTopo = '__PGA__';
    Datamap.prototype.phlTopo = '__PHL__';
    Datamap.prototype.plwTopo = '__PLW__';
    Datamap.prototype.pngTopo = '__PNG__';
    Datamap.prototype.polTopo = '__POL__';
    Datamap.prototype.priTopo = '__PRI__';
    Datamap.prototype.prkTopo = '__PRK__';
    Datamap.prototype.prtTopo = '__PRT__';
    Datamap.prototype.pryTopo = '__PRY__';
    Datamap.prototype.pyfTopo = '__PYF__';
    Datamap.prototype.qatTopo = '__QAT__';
    Datamap.prototype.rouTopo = '__ROU__';
    Datamap.prototype.rusTopo = '__RUS__';
    Datamap.prototype.rwaTopo = '__RWA__';
    Datamap.prototype.sahTopo = '__SAH__';
    Datamap.prototype.sauTopo = '__SAU__';
    Datamap.prototype.scrTopo = '__SCR__';
    Datamap.prototype.sdnTopo = '__SDN__';
    Datamap.prototype.sdsTopo = '__SDS__';
    Datamap.prototype.senTopo = '__SEN__';
    Datamap.prototype.serTopo = '__SER__';
    Datamap.prototype.sgpTopo = '__SGP__';
    Datamap.prototype.sgsTopo = '__SGS__';
    Datamap.prototype.shnTopo = '__SHN__';
    Datamap.prototype.slbTopo = '__SLB__';
    Datamap.prototype.sleTopo = '__SLE__';
    Datamap.prototype.slvTopo = '__SLV__';
    Datamap.prototype.smrTopo = '__SMR__';
    Datamap.prototype.solTopo = '__SOL__';
    Datamap.prototype.somTopo = '__SOM__';
    Datamap.prototype.spmTopo = '__SPM__';
    Datamap.prototype.srbTopo = '__SRB__';
    Datamap.prototype.stpTopo = '__STP__';
    Datamap.prototype.surTopo = '__SUR__';
    Datamap.prototype.svkTopo = '__SVK__';
    Datamap.prototype.svnTopo = '__SVN__';
    Datamap.prototype.sweTopo = '__SWE__';
    Datamap.prototype.swzTopo = '__SWZ__';
    Datamap.prototype.sxmTopo = '__SXM__';
    Datamap.prototype.sycTopo = '__SYC__';
    Datamap.prototype.syrTopo = '__SYR__';
    Datamap.prototype.tcaTopo = '__TCA__';
    Datamap.prototype.tcdTopo = '__TCD__';
    Datamap.prototype.tgoTopo = '__TGO__';
    Datamap.prototype.thaTopo = '__THA__';
    Datamap.prototype.tjkTopo = '__TJK__';
    Datamap.prototype.tkmTopo = '__TKM__';
    Datamap.prototype.tlsTopo = '__TLS__';
    Datamap.prototype.tonTopo = '__TON__';
    Datamap.prototype.ttoTopo = '__TTO__';
    Datamap.prototype.tunTopo = '__TUN__';
    Datamap.prototype.turTopo = '__TUR__';
    Datamap.prototype.tuvTopo = '__TUV__';
    Datamap.prototype.twnTopo = '__TWN__';
    Datamap.prototype.tzaTopo = '__TZA__';
    Datamap.prototype.ugaTopo = '__UGA__';
    Datamap.prototype.ukrTopo = '__UKR__';
    Datamap.prototype.umiTopo = '__UMI__';
    Datamap.prototype.uryTopo = '__URY__';
    Datamap.prototype.usaTopo = {"type":"Topology","transform":{"scale":[0.03514630243024302,0.005240860686068607],"translate":[-178.123152,18.948267]},"objects":{"usa":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":"AL","arcs":[[0,1,2,3,4]],"properties":{"name":"Alabama"}},{"type":"MultiPolygon","id":"AK","arcs":[[[5]],[[6]],[[7]],[[8]],[[9]],[[10]],[[11]],[[12]],[[13]],[[14]],[[15]],[[16]],[[17]],[[18]],[[19]],[[20]],[[21]],[[22]],[[23]],[[24]],[[25]],[[26]],[[27]],[[28]],[[29]],[[30]],[[31]],[[32]],[[33]],[[34]],[[35]],[[36]],[[37]],[[38]],[[39]],[[40]],[[41]],[[42]],[[43]]],"properties":{"name":"Alaska"}},{"type":"Polygon","id":"AZ","arcs":[[44,45,46,47,48]],"properties":{"name":"Arizona"}},{"type":"Polygon","id":"AR","arcs":[[49,50,51,52,53,54]],"properties":{"name":"Arkansas"}},{"type":"Polygon","id":"CA","arcs":[[55,-47,56,57]],"properties":{"name":"California"}},{"type":"Polygon","id":"CO","arcs":[[58,59,60,61,62,63]],"properties":{"name":"Colorado"}},{"type":"Polygon","id":"CT","arcs":[[64,65,66,67]],"properties":{"name":"Connecticut"}},{"type":"Polygon","id":"DE","arcs":[[68,69,70,71]],"properties":{"name":"Delaware"}},{"type":"Polygon","id":"DC","arcs":[[72,73]],"properties":{"name":"District of Columbia"}},{"type":"Polygon","id":"FL","arcs":[[74,75,-2]],"properties":{"name":"Florida"}},{"type":"Polygon","id":"GA","arcs":[[76,77,-75,-1,78,79]],"properties":{"name":"Georgia"}},{"type":"MultiPolygon","id":"HI","arcs":[[[80]],[[81]],[[82]],[[83]],[[84]]],"properties":{"name":"Hawaii"}},{"type":"Polygon","id":"ID","arcs":[[85,86,87,88,89,90,91]],"properties":{"name":"Idaho"}},{"type":"Polygon","id":"IL","arcs":[[92,93,94,95,96,97]],"properties":{"name":"Illinois"}},{"type":"Polygon","id":"IN","arcs":[[98,99,-95,100,101]],"properties":{"name":"Indiana"}},{"type":"Polygon","id":"IA","arcs":[[102,-98,103,104,105,106]],"properties":{"name":"Iowa"}},{"type":"Polygon","id":"KS","arcs":[[107,108,-60,109]],"properties":{"name":"Kansas"}},{"type":"Polygon","id":"KY","arcs":[[110,111,112,113,-96,-100,114]],"properties":{"name":"Kentucky"}},{"type":"Polygon","id":"LA","arcs":[[115,116,117,-52]],"properties":{"name":"Louisiana"}},{"type":"Polygon","id":"ME","arcs":[[118,119]],"properties":{"name":"Maine"}},{"type":"MultiPolygon","id":"MD","arcs":[[[120]],[[-71,121,122,123,124,-74,125,126,127]]],"properties":{"name":"Maryland"}},{"type":"Polygon","id":"MA","arcs":[[128,129,130,131,-68,132,133,134]],"properties":{"name":"Massachusetts"}},{"type":"MultiPolygon","id":"MI","arcs":[[[-102,135,136]],[[137]],[[138,139]],[[140]]],"properties":{"name":"Michigan"}},{"type":"Polygon","id":"MN","arcs":[[-107,141,142,143,144]],"properties":{"name":"Minnesota"}},{"type":"Polygon","id":"MS","arcs":[[-4,145,-116,-51,146]],"properties":{"name":"Mississippi"}},{"type":"Polygon","id":"MO","arcs":[[-97,-114,147,-55,148,-108,149,-104]],"properties":{"name":"Missouri"}},{"type":"Polygon","id":"MT","arcs":[[150,151,-92,152,153]],"properties":{"name":"Montana"}},{"type":"Polygon","id":"NE","arcs":[[-105,-150,-110,-59,154,155]],"properties":{"name":"Nebraska"}},{"type":"Polygon","id":"NV","arcs":[[156,-48,-56,157,-88]],"properties":{"name":"Nevada"}},{"type":"Polygon","id":"NH","arcs":[[-135,158,159,-120,160]],"properties":{"name":"New Hampshire"}},{"type":"Polygon","id":"NJ","arcs":[[161,-69,162,163]],"properties":{"name":"New Jersey"}},{"type":"Polygon","id":"NM","arcs":[[164,165,166,-45,-62]],"properties":{"name":"New Mexico"}},{"type":"Polygon","id":"NY","arcs":[[-133,-67,167,-164,168,169,170]],"properties":{"name":"New York"}},{"type":"Polygon","id":"NC","arcs":[[171,172,-80,173,174]],"properties":{"name":"North Carolina"}},{"type":"Polygon","id":"ND","arcs":[[175,-154,176,-143]],"properties":{"name":"North Dakota"}},{"type":"Polygon","id":"OH","arcs":[[177,-115,-99,-137,178,179]],"properties":{"name":"Ohio"}},{"type":"Polygon","id":"OK","arcs":[[-149,-54,180,-165,-61,-109]],"properties":{"name":"Oklahoma"}},{"type":"Polygon","id":"OR","arcs":[[-89,-158,-58,181,182]],"properties":{"name":"Oregon"}},{"type":"Polygon","id":"PA","arcs":[[-163,-72,-128,183,-180,184,-169]],"properties":{"name":"Pennsylvania"}},{"type":"MultiPolygon","id":"RI","arcs":[[[185,-130]],[[186,-65,-132]]],"properties":{"name":"Rhode Island"}},{"type":"Polygon","id":"SC","arcs":[[187,-77,-173]],"properties":{"name":"South Carolina"}},{"type":"Polygon","id":"SD","arcs":[[-142,-106,-156,188,-151,-176]],"properties":{"name":"South Dakota"}},{"type":"Polygon","id":"TN","arcs":[[189,-174,-79,-5,-147,-50,-148,-113]],"properties":{"name":"Tennessee"}},{"type":"Polygon","id":"TX","arcs":[[-53,-118,190,-166,-181]],"properties":{"name":"Texas"}},{"type":"Polygon","id":"UT","arcs":[[191,-63,-49,-157,-87]],"properties":{"name":"Utah"}},{"type":"Polygon","id":"VT","arcs":[[-134,-171,192,-159]],"properties":{"name":"Vermont"}},{"type":"MultiPolygon","id":"VA","arcs":[[[193,-123]],[[120]],[[-126,-73,-125,194,-175,-190,-112,195]]],"properties":{"name":"Virginia"}},{"type":"MultiPolygon","id":"WA","arcs":[[[-183,196,-90]],[[197]],[[198]]],"properties":{"name":"Washington"}},{"type":"Polygon","id":"WV","arcs":[[-184,-127,-196,-111,-178]],"properties":{"name":"West Virginia"}},{"type":"Polygon","id":"WI","arcs":[[199,-93,-103,-145,200,-140]],"properties":{"name":"Wisconsin"}},{"type":"Polygon","id":"WY","arcs":[[-189,-155,-64,-192,-86,-152]],"properties":{"name":"Wyoming"}}]}},"arcs":[[[2632,3060],[5,-164],[7,-242],[4,-53],[3,-30],[-2,-19],[4,-11],[-5,-25],[0,-24],[-2,-32],[2,-57],[-2,-51],[3,-52]],[[2649,2300],[-14,-1],[-59,0],[-1,-25],[6,-37],[-1,-31],[2,-16],[-4,-28]],[[2578,2162],[-4,-6],[-7,31],[-1,47],[-2,6],[-3,-36],[-1,-34],[-7,9]],[[2553,2179],[-2,291],[6,363],[4,209],[-3,20]],[[2558,3062],[24,1],[50,-3]],[[1324,6901],[1,32],[6,-19],[-1,-32],[-8,4],[2,15]],[[1317,6960],[5,-23],[-3,-33],[-2,11],[0,45]],[[1285,7153],[6,5],[3,-8],[-1,-28],[-6,-6],[-5,17],[3,20]],[[1267,7137],[12,-7],[3,-36],[13,-41],[4,-25],[0,-21],[3,-4],[1,-27],[5,-27],[0,-25],[3,8],[2,-19],[1,-74],[-3,-17],[-7,3],[-3,38],[-2,-3],[-6,28],[-2,-10],[-5,10],[1,-28],[5,7],[3,-10],[-2,-39],[-5,4],[-9,49],[-2,25],[1,26],[-7,-2],[0,20],[5,2],[5,18],[-2,31],[-6,7],[-1,50],[-2,25],[-4,-18],[-2,28],[4,14],[-3,32],[2,8]],[[1263,6985],[5,-12],[4,15],[4,-7],[-4,-28],[-6,8],[-3,24]],[[1258,7247],[-4,19],[5,13],[15,-18],[7,1],[5,-36],[9,-29],[-1,-22],[-5,-11],[-6,5],[-5,-14],[-6,9],[-7,-9],[-1,45],[0,30],[-5,1],[-1,16]],[[1252,7162],[-4,14],[-4,32],[0,24],[3,11],[4,-11],[0,20],[12,-35],[1,-33],[-4,-5],[-3,-37],[3,-11],[-3,-43],[-5,9],[0,-27],[-3,13],[-2,54],[5,25]],[[1207,7331],[8,38],[3,-16],[7,-13],[6,-2],[0,-30],[6,-99],[0,-85],[-1,-22],[-4,13],[-10,84],[-7,25],[3,20],[-3,48],[-8,39]],[[1235,7494],[10,-15],[5,2],[0,-14],[8,-52],[-5,8],[-2,-18],[6,-27],[2,-48],[-6,-13],[-2,-16],[-10,-35],[-3,1],[-1,37],[2,22],[-1,32],[-3,40],[0,21],[-2,51],[-4,22],[-1,38],[7,-36]],[[1203,7324],[4,0],[4,-35],[-2,-24],[-6,-5],[0,38],[0,26]],[[1207,7331],[-5,7],[-3,26],[-6,18],[-5,37],[-6,17],[1,30],[4,10],[1,26],[3,-11],[8,-1],[6,17],[8,-23],[-5,-26],[2,-9],[4,28],[10,-9],[5,-21],[-3,-38],[3,-3],[3,-50],[-7,-7],[-14,41],[0,-42],[-4,-17]],[[883,7871],[-12,-48],[-1,-19],[-9,-12],[2,29],[10,30],[7,34],[3,-14]],[[870,7943],[-2,-39],[-4,-41],[-6,14],[5,47],[7,19]],[[863,9788],[3,-8],[15,-9],[8,5],[10,0],[12,-7],[7,4],[7,-15],[12,-18],[16,-4],[5,10],[11,6],[4,14],[12,2],[0,-9],[7,5],[15,-15],[9,-24],[10,-11],[2,-11],[8,-2],[8,-18],[1,-11],[5,9],[6,-7],[0,-1783],[13,-16],[2,17],[14,-24],[8,30],[18,4],[-3,-52],[4,-17],[10,-17],[2,-27],[29,-101],[4,-63],[6,17],[12,31],[7,1],[3,23],[0,34],[5,0],[1,31],[9,7],[13,26],[13,-45],[-1,-27],[3,-27],[7,-7],[10,-40],[-1,-12],[4,-22],[12,-25],[19,-110],[3,-29],[6,-29],[8,-65],[9,-55],[-3,-23],[9,-9],[-2,-33],[7,-14],[1,-38],[7,2],[14,-40],[9,-7],[5,-19],[4,-5],[1,-19],[9,-5],[3,-23],[-4,-43],[1,-36],[4,-58],[-4,-15],[-6,-53],[-10,-39],[-3,20],[-4,-6],[-3,39],[1,17],[-3,20],[7,21],[-2,7],[-7,-26],[-3,17],[-4,-10],[-12,42],[4,46],[-8,-15],[0,-23],[-6,17],[-1,22],[4,24],[-1,24],[-6,-19],[-6,42],[-3,-8],[-2,36],[5,23],[6,0],[-2,28],[3,36],[-5,-1],[-9,32],[-6,37],[-15,27],[0,77],[-4,9],[1,31],[-5,9],[-8,42],[-2,22],[-12,7],[-14,56],[-6,132],[-3,-30],[1,-27],[6,-53],[-1,-8],[3,-43],[0,-28],[-6,6],[-4,31],[-6,6],[-8,-9],[0,45],[-5,38],[-5,-12],[-17,40],[-2,-11],[10,-13],[7,-31],[3,-1],[1,-25],[4,-30],[-10,-16],[-5,10],[0,-26],[-8,20],[-2,14],[-5,0],[-13,38],[-10,33],[-1,20],[-5,30],[-14,21],[-9,21],[-14,26],[-9,24],[1,26],[2,-9],[3,17],[-3,38],[4,21],[-2,9],[-7,-40],[-14,-26],[-18,10],[-14,24],[-1,18],[-7,-4],[-7,14],[-17,12],[-9,1],[-21,-10],[-8,-7],[-10,27],[-12,12],[-3,17],[-2,28],[-8,-2],[-3,-25],[-15,34],[-2,14],[-15,-27],[-7,-32],[-3,30],[3,17],[4,-5],[14,22],[-2,17],[-6,-8],[-3,22],[-6,3],[-6,55],[-3,-13],[-8,-8],[-3,8],[-3,-18],[-11,6],[-1,-20],[-7,-5],[-3,7],[2,36],[-3,-1],[-5,-38],[7,-12],[1,-27],[4,-30],[-3,-31],[-5,10],[-2,-15],[6,-7],[3,-41],[-8,-9],[-4,9],[-7,-12],[-3,10],[-9,-2],[0,16],[-4,-10],[-3,-20],[-3,18],[-5,-25],[2,-12],[-6,-15],[-6,-2],[-3,-20],[-6,-17],[-4,6],[-5,-21],[-4,1],[-8,-43],[-9,-3],[-3,14],[-5,-23],[-11,17],[2,33],[8,11],[4,-2],[2,13],[8,25],[0,21],[-11,-28],[-9,16],[-1,12],[5,48],[8,34],[1,29],[2,5],[1,30],[-4,34],[10,12],[19,48],[4,-19],[6,-5],[9,20],[-10,26],[-4,20],[-7,-2],[-5,9],[-2,-8],[-9,-14],[-4,-26],[-9,-6],[-9,-30],[-1,-20],[-7,-11],[-2,-22],[-5,-13],[-2,-39],[-10,-25],[5,-20],[-4,-29],[-9,-5],[-1,-38],[-8,-13],[-3,15],[-4,-29],[-5,-1],[1,-21],[-11,-13],[-2,-57],[12,-3],[10,-16],[3,-19],[-4,-30],[-7,-19],[-6,-1],[0,-17],[-4,-6],[1,-21],[-4,-31],[-9,-29],[-5,0],[-5,-11],[-5,2],[-4,-11],[2,-16],[-7,-8],[-2,-23],[-5,14],[-5,-45],[-9,4],[1,-24],[-6,6],[-3,-11],[0,-32],[-6,-50],[-10,-6],[-7,-23],[-2,-13],[-5,18],[-8,-48],[-2,13],[-5,-4],[-1,-27],[-5,-10],[-6,4],[-4,-27],[8,-9],[-9,-60],[-25,-20],[-6,-54],[-2,12],[1,33],[-5,6],[-6,-13],[-1,-14],[-10,-22],[-4,-25],[-1,18],[-2,-21],[-6,14],[-10,-33],[-8,2],[1,25],[-4,24],[-3,-20],[1,-21],[-11,-64],[-3,16],[-1,-24],[-8,4],[-1,38],[-4,8],[-2,-14],[4,-16],[-2,-27],[-5,-13],[-5,29],[-5,2],[-1,-11],[5,-17],[-9,-27],[6,-7],[0,-13],[-5,9],[-7,-25],[-15,1],[-7,-16],[0,-13],[-8,-15],[-6,6],[-2,35],[6,12],[4,43],[6,1],[13,28],[10,1],[4,-27],[3,20],[-1,23],[6,10],[7,0],[8,50],[10,45],[12,40],[15,18],[6,-9],[6,12],[1,-17],[-3,-19],[4,-14],[1,23],[7,2],[2,-15],[5,-5],[0,18],[-8,15],[0,11],[5,49],[6,28],[9,27],[15,24],[10,35],[5,-13],[4,5],[-1,22],[1,21],[8,44],[11,28],[8,38],[0,21],[7,148],[11,40],[-1,31],[-27,-45],[-8,6],[-2,18],[-5,9],[-1,21],[-4,-10],[-3,-32],[5,-41],[-6,-18],[-5,7],[-9,64],[-6,33],[-4,0],[-2,-24],[-3,-4],[-4,19],[-5,4],[-2,32],[-16,-37],[-13,-26],[-1,-14],[-11,-22],[-6,20],[5,23],[-1,54],[-4,57],[7,24],[-6,49],[-5,27],[-4,39],[-6,17],[-2,-34],[-7,-8],[-12,-22],[-14,-9],[-7,2],[-7,12],[-1,30],[-5,9],[-9,42],[-8,8],[-8,46],[6,21],[1,39],[-5,-8],[0,24],[2,19],[-6,18],[0,-19],[-7,8],[-1,32],[-6,4],[-3,22],[0,27],[-5,-12],[-1,26],[7,6],[-6,30],[10,2],[0,35],[2,24],[18,77],[4,23],[3,-5],[-2,33],[7,55],[6,22],[11,9],[8,-9],[12,-33],[8,4],[11,32],[11,49],[6,6],[1,-13],[13,0],[12,10],[11,52],[0,12],[-5,48],[-1,28],[-8,31],[-3,26],[8,-7],[8,22],[0,20],[-10,39],[-8,-30],[-7,5],[-6,-17],[-8,-4],[-2,-11],[-9,-17],[-2,-28],[-5,-12],[-2,34],[-5,7],[-4,-26],[-2,12],[-10,19],[-20,-1],[-14,-21],[-6,-3],[-11,13],[-22,14],[-6,12],[-3,19],[2,26],[-8,22],[2,24],[5,12],[-2,31],[-8,0],[-6,8],[-13,6],[-7,16],[-10,16],[-1,19],[16,27],[20,43],[15,27],[8,-15],[8,-3],[2,21],[-5,3],[-1,18],[20,29],[22,22],[12,2],[7,-7],[-4,-32],[2,-22],[-3,-15],[4,-26],[8,5],[10,-5],[11,6],[4,-10],[7,-2],[7,10],[8,-11],[9,42],[5,2],[5,-8],[2,24],[-12,11],[-11,-9],[1,31],[-8,34],[-10,10],[-2,30],[7,8],[9,-31],[-1,-24],[4,-18],[10,-22],[2,23],[-11,30],[5,54],[-4,10],[-11,-12],[-11,3],[-2,10],[-6,-10],[-24,23],[0,24],[-7,54],[-6,19],[-9,17],[-19,46],[-9,18],[-8,4],[-13,31],[-12,18],[-1,6],[9,10],[4,29],[1,59],[25,-4],[31,13],[8,11],[12,29],[12,45],[3,45],[5,38],[10,33],[5,24],[13,38],[2,-10],[11,-3],[16,20],[10,21],[24,64],[9,4],[1,-10],[9,7],[9,-2],[18,9],[17,28],[17,58],[7,13],[2,-10],[26,-24],[2,-17],[-9,-22],[-4,-1],[0,-29],[14,9],[0,16],[6,14],[2,-8],[5,33],[13,-30],[-2,-23],[8,-6],[5,-14],[7,22],[13,1],[7,7],[18,-7],[10,-8],[-5,-45],[17,-12],[2,-11],[16,-20],[1,9],[12,13],[11,-1],[0,-11],[7,-1],[7,15],[11,2],[9,-6],[11,-16],[5,3],[7,-22],[4,9],[7,-7],[5,-13]],[[717,7456],[-1,-8],[-9,13],[7,49],[6,4],[4,45],[5,-40],[4,14],[8,-22],[0,-31],[-11,-4],[-5,-13],[-8,-7]],[[688,7363],[8,25],[-8,6],[0,22],[6,14],[5,-10],[0,-22],[3,15],[0,32],[5,-15],[1,21],[5,-12],[5,0],[5,11],[7,-20],[0,-55],[9,4],[-6,-37],[-11,15],[4,-24],[-3,-20],[-6,10],[0,-38],[-8,-10],[-3,-16],[-5,15],[-6,-40],[-4,-4],[-5,-18],[-2,43],[-6,-23],[-1,13],[-6,14],[0,39],[-6,15],[4,45],[11,28],[7,-2],[1,-21]],[[671,7185],[-6,-39],[-2,6],[8,33]],[[640,7055],[4,-2],[-1,-40],[-8,6],[-1,13],[6,23]],[[519,6933],[-2,-41],[-9,-33],[5,51],[2,-5],[4,28]],[[501,6947],[5,0],[0,-20],[-5,-23],[-5,15],[-3,-14],[-2,35],[2,12],[8,-5]],[[451,6875],[1,-16],[-3,-11],[-3,18],[5,9]],[[447,8527],[-4,-19],[-2,16],[6,3]],[[436,6781],[6,-7],[-1,-16],[-5,1],[0,22]],[[358,6745],[2,-22],[-5,-10],[-1,23],[4,9]],[[352,6718],[-8,-21],[-2,14],[3,19],[7,-12]],[[335,7902],[6,7],[2,-14],[5,3],[6,-12],[1,-54],[-3,-18],[-7,-11],[-2,-18],[-11,20],[-5,-1],[-10,28],[-4,0],[-6,15],[-3,25],[4,7],[10,-7],[5,20],[5,2],[3,14],[4,-6]],[[334,6690],[5,-14],[-10,-36],[1,-6],[12,26],[0,-15],[-5,-17],[-8,-12],[-1,-18],[-8,-18],[-7,-1],[-5,-18],[-9,-16],[-5,17],[9,20],[3,-3],[8,16],[-2,19],[4,20],[6,-9],[1,12],[-7,4],[-4,14],[4,23],[11,13],[2,-26],[5,25]],[[266,6527],[10,37],[1,16],[4,17],[7,9],[3,-10],[1,-25],[-12,-27],[-6,-40],[-6,-13],[-2,36]],[[238,6477],[2,-19],[-8,-1],[-1,13],[7,7]],[[227,7303],[-4,-18],[-1,18],[5,0]],[[212,6440],[2,-18],[-5,-13],[-1,19],[4,12]],[[182,8542],[22,-28],[13,24],[6,-2],[5,-14],[2,-23],[11,-12],[4,-12],[15,-5],[8,-8],[-4,-28],[-7,6],[-8,-5],[-4,-13],[-4,-28],[-5,26],[-6,18],[-6,2],[-3,20],[-15,25],[-6,1],[-11,-22],[-7,11],[-4,23],[4,44]],[[162,6381],[0,-22],[-5,-4],[1,19],[4,7]],[[128,6335],[4,-8],[10,1],[1,-7],[-13,-9],[-2,23]],[[108,6360],[0,19],[4,7],[6,-19],[-2,-17],[-4,1],[1,-20],[-5,-2],[-12,-21],[-6,6],[2,15],[7,-2],[9,33]],[[47,6279],[5,3],[0,-24],[-6,3],[-8,-28],[-4,37],[4,1],[0,29],[5,1],[0,-21],[4,-1]],[[28,6296],[3,-9],[-2,-32],[-5,-10],[0,20],[4,31]],[[0,6291],[5,-1],[4,-23],[-4,-27],[-5,51]],[[9993,6496],[6,-13],[0,-19],[-11,-12],[-8,31],[0,15],[13,-2]],[[1966,3444],[-1,-1081]],[[1965,2363],[-57,0],[-34,71],[-73,150],[3,43]],[[1804,2627],[6,8],[1,16],[-1,36],[-4,1],[-2,71],[6,27],[0,28],[-1,45],[4,34],[4,12],[4,25],[-6,27],[-4,51],[-5,31],[0,24]],[[1806,3063],[2,26],[0,36],[-3,36],[-2,112],[11,7],[3,-23],[3,1],[3,33],[0,153]],[[1823,3444],[101,2],[42,-2]],[[2515,3253],[-1,-35],[-4,-11],[-1,-29],[-5,-31],[0,-46],[-3,-34],[-3,-5]],[[2498,3062],[2,-17],[-4,-14],[-2,-33],[-3,-8],[0,-38],[-5,-10],[0,-13],[-6,-31],[2,-21],[-5,-30],[-5,-59],[5,-25],[-2,-16],[1,-39],[-2,-26]],[[2474,2682],[-69,3],[-13,0]],[[2392,2685],[0,101],[-4,8],[-5,-9],[-3,18]],[[2380,2803],[1,335],[-5,211]],[[2376,3349],[4,0],[123,-1],[2,-36],[-4,-23],[-4,-36],[18,0]],[[1654,4398],[0,-331],[0,-241],[36,-171],[35,-169],[27,-137],[20,-101],[34,-185]],[[1804,2627],[-38,-18],[-30,-16],[-4,25],[0,40],[-2,47],[-4,33],[-9,46],[-12,43],[-2,-12],[-4,8],[1,18],[-5,39],[-7,-8],[-12,28],[-2,23],[-8,28],[-9,-1],[-7,13],[-10,-6],[-5,26],[1,53],[-1,8],[1,38],[-8,28],[0,39],[-3,2],[-4,33],[-4,8],[-1,20],[-11,79],[-5,23],[-1,61],[2,-5],[2,37],[-4,33],[-5,-4],[-7,30],[-2,24],[0,23],[-3,31],[0,50],[5,0],[-2,70],[-2,-7],[-1,-35],[-5,-7],[-7,26],[-1,45],[-4,35],[-6,22],[-3,25],[-9,50],[2,14],[-4,64],[2,35],[-3,54],[-7,52],[-7,29],[-2,35],[7,83],[2,29],[-2,22],[3,57],[-2,52],[-3,13],[1,42]],[[1534,4399],[28,1],[24,1],[38,-3],[30,0]],[[2107,4208],[57,0],[0,-191]],[[2164,4017],[1,-574]],[[2165,3443],[-28,1]],[[2137,3444],[-38,-1],[-72,0],[-15,1],[-46,0]],[[1966,3444],[0,223],[-1,21],[0,162],[0,357]],[[1965,4207],[32,1],[63,-1],[47,1]],[[3025,4400],[0,-113],[-2,-18]],[[3023,4269],[-2,3],[-12,-14],[-15,4],[-7,-26],[-7,-9],[-8,-22]],[[2972,4205],[-2,22],[7,21],[-2,16],[2,144]],[[2977,4408],[12,-2],[36,-3],[0,-3]],[[2922,3980],[-2,-23]],[[2920,3957],[-3,-13],[0,-30],[5,-29],[1,-47],[6,-49],[3,-2],[1,-66]],[[2933,3721],[-19,2],[-2,241]],[[2912,3964],[5,21],[5,-5]],[[2876,3786],[-2,27]],[[2874,3813],[2,12],[4,-19],[-4,-20]],[[2649,2300],[4,-55],[39,-13],[37,-14],[1,-41],[4,1],[1,39],[-1,35],[2,15],[7,-16],[8,-7]],[[2751,2244],[1,-83],[4,-93],[8,-122],[13,-131],[-2,-9],[1,-61],[5,-68],[8,-137],[2,-42],[0,-44],[-3,-158],[-3,-3],[-3,-49],[1,-16],[-5,-36],[-2,9],[-6,-15],[-9,-8],[-2,20],[1,29],[-7,85],[-5,15],[-4,-11],[-3,47],[-1,38],[-6,43],[-2,28],[1,41],[-3,8],[1,-24],[-3,-7],[-9,104],[-4,26],[9,76],[-6,-4],[-4,-24],[-3,38],[5,104],[1,87],[-4,21],[-1,28],[-5,6],[-7,46],[-5,19],[0,28],[-4,11],[-3,31],[-11,42],[-9,-10],[0,-29],[-3,5],[-12,-35],[-12,-9],[0,21],[-3,25],[-15,57],[-10,24],[-10,6],[-8,-4],[-17,-18]],[[2703,3063],[-6,-41],[0,-20],[9,-40],[3,3],[5,-42],[1,-22],[4,-40],[7,-24],[3,-35],[8,-33],[0,-22],[5,-35],[7,-29],[2,-32],[1,-40],[3,-14],[5,-51],[0,-33],[7,-16]],[[2767,2497],[-7,-65],[-2,-34],[-3,-29],[0,-30],[-3,-14],[-1,-81]],[[2632,3060],[37,1]],[[2669,3061],[20,-1],[14,3]],[[640,0],[-7,17],[-1,16],[1,43],[-5,73],[4,24],[2,34],[-2,22],[1,23],[8,-27],[9,-20],[5,-29],[0,-26],[8,-40],[-5,-34],[-8,-15],[-7,-25],[-3,-36]],[[613,397],[3,-26],[4,11],[9,-30],[-1,-27],[-9,-14],[-2,6],[-1,33],[-5,7],[-1,19],[3,21]],[[602,432],[-3,-20],[-7,0],[2,22],[8,-2]],[[574,525],[3,-45],[-2,-26],[-6,-5],[-4,54],[4,1],[5,21]],[[531,626],[3,-2],[2,-20],[-1,-28],[-4,-18],[-9,22],[1,31],[8,15]],[[1908,4871],[0,-472]],[[1908,4399],[-31,-1],[-54,0]],[[1823,4398],[-85,1]],[[1738,4399],[0,349],[4,62],[-2,16],[-6,3],[-2,26],[6,68],[3,6],[3,29],[-1,17],[4,23],[1,34],[6,56],[-2,26],[-7,14],[-4,32]],[[1741,5160],[0,34],[-3,33],[0,16],[0,255],[0,236]],[[1738,5734],[28,0]],[[1766,5734],[0,-195],[9,-54],[1,-52],[5,-23],[6,-8],[0,-14],[11,-51],[1,-21],[8,-20],[0,-12],[8,1],[-4,-71],[-1,-45],[3,-29],[-5,-21],[2,-20],[-1,-21],[6,-20],[7,26],[3,21],[5,-19],[-1,-15],[3,-37],[5,-39],[3,-13],[0,-37],[3,-16],[6,-2],[4,-61],[3,-11],[3,18],[9,-1],[7,17],[3,-10],[7,9],[2,-11],[5,8],[7,39],[4,-33],[5,-20]],[[2489,4496],[53,-3],[28,0]],[[2570,4493],[-1,-37],[4,-43],[5,-70]],[[2578,4343],[0,-450],[-3,-35],[3,-40],[1,-34],[-4,-27],[-1,-25],[-5,-41],[-3,-3],[0,-24],[-2,-9],[-1,-45],[0,-13]],[[2563,3597],[-3,-27],[2,-34],[-11,-17],[-1,-20],[2,-25],[-3,-16],[-11,29],[-3,-2],[-4,-33],[1,-11]],[[2532,3441],[-5,2],[-6,55],[2,12],[-2,37],[0,29],[-9,41],[-3,-4],[-3,25],[-9,38],[0,31],[5,49],[-1,18],[3,23],[-4,13],[-6,9],[-3,-18],[-3,11],[-1,63],[-10,41],[-9,49],[-3,58],[-1,39],[3,27]],[[2467,4089],[0,35],[8,21],[1,29],[4,19],[0,33],[-4,27],[2,34],[11,9],[9,24],[0,29],[4,13],[1,37],[0,24],[-7,18],[-1,20],[-6,35]],[[2655,4340],[0,-228],[0,-266]],[[2655,3846],[-2,-9],[2,-52],[-5,-1],[-5,-18],[-8,9],[1,-38],[-5,-16],[-2,-24],[-5,-9],[-3,-48],[-3,-13],[-6,18],[-1,22],[-7,-24],[1,-21],[-7,-7],[-1,19],[-8,-19],[-2,-20],[-7,28],[-4,-6],[-2,13],[-3,-13],[-7,-2],[-3,-18]],[[2578,4343],[3,-12],[8,0],[9,22]],[[2598,4353],[23,0],[34,0],[0,-13]],[[2473,4685],[0,-28],[4,-19],[-3,-23],[1,-43],[2,-30],[10,-22],[2,-24]],[[2467,4089],[-3,7],[-6,38],[-3,-1],[-40,-5],[-39,-2],[-33,3]],[[2343,4129],[-3,25],[2,49],[-3,43],[0,48],[-5,17],[-1,26],[2,23],[-2,33],[-4,13],[-5,86]],[[2324,4492],[-5,41],[2,29],[1,37],[2,14],[-3,19],[1,33],[-2,16],[4,4]],[[2324,4685],[144,0],[5,0]],[[2356,4017],[3,-18],[9,-14],[-6,-56],[4,-18],[4,-45],[6,-10],[0,-412]],[[2376,3444],[-156,0],[-55,-1]],[[2164,4017],[5,0],[187,0]],[[2718,3716],[-1,-57],[4,-37],[4,-28],[2,-22],[5,-22],[4,-3]],[[2736,3547],[-11,-51],[-11,-29],[0,-14],[-4,-13],[0,-16],[-6,-8],[-1,-21],[-16,-27]],[[2687,3368],[0,-3],[-24,2],[-22,6],[-5,-2],[-32,8],[-36,-5],[-6,9],[1,-35],[-36,2],[-3,-2]],[[2524,3348],[1,24],[5,-8],[2,77]],[[2655,3846],[11,0],[5,-40],[1,-17],[9,-7],[6,-26],[5,13],[10,-14],[4,19],[4,6],[1,-32],[3,-6],[4,-26]],[[2474,2682],[3,-22],[-2,-9],[-1,-38],[5,-24],[0,-57],[-3,-44],[-7,-27],[-2,-43],[-2,4],[-1,-70],[-3,-2],[2,-37],[-2,-14],[54,0],[-3,-63],[4,-41],[1,-32],[4,-20]],[[2521,2143],[-9,-26],[0,-19],[7,-12],[3,30],[6,-30],[-1,-24],[-3,-11],[-7,10],[1,-18],[-2,-27],[5,-24],[9,-7],[3,-29],[3,-4],[-5,-32],[-5,6],[-4,33],[-10,18],[0,33],[-6,-11],[1,-27],[-3,-25],[-3,-4],[-3,28],[-7,1],[-2,-29],[-4,-9],[-5,18],[-4,2],[-3,47],[-7,21],[-2,-3],[-3,40],[-7,-5],[0,24],[-8,-23],[1,-18],[-5,-17],[-9,8],[-10,27],[-7,11],[-16,-9],[-2,-8]],[[2398,2049],[-2,19],[6,68],[-2,37],[2,20],[-1,26],[3,19],[3,50],[0,40],[-8,78],[0,41],[-7,42],[0,196]],[[3046,5029],[12,26],[-2,13],[5,30],[4,13],[-1,12],[5,18],[-1,33],[2,50],[5,17],[1,53],[22,147],[6,-7],[0,-35],[4,-13],[9,21],[6,0],[4,14],[8,-31],[4,-25],[1,-214],[-1,-51],[10,-14],[-2,-22],[3,-21],[-2,-18],[4,-30],[5,7],[5,-68],[-6,-31],[-3,12],[-3,-21],[-4,5],[0,-18],[-6,2],[-8,-40],[-2,28],[-3,2],[1,-30],[-6,-15],[-2,24],[-3,-12],[-7,0],[0,28],[-5,-6],[1,-20],[-4,-42],[1,-12],[-6,-23],[-5,9],[-3,-24],[-4,-3],[-4,-20],[-4,4],[-1,21],[-7,-34],[2,-21],[-5,-7],[0,-18],[-5,-22],[-5,-50]],[[3056,4600],[-3,14],[0,19],[-4,22],[-2,250],[-1,124]],[[2904,3626],[2,0],[-1,0],[-1,0]],[[2933,3721],[-6,-80]],[[2927,3641],[-4,-3],[-8,-12]],[[2915,3626],[-6,-8],[0,31],[-2,13],[3,13],[-4,32],[-2,-14],[-6,3],[-2,35],[2,0],[0,45],[2,18],[-2,60],[3,36],[5,6],[0,37],[-3,-5],[0,-18],[-8,-25],[-2,-21],[0,-56],[-3,-26],[1,-44],[4,-30],[-1,-23],[3,-23],[-2,-16],[-6,30],[-10,15],[-2,29],[-6,-16],[-2,23],[5,29]],[[2874,3756],[2,30]],[[2874,3813],[-4,18],[-6,10],[0,28],[-3,15],[-4,4]],[[2857,3888],[-4,53],[-4,0],[-5,18],[-3,-15],[-5,1],[-1,-21],[-8,14],[-6,-28],[-3,6],[-6,-33],[-6,-17],[1,98]],[[2807,3964],[105,0]],[[3053,4565],[1,-34],[-1,-27],[-5,-25],[0,-29],[6,-4],[4,-31],[0,-24],[3,-6],[0,-22],[8,-19],[9,18],[-2,-26],[-13,-23],[-5,-1],[-3,18],[-5,-6],[0,-13],[-5,-9]],[[3045,4302],[-3,35]],[[3042,4337],[0,6]],[[3042,4343],[-3,14],[-2,45],[-4,0],[-8,-2]],[[2977,4408],[0,7],[6,126]],[[2983,4541],[23,-3]],[[3006,4538],[34,-7],[3,18],[7,19],[3,-3]],[[2598,4353],[5,25],[4,43],[4,26],[3,36],[1,52],[0,57],[-9,111],[3,42],[-2,50],[6,51],[2,43],[-1,23],[5,9],[0,31],[8,9],[5,34],[0,-69],[3,-3],[3,35],[1,58],[2,15],[8,9],[-3,41],[5,35],[7,2],[7,-22],[7,-3],[3,-28],[6,-2],[9,-25],[3,1],[4,-41],[-3,-21],[3,-29],[2,-32],[-2,-71],[-6,-18],[-1,-37],[-7,-12],[-4,-44],[2,-17],[6,-15],[6,24],[6,49],[10,19],[5,-15],[3,-27],[3,-80],[0,-39],[3,-48],[-3,-69],[-4,-11],[-1,25],[-3,-7],[-3,-58],[-6,-21],[-2,-44],[-7,-37],[0,-16]],[[2694,4347],[-39,-7]],[[2635,5110],[1,-23],[-4,-4],[1,33],[2,-6]],[[2496,5270],[11,20],[5,23],[12,9],[8,29],[4,1],[3,20],[9,28],[4,24],[7,15],[6,-13],[-11,-59],[-2,-19],[0,-36],[5,27],[10,-4],[8,-19],[7,-52],[3,-10],[7,9],[2,-12],[7,-6],[16,44],[8,4],[10,-2],[7,15],[6,1],[1,-54],[5,-7],[6,8],[2,-12],[4,16],[8,5],[1,-67],[3,-28],[6,-8],[1,19],[5,0],[3,-20],[-3,-14],[-15,12],[-8,-8],[-8,23],[-2,-21],[1,-18],[-4,4],[-5,27],[-9,15],[-5,1],[-4,-25],[-8,-6],[-8,5],[-3,-10],[-1,-21],[-9,-18],[1,25],[-4,5],[-2,-26],[-6,-1],[-3,-11],[-5,-45],[-8,-58],[1,-5]],[[2576,4989],[-4,20],[2,27],[-7,4],[3,26],[0,34],[-5,23],[-4,24],[-12,19],[-4,-7],[-12,29],[-29,38],[-3,33],[-5,11]],[[2541,5539],[-7,-24],[-4,-3],[1,19],[18,45],[-4,-31],[-4,-6]],[[2324,4685],[0,343],[-7,22],[-5,36],[8,41],[1,22]],[[2321,5149],[-1,76],[-4,20],[-2,42],[0,51],[-1,8],[-1,123],[-5,65],[-3,36],[0,77],[1,27],[-3,60]],[[2302,5734],[59,0],[0,73],[5,-2],[4,-14],[4,-100],[3,-11],[9,-3],[1,-10],[11,-4],[1,-21],[10,5],[0,9],[7,10],[6,-4],[8,-16],[2,-19],[4,2],[4,-43],[2,18],[7,8],[1,-18],[9,-12],[0,-17],[4,-14],[8,8],[5,18],[8,12],[2,-28],[5,6],[6,-6],[6,4],[8,-24],[7,4],[0,-10],[-10,-24],[-13,-19],[-9,-20],[-12,-49],[-5,-31],[-8,-34],[-13,-46],[2,-16]],[[2450,5296],[-2,9],[-6,-16],[0,-113],[-2,-11],[-8,-16],[-6,-41],[-1,-27],[3,-2],[4,-24],[-3,-29],[0,-33],[-2,-70],[8,-34],[6,-3],[3,-21],[8,-21],[2,-25],[8,-33],[5,-7],[5,-42],[-1,-30],[2,-22]],[[2553,2179],[-3,-8],[-7,4],[-3,12],[-7,-8],[-9,-22],[-3,-14]],[[2498,3062],[53,0],[7,0]],[[2524,3348],[-2,0],[-2,0],[1,-47],[-6,-48]],[[2376,3349],[0,95]],[[2356,4017],[-7,50],[-6,62]],[[2108,5151],[0,-181],[-1,0]],[[2107,4970],[-53,1],[-90,0],[-56,0],[0,-100]],[[1766,5734],[130,-1],[58,1],[154,0]],[[2108,5734],[0,-217],[0,-366]],[[2107,4208],[0,382]],[[2107,4590],[21,0],[49,-1],[88,0],[1,-10],[15,-34],[4,19],[4,-4],[13,0],[15,-36],[2,-27],[5,-5]],[[1823,4398],[0,-954]],[[1654,4398],[37,-1],[47,2]],[[3006,4538],[-2,14],[0,28],[3,11],[-1,27],[3,81],[5,37],[2,43],[3,16],[-1,47],[10,17],[5,33],[-3,31],[4,32],[0,18]],[[3034,4973],[4,49],[6,-5],[2,12]],[[3056,4600],[-3,-35]],[[2962,4152],[-5,-13],[-2,-29],[8,-14],[0,-22],[-3,-103],[-9,-76],[-6,-22],[-5,-48],[-3,31],[-8,16],[-10,42],[-1,28],[0,4],[2,11]],[[2922,3980],[8,15],[0,15],[9,31],[2,17],[-9,39],[0,24],[-3,6],[-1,22],[5,33],[-3,20],[7,40],[2,21],[4,13]],[[2943,4276],[13,-41],[9,-28],[-3,-55]],[[2137,3444],[0,-95]],[[2137,3349],[-1,0],[0,-474],[0,-193],[0,-192],[-101,0],[-1,-18],[3,-22]],[[2037,2450],[-48,0],[0,-87],[-24,0]],[[2972,4205],[13,-15],[2,11],[10,0],[6,6],[8,31],[1,-22],[5,-10],[-11,-28],[-22,-42],[-9,-8],[-6,2],[-5,-9],[-2,31]],[[2943,4276],[-2,14],[-4,1],[-5,32],[1,29],[-4,22],[-2,-2],[-3,27],[-125,0],[0,48],[0,3]],[[2799,4450],[17,54],[3,26],[5,18],[-2,32],[-2,7],[-2,52],[17,22],[15,-1],[6,-5],[6,-21],[4,8],[12,-1],[8,14],[8,34],[5,1],[0,52],[3,31],[-7,21],[2,24],[11,32],[4,28],[14,64],[13,32],[19,-5],[23,4]],[[2981,4973],[1,-39],[-2,-36],[3,-34],[-1,-37],[-3,-39],[2,-52],[-1,-16],[4,-31],[-1,-132],[0,-16]],[[2909,3359],[4,-77],[-8,8],[-1,-10],[-10,-11],[-1,-11],[-7,-3],[0,-13],[8,9],[1,-8],[9,9],[3,-18],[5,8],[2,-46],[-2,-22],[-3,-2],[-8,-47],[-9,-2],[-2,-33],[4,-32],[4,-6],[-6,-54],[-6,7],[-9,-6],[-6,-11],[-10,-37],[-7,-48],[-4,-60],[-6,13],[-11,-12]],[[2833,2844],[-32,181],[-32,4],[1,21],[-5,33],[-3,-12],[0,20],[-35,10],[-8,-8],[-6,-17],[-10,-13]],[[2669,3061],[1,45],[5,4],[3,31],[7,29],[7,1],[7,29],[8,10],[6,43],[4,13],[1,-19],[11,37],[5,-8],[4,36],[5,9],[1,45]],[[2744,3366],[20,-5],[19,-3],[23,-1],[103,2]],[[2321,5149],[-213,2]],[[2108,5734],[194,0]],[[2777,4138],[-4,-10],[2,-21],[0,-29],[-4,-46],[-3,-70],[-11,-62],[-3,-8],[-4,12],[-3,-27],[-3,1],[-4,-36],[1,-22],[-3,-18],[-4,29],[-5,-46],[1,-29],[-3,-11],[-1,-25],[-8,-4]],[[2694,4347],[11,-26],[3,-15],[3,14],[6,-30],[4,-9],[14,25],[7,-6],[9,36],[12,34],[14,24]],[[2777,4394],[0,-256]],[[2380,2803],[-11,21],[-3,22],[-7,18],[-2,-16],[-8,1],[-1,10],[-7,-19],[-3,11],[-6,-10],[-5,-29],[-2,17],[-6,14],[-7,0],[-2,21],[-7,-42],[-2,24],[-3,-8],[-3,16],[-7,15],[-5,-25],[-2,26],[-4,3],[-2,21],[-6,8],[-3,-18],[-3,16],[-5,-2],[-6,17],[-6,-2],[-2,36],[-9,2],[-4,-6],[-6,37],[-2,-3],[0,370],[-52,0],[-34,0]],[[1534,4399],[-4,22],[-2,61],[0,43],[-4,33],[3,32],[2,51],[4,54],[2,48],[3,162],[0,22],[3,71],[1,99],[-2,54],[1,32],[12,29]],[[1553,5212],[5,-22],[4,5],[3,2],[6,-20],[3,-23],[1,-57],[15,-21],[12,30],[8,3],[9,-10],[1,-13],[16,27],[3,-9],[9,5],[7,19],[12,17],[12,4],[4,12],[58,-1]],[[2807,3964],[-30,0],[0,174]],[[2777,4394],[5,11],[17,45]],[[3045,4302],[-6,-4],[3,39]],[[3042,4343],[-4,3],[-3,-28],[-1,-40],[-11,-9]],[[2833,2844],[-5,-10],[-6,-31],[-6,-49],[-1,-40],[-5,-31],[-6,0],[-2,-23],[-6,-25],[-4,-28],[-6,-11],[-6,-29],[-1,-14],[-6,-16],[-6,-40]],[[2107,4590],[0,380]],[[2687,3368],[57,-2]],[[2398,2049],[-5,-1],[-14,-26],[-6,15],[-1,31],[-3,-22],[-3,5],[-1,-27],[3,-11],[0,-36],[-5,-37],[-9,-47],[-17,-51],[-2,9],[-5,-13],[0,12],[-7,-9],[-3,24],[-2,-5],[7,-49],[-5,-16],[-5,10],[-1,-35],[-7,-35],[-6,-66],[-4,-69],[-3,5],[-1,-25],[3,6],[-2,-50],[-2,-2],[0,-28],[3,-16],[1,-57],[3,-20],[0,-37],[3,-32],[-9,-20],[-3,25],[-7,10],[-9,-3],[-8,32],[-5,3],[-5,25],[-6,8],[-4,24],[-2,58],[-5,34],[0,30],[-2,31],[1,27],[-4,30],[-3,4],[-5,27],[-1,34],[-5,32],[-6,26],[-3,57],[-2,16],[-4,46],[-1,38],[-4,27],[-6,24],[-1,16],[-6,15],[-4,42],[-13,9],[-7,-2],[-7,15],[-1,-20],[-7,-6],[-5,-40],[-3,-64],[-2,-1],[-4,-37],[-5,-1],[-7,29],[-17,47],[-4,25],[-6,24],[-5,54],[-1,49],[-4,40],[-2,35],[-3,22],[-11,32],[-6,44],[-4,15],[-6,38],[-7,20],[-5,50],[-4,11]],[[1908,4399],[0,-192],[57,0]],[[2981,4973],[30,-2],[23,2]],[[2927,3641],[-4,-32],[-3,-12],[-3,-44],[-6,-71],[-5,-15],[-1,27],[2,58],[8,74]],[[2874,3756],[-4,-8],[-2,-28],[1,-19],[8,6],[1,-31],[10,-12],[3,-24],[8,-26],[-4,-54],[4,-41],[-4,-20],[-1,-24],[4,-15],[-4,-23],[-6,30],[-1,-10],[5,-22],[14,-5],[3,-71]],[[2736,3547],[-1,-16],[4,-32],[5,-16],[4,1],[5,25],[4,-20],[7,11],[13,36],[1,-11],[5,17],[0,34],[4,30],[5,29],[2,34],[6,36],[2,44],[5,-27],[4,-8],[3,16],[6,68],[4,-17],[13,77],[2,57],[15,-64],[3,37]],[[1553,5212],[-5,7],[-4,-12],[-6,17],[1,26],[4,14],[-6,40],[-4,103],[-2,14],[-3,73],[-6,28],[-2,56],[3,38],[6,-18],[11,-24],[8,1],[8,-9],[8,9],[3,-16],[7,1],[5,-42],[3,3],[1,-56],[2,-52],[3,6],[-3,43],[1,43],[4,44],[-3,18],[-1,31],[-3,35],[2,25],[-2,29],[-5,4],[-4,22],[1,21],[163,0]],[[1576,5602],[4,9],[0,-39],[-5,15],[1,15]],[[1568,5655],[3,25],[4,-30],[-1,-27],[-7,8],[1,24]],[[2576,4989],[-1,-23],[-6,-4],[-4,-44],[-2,-30],[3,-6],[5,20],[4,38],[6,15],[5,48],[6,10],[-1,-25],[-4,-23],[-8,-79],[-2,-44],[0,-32],[-3,-10],[-2,-43],[1,-37],[-3,-24],[-3,-59],[0,-47],[4,-42],[-1,-55]],[[2450,5296],[6,-2],[20,33],[8,17],[2,-13],[-4,-25],[9,-33],[5,-3]]]};
    Datamap.prototype.usgTopo = '__USG__';
    Datamap.prototype.uzbTopo = '__UZB__';
    Datamap.prototype.vatTopo = '__VAT__';
    Datamap.prototype.vctTopo = '__VCT__';
    Datamap.prototype.venTopo = '__VEN__';
    Datamap.prototype.vgbTopo = '__VGB__';
    Datamap.prototype.virTopo = '__VIR__';
    Datamap.prototype.vnmTopo = '__VNM__';
    Datamap.prototype.vutTopo = '__VUT__';
    Datamap.prototype.wlfTopo = '__WLF__';
    Datamap.prototype.wsbTopo = '__WSB__';
    Datamap.prototype.wsmTopo = '__WSM__';
    Datamap.prototype.yemTopo = '__YEM__';
    Datamap.prototype.zafTopo = '__ZAF__';
    Datamap.prototype.zmbTopo = '__ZMB__';
    Datamap.prototype.zweTopo = '__ZWE__';
  
    /**************************************
                  Utilities
    ***************************************/
  
    // Convert lat/lng coords to X / Y coords
    Datamap.prototype.latLngToXY = function(lat, lng) {
       return this.projection([lng, lat]);
    };
  
    // Add <g> layer to root SVG
    Datamap.prototype.addLayer = function( className, id, first ) {
      var layer;
      if ( first ) {
        layer = this.svg.insert('g', ':first-child')
      }
      else {
        layer = this.svg.append('g')
      }
      return layer.attr('id', id || '')
        .attr('class', className || '');
    };
  
    Datamap.prototype.updateChoropleth = function(data, options) {
      var svg = this.svg;
      var that = this;
  
      // When options.reset = true, reset all the fill colors to the defaultFill and kill all data-info
      if ( options && options.reset === true ) {
        svg.selectAll('.datamaps-subunit')
          .attr('data-info', function() {
             return "{}"
          })
          .transition().style('fill', this.options.fills.defaultFill)
      }
  
      for ( var subunit in data ) {
        if ( data.hasOwnProperty(subunit) ) {
          var color;
          var subunitData = data[subunit]
          if ( ! subunit ) {
            continue;
          }
          else if ( typeof subunitData === "string" ) {
            color = subunitData;
          }
          else if ( typeof subunitData.color === "string" ) {
            color = subunitData.color;
          }
          else if ( typeof subunitData.fillColor === "string" ) {
            color = subunitData.fillColor;
          }
          else {
            color = this.options.fills[ subunitData.fillKey ];
          }
          // If it's an object, overriding the previous data
          if ( subunitData === Object(subunitData) ) {
            this.options.data[subunit] = defaults(subunitData, this.options.data[subunit] || {});
            var geo = this.svg.select('.' + subunit).attr('data-info', JSON.stringify(this.options.data[subunit]));
          }
          svg
            .selectAll('.' + subunit)
            .transition()
              .style('fill', color);
        }
      }
    };
  
    Datamap.prototype.updatePopup = function (element, d, options) {
      var self = this;
      element.on('mousemove', null);
      element.on('mousemove', function() {
        var position = d3.mouse(self.options.element);
        d3.select(self.svg[0][0].parentNode).select('.datamaps-hoverover')
          .style('top', ( (position[1] + 30)) + "px")
          .html(function() {
            var data = JSON.parse(element.attr('data-info'));
            try {
              return options.popupTemplate(d, data);
            } catch (e) {
              return "";
            }
          })
          .style('left', ( position[0]) + "px");
      });
  
      d3.select(self.svg[0][0].parentNode).select('.datamaps-hoverover').style('display', 'block');
    };
  
    Datamap.prototype.addPlugin = function( name, pluginFn ) {
      var self = this;
      if ( typeof Datamap.prototype[name] === "undefined" ) {
        Datamap.prototype[name] = function(data, options, callback, createNewLayer) {
          var layer;
          if ( typeof createNewLayer === "undefined" ) {
            createNewLayer = false;
          }
  
          if ( typeof options === 'function' ) {
            callback = options;
            options = undefined;
          }
  
          options = defaults(options || {}, self.options[name + 'Config']);
  
          // Add a single layer, reuse the old layer
          if ( !createNewLayer && this.options[name + 'Layer'] ) {
            layer = this.options[name + 'Layer'];
            options = options || this.options[name + 'Options'];
          }
          else {
            layer = this.addLayer(name);
            this.options[name + 'Layer'] = layer;
            this.options[name + 'Options'] = options;
          }
          pluginFn.apply(this, [layer, data, options]);
          if ( callback ) {
            callback(layer);
          }
        };
      }
    };
  
    // Expose library
    if (typeof exports === 'object') {
      d3 = require('d3');
      topojson = require('topojson');
      module.exports = Datamap;
    }
    else if ( typeof define === "function" && define.amd ) {
      define( "datamaps", ["require", "d3", "topojson"], function(require) {
        d3 = require('d3');
        topojson = require('topojson');
  
        return Datamap;
      });
    }
    else {
      window.Datamap = window.Datamaps = Datamap;
    }
  
    if ( window.jQuery ) {
      window.jQuery.fn.datamaps = function(options, callback) {
        options = options || {};
        options.element = this[0];
        var datamap = new Datamap(options);
        if ( typeof callback === "function" ) {
          callback(datamap, options);
        }
        return this;
      };
    }
  })();
  